<!-- #region TermCorrectionPopup [C:3] [TYPE Component] [SEMANTICS translate, correction, popup, dictionary, term] -->
<!-- @BRIEF Component component: lib/components/translate/TermCorrectionPopup.svelte -->
<!-- @RELATION DEPENDS_ON -> [TranslateApi] -->
<!-- @RELATION BINDS_TO -> [EXT:frontend:dictionaryApi] -->
<!-- @UX_STATE closed -> Hidden -->
<!-- @UX_STATE selecting -> User selects target dictionary -->
<!-- @UX_STATE editing -> User enters corrected term -->
<!-- @UX_STATE submitting -> API call in progress -->
<!-- @UX_STATE conflict_detected -> Existing entry found, user chooses overwrite/keep -->
<!-- @UX_STATE submitted -> Success feedback -->
<!-- @UX_FEEDBACK Toast on success/error; conflict dialog with action buttons -->
<!-- @UX_RECOVERY Cancel button returns to previous state -->
<script lang="ts">
	import { addToast } from '$lib/toasts.svelte.js';
	import { submitCorrection, dictionaryApi } from '$lib/api/translate.js';
	import { _, getT } from '$lib/i18n/index.svelte.js';

	let {
		sourceTerm = '',
		incorrectTarget = '',
		sourceLanguage = '',
		targetLanguage = '',
		runId = '',
		rowKey = '',
		onClose = () => {},
		onSubmitted = () => {},
		/** @type {Record<string, any>|null} initial context data auto-captured from source row */
		initialContextData = null,
		/** @type {string|null} optional context usage notes */
		initialUsageNotes = ''
	} = $props();

	/** @type {'closed'|'selecting'|'editing'|'submitting'|'conflict_detected'|'submitted'} */
	let uxState = $state('closed');
  // @RATIONALE Svelte 5 store detection fails for `$t` in deeply nested templates.
  //             Use getT() + $derived to keep reactivity to locale changes.
  const _t = $derived(getT());
	let correctedTarget = $state('');
	let dictionaries = $state([]);
	let selectedDictId = $state('');
	let conflictInfo = $state(null);
	let submitResult = $state(null);

	// Context state
	let contextData = $state(null);
	let contextUsageNotes = $state('');
	let hasEditedContext = $state(false);
	let showContextEditor = $state(false);

	$effect(() => {
		if (initialContextData) {
			contextData = JSON.parse(JSON.stringify(initialContextData));
		}
		if (initialUsageNotes) {
			contextUsageNotes = initialUsageNotes;
		}
	});

	$effect(() => {
		if (sourceTerm && incorrectTarget) {
			uxState = 'selecting';
			loadDictionaries();
		}
	});

	async function loadDictionaries() {
		try {
			const result = await dictionaryApi.fetchDictionaries({ page_size: 100 });
			dictionaries = Array.isArray(result) ? result : (result?.items || []);
			if (dictionaries.length === 1) {
				selectedDictId = dictionaries[0].id;
			}
			uxState = dictionaries.length > 0 ? 'editing' : 'selecting';
		} catch {
			addToast(_('translate.term_correction.dict_load_failed'), 'error');
			uxState = 'editing';
		}
	}

	async function handleSubmit() {
		if (!selectedDictId || !correctedTarget.trim()) return;
		uxState = 'submitting';
		try {
			const payload = {
				source_term: sourceTerm,
				incorrect_target_term: incorrectTarget,
				corrected_target_term: correctedTarget.trim(),
				dictionary_id: selectedDictId,
				origin_run_id: runId || undefined,
				origin_row_key: rowKey || undefined,
			};
			if (contextData) {
				payload.context_data = contextData;
			}
			if (contextUsageNotes) {
				payload.usage_notes = contextUsageNotes;
			}
			const result = await submitCorrection(payload);
			if (result.action === 'conflict_detected') {
				conflictInfo = result.conflict;
				uxState = 'conflict_detected';
			} else if (result.action === 'created' || result.action === 'updated') {
				submitResult = result;
				uxState = 'submitted';
				addToast(result.message || _('translate.term_correction.submit_success'), 'success');
				onSubmitted(result);
			}
		} catch (err) {
			addToast(err?.message || _('translate.term_correction.submit_failed'), 'error');
			uxState = 'editing';
		}
	}

	async function handleConflictOverwrite() {
		try {
			const result = await submitCorrection({
				source_term: sourceTerm,
				incorrect_target_term: incorrectTarget,
				corrected_target_term: correctedTarget.trim(),
				dictionary_id: selectedDictId,
				origin_run_id: runId || undefined,
				origin_row_key: rowKey || undefined,
			});
			submitResult = result;
			uxState = 'submitted';
			addToast(result.message || _('translate.term_correction.overwrite_success'), 'success');
			onSubmitted(result);
		} catch (err) {
			addToast(err?.message || _('translate.term_correction.overwrite_failed'), 'error');
			uxState = 'conflict_detected';
		}
	}

	function handleConflictKeep() {
		uxState = 'submitted';
		addToast(_('translate.term_correction.keep_success'), 'info');
		onSubmitted({ action: 'kept' });
	}

	function handleClose() {
		uxState = 'closed';
		onClose();
	}
</script>

{#if uxState !== 'closed'}
	<!-- svelte-ignore a11y_no_static_element_interactions -->
	<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/40" onclick={handleClose} onkeydown={(e) => e.key === 'Escape' && handleClose()} role="presentation">
		<div class="bg-surface-card rounded-lg shadow-xl p-6 w-full max-w-md mx-4" onclick={(e) => e.stopPropagation()} onkeydown={(e) => e.key === 'Escape' && handleClose()} tabindex="-1">
			<!-- Header -->
			<div class="flex items-center justify-between mb-4">
				<h3 class="text-lg font-semibold text-text">{_t.translate?.term_correction?.title}</h3>
				<button onclick={handleClose} class="text-text-subtle hover:text-text-muted" aria-label={_t.translate?.term_correction?.close || 'Close'}>
					<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
						<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
					</svg>
				</button>
			</div>

			<!-- Selecting state -->
			{#if uxState === 'selecting'}
				<p class="text-sm text-text-muted">{_t.translate?.term_correction?.loading_dictionaries}</p>

			<!-- Editing state -->
			{:else if uxState === 'editing'}
				<div class="space-y-4">
					{#if sourceLanguage || targetLanguage}
						<div class="bg-primary-light border-primary-ring rounded-lg px-3 py-2 text-xs text-primary">
							<span class="font-medium">{_t.translate?.term_correction?.language_pair}</span> {sourceLanguage || _t.translate?.term_correction?.detected} → {targetLanguage || _t.translate?.term_correction?.detected}
						</div>
					{/if}

					<!-- Context section (collapsible) -->
					<div class="border border-border rounded-lg overflow-hidden">
						<button
							onclick={() => { showContextEditor = !showContextEditor; }}
							class="w-full flex items-center justify-between px-3 py-2 text-xs font-medium text-text-muted bg-surface-muted hover:bg-surface-muted transition-colors"
						>
							<span class="flex items-center gap-1.5">
								<span>📋</span>
								<span>{_t.translate?.term_correction?.context_from_source}</span>
								{#if contextData}
									<span class="inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded-full"
										class:bg-primary-light:text-primary={!hasEditedContext}
										class:bg-success-light:text-success={hasEditedContext}
									>
										{hasEditedContext ? '✏️ ' + _t.translate?.term_correction?.edited_badge : '🤖 ' + _t.translate?.term_correction?.auto_badge}
									</span>
								{/if}
							</span>
							<svg class="w-3.5 h-3.5 transition-transform" class:rotate-180={showContextEditor} fill="none" stroke="currentColor" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
							</svg>
						</button>
						{#if showContextEditor}
							<div class="p-3 space-y-2 border-t border-border">
								{#if contextData}
									<div class="bg-surface-muted rounded p-2 font-mono text-[11px] text-text-muted max-h-24 overflow-y-auto">
										{JSON.stringify(contextData, null, 2)}
									</div>
									<div class="flex gap-2">
										<button
											onclick={() => {
												showContextEditor = true;
											}}
											class="text-[11px] px-2 py-1 rounded border border-border-strong text-text-muted hover:bg-surface-muted"
										>
											{_t.translate?.term_correction?.edit_context}
										</button>
										<button
											onclick={() => {
												contextData = null;
												hasEditedContext = true;
											}}
											class="text-[11px] px-2 py-1 rounded border border-destructive-light text-destructive hover:bg-destructive-light"
										>
											{_t.translate?.term_correction?.remove_context}
										</button>
									</div>
								{:else}
									<p class="text-[11px] text-text-subtle italic">{_t.translate?.term_correction?.no_context}</p>
									<button
										onclick={() => {
											contextData = JSON.parse(JSON.stringify(initialContextData));
											hasEditedContext = false;
										}}
										class="text-[11px] px-2 py-1 rounded border border-border-strong text-text-muted hover:bg-surface-muted"
									>
										{_t.translate?.term_correction?.restore_context}
									</button>
								{/if}
							</div>
						{/if}
					</div>

					<!-- Usage notes -->
					<div>
						<label class="block text-xs font-medium text-text-muted mb-1" for="term-corr-usage-notes">
							📝 {_t.translate?.term_correction?.usage_notes}
						</label>
						<textarea
							id="term-corr-usage-notes"
							bind:value={contextUsageNotes}
							placeholder={_t.translate?.term_correction?.usage_notes_placeholder}
							rows="2"
							class="w-full px-3 py-2 border border-border-strong rounded-lg text-xs focus-visible:ring-2 focus-visible:ring-primary-ring focus-visible:border-primary-ring resize-none"
						></textarea>
					</div>

					<div>
						<label class="block text-sm font-medium text-text mb-1" for="term-corr-source-term">{_t.translate?.term_correction?.source_term}</label>
						<input id="term-corr-source-term" type="text" readonly value={sourceTerm} class="w-full px-3 py-2 bg-surface-muted border border-border rounded-lg text-sm" />
					</div>
					<div>
						<label class="block text-sm font-medium text-text mb-1" for="term-corr-incorrect-target">{_t.translate?.term_correction?.incorrect_target}</label>
						<input id="term-corr-incorrect-target" type="text" readonly value={incorrectTarget} class="w-full px-3 py-2 bg-surface-muted border border-border rounded-lg text-sm" />
					</div>
					<div>
						<label class="block text-sm font-medium text-text mb-1" for="term-corr-source-lang">{_t.translate?.term_correction?.source_language}</label>
						<input id="term-corr-source-lang" type="text" readonly value={sourceLanguage || _t.translate?.term_correction?.auto_detected} class="w-full px-3 py-2 bg-surface-muted border border-border rounded-lg text-sm font-mono" />
					</div>
					<div>
						<label class="block text-sm font-medium text-text mb-1" for="term-corr-target-lang">{_t.translate?.term_correction?.target_language}</label>
						<input id="term-corr-target-lang" type="text" readonly value={targetLanguage || '—'} class="w-full px-3 py-2 bg-surface-muted border border-border rounded-lg text-sm font-mono" />
					</div>
					<div>
						<label class="block text-sm font-medium text-text mb-1" for="term-corr-corrected-target">{_t.translate?.term_correction?.corrected_target}</label>
						<input
							id="term-corr-corrected-target"
							type="text"
							bind:value={correctedTarget}
							placeholder={_t.translate?.term_correction?.corrected_placeholder}
							class="w-full px-3 py-2 border border-border-strong rounded-lg text-sm focus-visible:ring-2 focus-visible:ring-primary-ring focus-visible:border-primary-ring"
						/>
					</div>
					<div>
						<label class="block text-sm font-medium text-text mb-1" for="term-corr-dictionary">{_t.translate?.term_correction?.dictionary}</label>
						<select
							id="term-corr-dictionary"
							bind:value={selectedDictId}
							class="w-full px-3 py-2 border border-border-strong rounded-lg text-sm"
						>
							<option value="">{_t.translate?.term_correction?.select_dictionary}</option>
							{#each dictionaries as dict}
								<option value={dict.id}>{dict.name}</option>
							{/each}
						</select>
					</div>
					<div class="flex justify-end gap-2 pt-2">
						<button onclick={handleClose} class="px-4 py-2 text-sm text-text bg-surface-muted rounded-lg hover:bg-surface-muted">
							{_t.translate?.term_correction?.cancel}
						</button>
						<button
							onclick={handleSubmit}
							disabled={!selectedDictId || !correctedTarget.trim()}
							class="px-4 py-2 text-sm text-white bg-primary rounded-lg hover:bg-primary-hover disabled:opacity-50"
						>
							{_t.translate?.term_correction?.submit_correction}
						</button>
					</div>
				</div>

			<!-- Submitting state -->
			{:else if uxState === 'submitting'}
				<div class="text-center py-6">
					<div class="animate-spin w-8 h-8 border-2 border-primary-ring border-t-transparent rounded-full mx-auto mb-3"></div>
					<p class="text-sm text-text-muted">{_t.translate?.term_correction?.submitting}</p>
				</div>

			<!-- Conflict state -->
			{:else if uxState === 'conflict_detected'}
				<div class="space-y-4">
					<div class="bg-warning-light border border-warning rounded-lg p-4">
						<p class="text-sm font-medium text-warning">{_t.translate?.term_correction?.conflict_detected}</p>
						<p class="text-xs text-warning mt-1">
							{_t.translate?.term_correction?.conflict_description.replace('{source}', conflictInfo?.source_term || '').replace('{existing}', conflictInfo?.existing_target_term || '')}
						</p>
					</div>
					<div class="flex justify-end gap-2">
						<button onclick={handleConflictKeep} class="px-4 py-2 text-sm text-text bg-surface-muted rounded-lg hover:bg-surface-muted">
							{_t.translate?.term_correction?.keep_existing}
						</button>
						<button onclick={handleConflictOverwrite} class="px-4 py-2 text-sm text-white bg-yellow-600 rounded-lg hover:bg-yellow-700">
							{_t.translate?.term_correction?.overwrite}
						</button>
					</div>
				</div>

			<!-- Submitted state -->
			{:else if uxState === 'submitted'}
				<div class="text-center py-6">
					<svg class="w-12 h-12 text-success mx-auto mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
						<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
					</svg>
					<p class="text-sm font-medium text-text">{_t.translate?.term_correction?.submitted}</p>
					<p class="text-xs text-text-muted mt-1">{submitResult?.message || ''}</p>
					<button onclick={handleClose} class="mt-4 px-4 py-2 text-sm text-white bg-primary rounded-lg hover:bg-primary-hover">
						{_t.translate?.term_correction?.close}
					</button>
				</div>
			{/if}
		</div>
	</div>
{/if}
<!-- #endregion TermCorrectionPopup -->
