<script lang="ts">
	import { untrack } from 'svelte';
	import { Button } from '$lib/components/ui/button';
	import * as Dialog from '$lib/components/ui/dialog';
	import { Input } from '$lib/components/ui/input';
	import { Label } from '$lib/components/ui/label';
	import * as Table from '$lib/components/ui/table';
	import { companyStore } from '$lib/stores/company.svelte';
	import { toast } from 'svelte-sonner';
	import { Check } from 'lucide-svelte';
	import type {
		Equivalency,
		EquivalencyItem
	} from '$lib/api/dashboard/a76/general_catalogs/equivalencies';
	import {
		getEquivalencyItems,
		getEquivalencies,
		createEquivalency,
		deleteEquivalencyItem,
		updateEquivalency
	} from '$lib/api/dashboard/a76/general_catalogs/equivalencies';
	import EquivalencyItemCreateEditDialog from './create-edit-dialog.svelte';

	let {
		open = $bindable(false),
		equivalency = null,
		mode = 'edit',
		onSuccess
	}: {
		open: boolean;
		equivalency?: Equivalency | null;
		mode?: 'create' | 'edit';
		onSuccess?: () => void;
	} = $props();

	let loading = $state(false);
	let error = $state<string | null>(null);
	let items = $state<EquivalencyItem[]>([]);

	// El item actualmente seleccionado/asociado a esta equivalencia
	let selectedItemId = $state<number | null>(null);

	let equivalencyDraft = $state({ identifier: '', description: '' });
	let descriptionDraft = $state('');
	let savedEquivalency = $state<Equivalency | null>(null);

	function getEffectiveEquivalency(): Equivalency | null {
		if (mode === 'edit') return equivalency ?? null;
		return savedEquivalency;
	}

	// Modal de crear/editar item
	let inputsOpen = $state(false);
	let inputsItem = $state<EquivalencyItem | null>(null);

	function getSelectedItem(): EquivalencyItem | null {
		if (selectedItemId === null) return null;
		return items.find((i) => i.id === selectedItemId) || null;
	}

	async function reloadItems() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) {
			items = [];
			return;
		}

		loading = true;
		error = null;
		try {
			const resp = await getEquivalencyItems(1, 2000, companyId);
			if (resp.error) throw new Error(resp.error);
			items = resp.data.items || [];
		} catch (e) {
			console.error(e);
			error = e instanceof Error ? e.message : 'Error al cargar items';
			items = [];
		} finally {
			loading = false;
		}
	}

	async function ensureEquivalencySaved(): Promise<Equivalency | null> {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) {
			toast.error('Selecciona una compañía');
			return null;
		}

		if (mode === 'edit') {
			return equivalency ?? null;
		}

		if (savedEquivalency) return savedEquivalency;

		const identifier = equivalencyDraft.identifier.trim();
		if (!identifier) {
			toast.error('El identificador es requerido');
			return null;
		}

		const description = descriptionDraft.trim() || equivalencyDraft.description.trim() || null;

		const created = await createEquivalency({ identifier, description }, companyId);

		if (created.data && !created.error) {
			savedEquivalency = created.data;
			descriptionDraft = created.data.description || '';
			return savedEquivalency;
		}

		// Si ya existía, resolver por identifier
		const listResp = await getEquivalencies(1, 50, companyId, { from_unit_code: identifier });
		const existing =
			(listResp.data?.items || []).find(
				(e) => e.identifier?.toUpperCase() === identifier.toUpperCase()
			) ?? null;

		if (!existing) {
			toast.error(listResp.error || 'No se pudo crear la equivalencia');
			return null;
		}

		savedEquivalency = existing;
		descriptionDraft = existing.description || '';
		return savedEquivalency;
	}

	async function handleSave() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		if (mode === 'create') {
			const identifier = equivalencyDraft.identifier.trim();
			if (!identifier) {
				toast.error('El identificador es requerido');
				return;
			}
			const description = descriptionDraft.trim() || null;

			if (!savedEquivalency) {
				const created = await createEquivalency(
					{ identifier, description, item_id: selectedItemId },
					companyId
				);
				if (created.error || !created.data) {
					toast.error(created.error || 'Error al guardar');
					return;
				}
				savedEquivalency = created.data;
			} else {
				const updated = await updateEquivalency(
					savedEquivalency.id,
					{ identifier, description, item_id: selectedItemId },
					companyId
				);
				if (updated.error) {
					toast.error(updated.error || 'Error al actualizar');
					return;
				}
			}
		} else {
			if (!equivalency) return;
			const updated = await updateEquivalency(
				equivalency.id,
				{ description: descriptionDraft.trim() || null, item_id: selectedItemId },
				companyId
			);
			if (updated.error) {
				toast.error(updated.error || 'Error al actualizar');
				return;
			}
		}

		toast.success('Equivalencia guardada');
		open = false;
		onSuccess?.();
	}

	async function handleInsert() {
		const eq = await ensureEquivalencySaved();
		if (!eq) return;
		inputsItem = null;
		inputsOpen = true;
	}

	async function handleEdit() {
		const selected = getSelectedItem();
		if (!selected) {
			toast.error('Selecciona un item para editar');
			return;
		}
		inputsItem = selected;
		inputsOpen = true;
	}

	async function handleDelete() {
		const companyId = companyStore.activeCompany?.id;
		if (!companyId) return;

		const selected = getSelectedItem();
		if (!selected) {
			toast.error('Selecciona un item para borrar');
			return;
		}

		if (!confirm('¿Está seguro de eliminar este item del pool?')) return;

		try {
			await deleteEquivalencyItem(selected.id, companyId);
			toast.success('Item eliminado');
			// Si era el item asociado a esta equivalencia, desvincular
			if (selectedItemId === selected.id) selectedItemId = null;
			await reloadItems();
			onSuccess?.();
		} catch (e) {
			console.error(e);
			toast.error('No se pudo eliminar', { description: e instanceof Error ? e.message : '' });
		}
	}

	$effect(() => {
		if (!open) return;
		const _mode = mode;
		const _equivalency = equivalency;

		untrack(() => {
			savedEquivalency = null;

			if (_mode === 'edit') {
				descriptionDraft = _equivalency?.description || '';
				equivalencyDraft = {
					identifier: _equivalency?.identifier || '',
					description: _equivalency?.description || ''
				};
				savedEquivalency = _equivalency ?? null;
				selectedItemId = _equivalency?.item_id ?? null;
			} else {
				equivalencyDraft = { identifier: '', description: '' };
				descriptionDraft = '';
				selectedItemId = null;
			}

			reloadItems();
		});
	});

	function handleInputsSuccess() {
		inputsOpen = false;
		reloadItems();
		onSuccess?.();
	}
</script>

<Dialog.Root bind:open>
	<Dialog.Content class="sm:max-w-[900px]">
		<Dialog.Header>
			<Dialog.Title>DATOS DE EQUIVALENTES</Dialog.Title>
			<Dialog.Description>
				Selecciona un item del pool para asociarlo a esta equivalencia.
			</Dialog.Description>
		</Dialog.Header>

		<div class="grid gap-4 py-4">
			<div class="grid grid-cols-3 gap-4">
				<div class="grid gap-2">
					<Label>Identificador</Label>
					{#if mode === 'edit'}
						<Input value={equivalency?.identifier || ''} readonly />
					{:else if savedEquivalency}
						<Input value={savedEquivalency.identifier || ''} readonly />
					{:else}
						<Input
							bind:value={equivalencyDraft.identifier}
							placeholder="Ej: PZA, KGS, MP..."
						/>
					{/if}
				</div>

				<div class="grid gap-2 col-span-2">
					<Label>Descripción</Label>
					<Input bind:value={descriptionDraft} placeholder="(opcional)" />
				</div>
			</div>

			<div class="rounded-md border">
				<Table.Root>
					<Table.Header>
						<Table.Row inTabOrder={false} class="bg-muted/20">
							<Table.Head class="w-10"></Table.Head>
							<Table.Head>Campo Original</Table.Head>
							<Table.Head>Campo Externo</Table.Head>
						</Table.Row>
					</Table.Header>
					<Table.Body>
						{#if loading}
							<Table.Row inTabOrder={false}>
								<Table.Cell colspan={3} class="h-24 text-center">Cargando...</Table.Cell>
							</Table.Row>
						{:else if error}
							<Table.Row inTabOrder={false}>
								<Table.Cell colspan={3} class="h-24 text-center text-destructive">
									{error}
								</Table.Cell>
							</Table.Row>
						{:else if items.length === 0}
							<Table.Row inTabOrder={false}>
								<Table.Cell colspan={3} class="h-24 text-center text-muted-foreground">
									No hay items en el pool. Usa "Insertar" para crear uno.
								</Table.Cell>
							</Table.Row>
						{:else}
							{#each items as item}
								{@const isSelected = item.id === selectedItemId}
								<Table.Row inTabOrder={false}
									class={[
										'cursor-pointer transition-colors',
										isSelected
											? 'bg-primary/10 font-medium'
											: 'hover:bg-muted/50 text-muted-foreground'
									].join(' ')}
									onclick={() => (selectedItemId = isSelected ? null : item.id)}
								>
									<Table.Cell class="w-10 text-center">
										{#if isSelected}
											<Check class="h-4 w-4 text-primary mx-auto" />
										{/if}
									</Table.Cell>
									<Table.Cell class="font-mono">{item.original_field}</Table.Cell>
									<Table.Cell class="font-mono">{item.external_field}</Table.Cell>
								</Table.Row>
							{/each}
						{/if}
					</Table.Body>
				</Table.Root>
			</div>

			<div class="flex justify-between items-center">
				<p class="text-xs text-muted-foreground">
					{#if selectedItemId}
						Item seleccionado: <span class="font-mono font-medium">
							{items.find((i) => i.id === selectedItemId)?.original_field ?? ''}
							→ {items.find((i) => i.id === selectedItemId)?.external_field ?? ''}
						</span>
					{:else}
						Ningún item seleccionado para esta equivalencia.
					{/if}
				</p>
				<div class="flex gap-2">
					<Button variant="outline" size="sm" onclick={handleInsert}>Insertar</Button>
					<Button
						variant="outline"
						size="sm"
						onclick={handleEdit}
						disabled={selectedItemId === null}
					>
						Editar
					</Button>
					<Button
						variant="outline"
						size="sm"
						onclick={handleDelete}
						disabled={selectedItemId === null}
					>
						Borrar
					</Button>
				</div>
			</div>
		</div>

		<Dialog.Footer>
			<Button type="button" variant="outline" onclick={() => (open = false)}>Cerrar</Button>
			<Button type="button" onclick={handleSave}>Guardar</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>

<EquivalencyItemCreateEditDialog
	bind:open={inputsOpen}
	item={inputsItem}
	defaultOriginalField={inputsItem ? null : null}
	onSuccess={handleInputsSuccess}
/>
