<script lang="ts">
	import { t } from '$lib/i18n';
	import MdiIcon from '$lib/components/MdiIcon.svelte';
	import Button from '$lib/components/Button.svelte';

	type ConflictMode = 'skip' | 'rename' | 'overwrite';

	interface ValidationResult {
		valid: boolean;
		entity_counts?: Record<string, number>;
		warnings?: string[];
		errors?: string[];
	}

	interface ImportResult {
		created?: number;
		skipped?: number;
		overwritten?: number;
		errors?: string[];
		warnings?: string[];
	}

	interface Props {
		importFile: File | null;
		importConflict: ConflictMode;
		validating: boolean;
		validationResult: ValidationResult | null;
		importing: boolean;
		importResult: ImportResult | null;
		onFileSelect: (file: File | null) => void;
		onConflictChange: (mode: ConflictMode) => void;
		onValidate: () => void;
		onImport: () => void;
	}

	let {
		importFile,
		importConflict,
		validating,
		validationResult,
		importing,
		importResult,
		onFileSelect,
		onConflictChange,
		onValidate,
		onImport,
	}: Props = $props();

	let dragging = $state(false);
	let inputEl = $state<HTMLInputElement | undefined>();

	const conflictOptions: Array<{ value: ConflictMode; icon: string; labelKey: string }> = [
		{ value: 'skip', icon: 'mdiSkipNext', labelKey: 'backup.conflictSkip' },
		{ value: 'rename', icon: 'mdiRename', labelKey: 'backup.conflictRename' },
		{ value: 'overwrite', icon: 'mdiSync', labelKey: 'backup.conflictOverwrite' },
	];

	function pickFile(): void {
		inputEl?.click();
	}

	function handleInput(e: Event): void {
		const input = e.target as HTMLInputElement;
		const file = input.files?.[0] ?? null;
		onFileSelect(file);
	}

	function handleDrop(e: DragEvent): void {
		e.preventDefault();
		dragging = false;
		const file = e.dataTransfer?.files?.[0];
		if (file && (file.name.endsWith('.json') || file.type === 'application/json')) {
			onFileSelect(file);
		}
	}

	function handleDragOver(e: DragEvent): void {
		e.preventDefault();
		dragging = true;
	}

	function handleDragLeave(): void {
		dragging = false;
	}

	function formatBytes(bytes: number): string {
		if (bytes < 1024) return `${bytes} B`;
		if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
		return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
	}

	const entityCount = $derived(
		validationResult?.entity_counts
			? Object.values(validationResult.entity_counts).reduce<number>((a, b) => a + (b as number), 0)
			: 0
	);
</script>

<section class="import-panel glass">
	<header class="panel-head">
		<div class="panel-eyebrow">
			<MdiIcon name="mdiDatabaseImport" size={14} />
			<span>{t('backup.import')}</span>
		</div>
		<h3 class="panel-title">{t('backup.importDescription')}</h3>
	</header>

	<div class="panel-body">
		<!-- Step 1: file -->
		<div class="step">
			<div class="step-head">
				<span class="step-num">01</span>
				<span class="step-label">{t('backup.stepFile')}</span>
			</div>

			{#if importFile}
				<div class="file-pill">
					<span class="file-icon"><MdiIcon name="mdiCodeJson" size={18} /></span>
					<div class="file-meta">
						<div class="file-name" title={importFile.name}>{importFile.name}</div>
						<div class="file-size">{formatBytes(importFile.size)}</div>
					</div>
					<button class="file-change" type="button" onclick={pickFile}>
						<MdiIcon name="mdiSwapHorizontal" size={14} />
						<span>{t('backup.changeFile')}</span>
					</button>
				</div>
			{:else}
				<button type="button"
					class="dropzone"
					class:dropzone-active={dragging}
					onclick={pickFile}
					ondragover={handleDragOver}
					ondragleave={handleDragLeave}
					ondrop={handleDrop}>
					<span class="dropzone-icon"><MdiIcon name="mdiCloudUploadOutline" size={28} /></span>
					<span class="dropzone-text">
						{dragging ? t('backup.dropZoneActive') : t('backup.dropZone')}
					</span>
				</button>
			{/if}
			<input bind:this={inputEl} type="file" accept=".json,application/json"
				class="visually-hidden" onchange={handleInput} />
		</div>

		<!-- Step 2: validate -->
		{#if importFile}
			<div class="step">
				<div class="step-head">
					<span class="step-num">02</span>
					<span class="step-label">{t('backup.stepValidate')}</span>
					{#if validationResult}
						<span class="validate-pill"
							class:validate-ok={validationResult.valid}
							class:validate-bad={!validationResult.valid}>
							<MdiIcon name={validationResult.valid ? 'mdiCheckCircle' : 'mdiCloseCircle'} size={12} />
							{validationResult.valid ? t('backup.validationPassed') : t('backup.validationFailed')}
						</span>
					{/if}
				</div>
				{#if !validationResult}
					<Button variant="secondary" size="sm" onclick={onValidate} disabled={validating}>
						{#if validating}
							<MdiIcon name="mdiLoading" size={14} />
						{:else}
							<MdiIcon name="mdiCheckDecagramOutline" size={14} />
						{/if}
						{validating ? t('backup.validating') : t('backup.validateBtn')}
					</Button>
				{:else}
					<div class="validate-card" class:validate-card-bad={!validationResult.valid}>
						{#if entityCount > 0}
							<div class="validate-summary">
								<span class="validate-count font-mono">{entityCount}</span>
								<span class="validate-count-label">{t('backup.entities')}</span>
							</div>
							<div class="validate-categories">
								{#each Object.entries(validationResult.entity_counts ?? {}) as [cat, count]}
									<span class="validate-cat">
										<span class="validate-cat-num font-mono">{count}</span>
										<span class="validate-cat-name">{cat}</span>
									</span>
								{/each}
							</div>
						{/if}
						{#if validationResult.warnings?.length}
							<ul class="validate-list validate-warn">
								{#each validationResult.warnings as w}
									<li><MdiIcon name="mdiAlert" size={12} /><span>{w}</span></li>
								{/each}
							</ul>
						{/if}
						{#if validationResult.errors?.length}
							<ul class="validate-list validate-err">
								{#each validationResult.errors as e}
									<li><MdiIcon name="mdiAlertCircle" size={12} /><span>{e}</span></li>
								{/each}
							</ul>
						{/if}
					</div>
				{/if}
			</div>
		{/if}

		<!-- Step 3: conflict mode -->
		{#if importFile && validationResult?.valid}
			<div class="step">
				<div class="step-head">
					<span class="step-num">03</span>
					<span class="step-label">{t('backup.stepConflict')}</span>
				</div>
				<div class="segmented" role="radiogroup" aria-label={t('backup.conflictMode')}>
					{#each conflictOptions as opt}
						<button type="button"
							role="radio"
							aria-checked={importConflict === opt.value}
							class="seg"
							class:seg-on={importConflict === opt.value}
							onclick={() => onConflictChange(opt.value)}>
							<MdiIcon name={opt.icon} size={14} />
							<span>{t(opt.labelKey)}</span>
						</button>
					{/each}
				</div>
			</div>
		{/if}

		<!-- Step 4: CTA + results -->
		<div class="step step-cta">
			{#if importFile && !validationResult?.valid && !validating}
				<div class="cta-hint">
					<MdiIcon name="mdiInformationOutline" size={12} />
					<span>{t('backup.validateFirst')}</span>
				</div>
			{/if}
			<Button onclick={onImport} disabled={importing || !importFile || !validationResult?.valid}>
				{#if importing}
					<MdiIcon name="mdiLoading" size={14} />
				{:else}
					<MdiIcon name="mdiUpload" size={14} />
				{/if}
				{importing ? t('backup.importing') : t('backup.importBtn')}
			</Button>

			{#if importResult}
				<div class="import-results">
					<div class="result-tiles">
						<div class="result-tile tile-created">
							<span class="result-num font-mono">{importResult.created ?? 0}</span>
							<span class="result-label">{t('backup.resultCreated')}</span>
						</div>
						<div class="result-tile tile-skipped">
							<span class="result-num font-mono">{importResult.skipped ?? 0}</span>
							<span class="result-label">{t('backup.resultSkipped')}</span>
						</div>
						<div class="result-tile tile-overwritten">
							<span class="result-num font-mono">{importResult.overwritten ?? 0}</span>
							<span class="result-label">{t('backup.resultOverwritten')}</span>
						</div>
					</div>
					{#if importResult.errors?.length}
						<ul class="validate-list validate-err">
							{#each importResult.errors as e}
								<li><MdiIcon name="mdiAlertCircle" size={12} /><span>{e}</span></li>
							{/each}
						</ul>
					{/if}
					{#if importResult.warnings?.length}
						<ul class="validate-list validate-warn">
							{#each importResult.warnings as w}
								<li><MdiIcon name="mdiAlert" size={12} /><span>{w}</span></li>
							{/each}
						</ul>
					{/if}
				</div>
			{/if}
		</div>
	</div>
</section>

<style>
	.import-panel {
		padding: 1.5rem 1.5rem 1.35rem;
		display: flex;
		flex-direction: column;
		gap: 1.1rem;
		min-height: 100%;
	}
	.panel-head { position: relative; z-index: 1; }
	.panel-eyebrow {
		display: inline-flex;
		align-items: center;
		gap: 0.35rem;
		font-family: var(--font-mono);
		font-size: 0.62rem;
		text-transform: uppercase;
		letter-spacing: 0.18em;
		color: var(--color-muted-foreground);
		margin-bottom: 0.5rem;
	}
	.panel-title {
		margin: 0;
		font-family: var(--font-display);
		font-weight: 400;
		font-size: 1.15rem;
		line-height: 1.35;
		letter-spacing: -0.015em;
		color: var(--color-foreground);
		max-width: 36ch;
	}

	.panel-body {
		position: relative;
		z-index: 1;
		display: flex;
		flex-direction: column;
		gap: 1.25rem;
		flex: 1;
	}

	.step { display: flex; flex-direction: column; gap: 0.6rem; }
	.step-head { display: flex; align-items: baseline; gap: 0.6rem; }
	.step-num {
		font-family: var(--font-mono);
		font-size: 0.62rem;
		letter-spacing: 0.18em;
		color: var(--color-muted-foreground);
	}
	.step-label {
		font-size: 0.78rem;
		font-weight: 500;
		color: var(--color-foreground);
	}

	/* Drop zone */
	.dropzone {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 0.55rem;
		padding: 1.65rem 1.1rem;
		border-radius: 16px;
		border: 1.5px dashed var(--color-rule-strong);
		background: color-mix(in srgb, var(--color-primary) 4%, var(--color-glass-strong));
		color: var(--color-muted-foreground);
		cursor: pointer;
		font-family: inherit;
		font-size: 0.78rem;
		text-align: center;
		transition: background 0.18s, border-color 0.18s, color 0.18s, transform 0.18s;
		min-height: 140px;
	}
	.dropzone:hover {
		color: var(--color-foreground);
		border-color: color-mix(in srgb, var(--color-primary) 50%, var(--color-border));
		background: color-mix(in srgb, var(--color-primary) 8%, var(--color-glass-strong));
	}
	.dropzone-active {
		color: var(--color-foreground);
		border-color: var(--color-primary);
		background: color-mix(in srgb, var(--color-primary) 14%, var(--color-glass-strong));
		transform: scale(1.005);
	}
	.dropzone-icon { color: var(--color-primary); display: inline-flex; }
	.dropzone-text { line-height: 1.4; max-width: 28ch; }

	.visually-hidden {
		position: absolute;
		width: 1px; height: 1px;
		padding: 0; margin: -1px;
		overflow: hidden;
		clip: rect(0,0,0,0);
		white-space: nowrap;
		border: 0;
	}

	/* File pill */
	.file-pill {
		display: flex;
		align-items: center;
		gap: 0.7rem;
		padding: 0.6rem 0.75rem;
		border-radius: 14px;
		border: 1px solid color-mix(in srgb, var(--color-primary) 35%, var(--color-border));
		background: color-mix(in srgb, var(--color-primary) 8%, var(--color-glass-strong));
	}
	.file-icon { color: var(--color-primary); flex-shrink: 0; }
	.file-meta { flex: 1; min-width: 0; }
	.file-name {
		font-family: var(--font-mono);
		font-size: 0.75rem;
		color: var(--color-foreground);
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}
	.file-size {
		font-size: 0.66rem;
		color: var(--color-muted-foreground);
		font-family: var(--font-mono);
	}
	.file-change {
		display: inline-flex;
		align-items: center;
		gap: 0.3rem;
		padding: 0.32rem 0.65rem;
		border-radius: 999px;
		background: var(--color-glass-strong);
		border: 1px solid var(--color-border);
		color: var(--color-muted-foreground);
		font-size: 0.7rem;
		cursor: pointer;
		font-family: inherit;
		transition: background 0.15s, color 0.15s, border-color 0.15s;
	}
	.file-change:hover { color: var(--color-foreground); border-color: var(--color-rule-strong); background: var(--color-glass-elev); }

	/* Validation */
	.validate-pill {
		margin-left: auto;
		display: inline-flex;
		align-items: center;
		gap: 0.25rem;
		font-size: 0.65rem;
		padding: 0.2rem 0.55rem;
		border-radius: 999px;
		font-weight: 500;
	}
	.validate-ok {
		color: var(--color-success-fg);
		background: var(--color-success-bg);
		border: 1px solid color-mix(in srgb, var(--color-success-fg) 30%, transparent);
	}
	.validate-bad {
		color: var(--color-error-fg);
		background: var(--color-error-bg);
		border: 1px solid color-mix(in srgb, var(--color-error-fg) 30%, transparent);
	}

	.validate-card {
		padding: 0.7rem 0.85rem;
		border-radius: 12px;
		border: 1px solid var(--color-border);
		background: var(--color-glass-strong);
		display: flex;
		flex-direction: column;
		gap: 0.55rem;
	}
	.validate-card-bad {
		border-color: color-mix(in srgb, var(--color-error-fg) 28%, var(--color-border));
		background: color-mix(in srgb, var(--color-error-fg) 6%, var(--color-glass-strong));
	}
	.validate-summary {
		display: flex;
		align-items: baseline;
		gap: 0.45rem;
	}
	.validate-count {
		font-size: 1.4rem;
		font-weight: 500;
		color: var(--color-foreground);
		line-height: 1;
	}
	.validate-count-label {
		font-size: 0.65rem;
		text-transform: uppercase;
		letter-spacing: 0.16em;
		color: var(--color-muted-foreground);
	}
	.validate-categories {
		display: flex;
		flex-wrap: wrap;
		gap: 0.35rem;
	}
	.validate-cat {
		display: inline-flex;
		align-items: baseline;
		gap: 0.3rem;
		padding: 0.18rem 0.55rem;
		border-radius: 999px;
		border: 1px solid var(--color-border);
		background: var(--color-glass);
		font-size: 0.66rem;
	}
	.validate-cat-num {
		color: var(--color-primary);
		font-weight: 500;
	}
	.validate-cat-name {
		color: var(--color-muted-foreground);
	}

	.validate-list {
		list-style: none;
		padding: 0; margin: 0;
		display: flex;
		flex-direction: column;
		gap: 0.25rem;
	}
	.validate-list li {
		display: flex;
		align-items: flex-start;
		gap: 0.35rem;
		font-size: 0.7rem;
		line-height: 1.4;
	}
	.validate-warn li { color: var(--color-warning-fg); }
	.validate-err li { color: var(--color-error-fg); }

	/* Segmented (same vocabulary as ExportPanel) */
	.segmented {
		display: grid;
		grid-template-columns: 1fr;
		gap: 0.4rem;
	}
	@media (min-width: 480px) {
		.segmented { grid-template-columns: repeat(3, 1fr); }
	}
	.seg {
		display: inline-flex;
		flex-direction: column;
		align-items: flex-start;
		gap: 0.25rem;
		padding: 0.55rem 0.7rem;
		border-radius: 12px;
		border: 1px solid var(--color-border);
		background: var(--color-glass-strong);
		color: var(--color-muted-foreground);
		cursor: pointer;
		font-family: inherit;
		font-size: 0.72rem;
		text-align: left;
		line-height: 1.25;
		transition: background 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.18s;
	}
	.seg:hover { color: var(--color-foreground); border-color: var(--color-rule-strong); background: var(--color-glass-elev); }
	.seg-on {
		background: linear-gradient(135deg, color-mix(in srgb, var(--color-primary) 16%, transparent), color-mix(in srgb, var(--color-orchid) 14%, transparent));
		border-color: color-mix(in srgb, var(--color-primary) 50%, transparent);
		color: var(--color-foreground);
		box-shadow:
			inset 0 1px 0 var(--color-highlight),
			0 0 0 1px color-mix(in srgb, var(--color-primary) 30%, transparent);
	}

	.cta-hint {
		display: flex;
		align-items: center;
		gap: 0.35rem;
		font-size: 0.7rem;
		color: var(--color-muted-foreground);
		margin-bottom: 0.5rem;
	}

	.step-cta {
		margin-top: auto;
		padding-top: 0.4rem;
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		gap: 0.65rem;
	}

	.import-results {
		width: 100%;
		display: flex;
		flex-direction: column;
		gap: 0.6rem;
	}
	.result-tiles {
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		gap: 0.4rem;
	}
	.result-tile {
		display: flex;
		flex-direction: column;
		gap: 0.15rem;
		padding: 0.6rem 0.7rem;
		border-radius: 12px;
		border: 1px solid var(--color-border);
		background: var(--color-glass-strong);
	}
	.result-num {
		font-size: 1.2rem;
		font-weight: 500;
		line-height: 1;
		color: var(--color-foreground);
	}
	.result-label {
		font-size: 0.6rem;
		letter-spacing: 0.14em;
		text-transform: uppercase;
		color: var(--color-muted-foreground);
	}
	.tile-created { border-color: color-mix(in srgb, var(--color-mint) 35%, var(--color-border)); }
	.tile-created .result-num { color: var(--color-mint); }
	.tile-skipped { border-color: color-mix(in srgb, var(--color-sky) 30%, var(--color-border)); }
	.tile-skipped .result-num { color: var(--color-sky); }
	.tile-overwritten { border-color: color-mix(in srgb, var(--color-citrus) 35%, var(--color-border)); }
	.tile-overwritten .result-num { color: var(--color-citrus); }
</style>
