<script lang="ts">
	import { Button } from '$lib/components/ui/button';
	import * as Dialog from '$lib/components/ui/dialog';
	import { Input, FilePickerInput } from '$lib/components/ui/input';
	import { Label } from '$lib/components/ui/label';
	import { Separator } from '$lib/components/ui/separator';
	import * as Select from '$lib/components/ui/select';
	import { LoaderCircle, Search } from 'lucide-svelte';
	import {
		expedienteArchivosApi,
		type ExpedienteArchivo,
		type ExpedienteArchivoCreateDTO
	} from '$lib/api/dashboard/a76/expediente-archivos';
	import type { Pedimento } from '$lib/api/dashboard/a76/pedimentos';
	import {
		documentTypesDigitizationApi,
		type DocumentTypeDigitization
	} from '$lib/api/dashboard/reference_data/document_types_digitization';
	import { customsBrokersApi, type CustomsBroker } from '$lib/api/dashboard/a76/customs-brokers';
	import PedimentoSelectorDialog from '$lib/components/dashboard/pedimentos/edit/pedimento-selector-dialog.svelte';
	import { companyStore } from '$lib/stores/company.svelte';
	import { m } from '$lib/i18n/messages';

	let {
		open = $bindable(false),
		item = null,
		onSuccess
	}: {
		open: boolean;
		item?: ExpedienteArchivo | null;
		onSuccess?: () => void;
	} = $props();

	const isEdit = $derived(!!item);
	const title = $derived(
		isEdit ? 'Editar Documento Digitalizado' : 'Nuevo Documento Digitalizado'
	);

	// ── Catálogos ──────────────────────────────────────────────────────────── //
	let docTypes = $state<DocumentTypeDigitization[]>([]);
	let docTypesLoading = $state(false);
	let brokers = $state<CustomsBroker[]>([]);
	let brokersLoading = $state(false);

	// ── RFC auto-llenado ────────────────────────────────────────────────────── //
	async function onBrokerSelected(licenseKey: string | undefined) {
		formData.agente_aduanal = licenseKey ?? null;
		formData.rfc_consulta = null;
		if (!licenseKey) return;

		// Buscar en la lista ya cargada primero
		const found = brokers.find((b) => b.license === licenseKey);
		if (found?.tax_id?.trim()) {
			formData.rfc_consulta = found.tax_id.trim().toUpperCase();
			return;
		}
		if (found?.vu?.query_tax_id) {
			formData.rfc_consulta = found.vu.query_tax_id.trim().toUpperCase();
			return;
		}

		// Fallback: obtener detalle completo del agente para acceder al VU
		const company = companyStore.activeCompany;
		if (!company) return;
		try {
			const brokerKey = found?.broker_key || licenseKey;
			const res = await customsBrokersApi.get(brokerKey, company.id.toString());
			const broker = (res.data || res) as CustomsBroker;
			if (broker?.tax_id?.trim()) {
				formData.rfc_consulta = broker.tax_id.trim().toUpperCase();
				return;
			}
			if (broker?.vu?.query_tax_id) {
				formData.rfc_consulta = broker.vu.query_tax_id.trim().toUpperCase();
			}
		} catch {
			// VU no disponible, dejar rfc vacío
		}
	}

	// ── Formulario ─────────────────────────────────────────────────────────── //
	let formData = $state<ExpedienteArchivoCreateDTO>({
		e_document: null,
		num_operacion: null,
		tipo_documento: null,
		archivo_digitalizado_en: null,
		fecha_digitalizacion: null,
		agente_aduanal: null,
		pedimento: null,
		rfc_consulta: null,
		nombre_archivo: null
	});

	let loading = $state(false);
	let error = $state<string | null>(null);
	let isPedimentoDialogOpen = $state(false);
	let selectedFile = $state<File | null>(null);
	const selectedDocType = $derived(docTypes.find((d) => d.code === formData.tipo_documento) ?? null);
	const selectedBroker = $derived(
		brokers.find((broker) => broker.license === formData.agente_aduanal) ?? null
	);

	function buildPedimentoLabel(pedimento: Pedimento): string {
		return `${pedimento.customs_office?.slice(0, 2) || ''}-${pedimento.license || ''}-${pedimento.pedimento_number || ''}`.replace(
			/^-+|-+$/g,
			''
		);
	}

	function handlePedimentoSelect(pedimento: Pedimento) {
		formData.pedimento = buildPedimentoLabel(pedimento);
	}

	// ── Efectos ────────────────────────────────────────────────────────────── //
	$effect(() => {
		if (open && companyStore.activeCompany?.id) {
			const companyId = companyStore.activeCompany.id;
			// Cargar tipos de documento
			if (docTypes.length === 0) {
				docTypesLoading = true;
				documentTypesDigitizationApi
					.getAll(companyId, true)
					.then((res) => {
						docTypes = res.data?.items || [];
					})
					.catch(() => (docTypes = []))
					.finally(() => (docTypesLoading = false));
			}
			// Cargar agentes aduanales
			if (brokers.length === 0) {
				brokersLoading = true;
				customsBrokersApi
					.list(companyStore.activeCompany.id.toString(), 1, 200)
					.then((res) => {
						const data = (res.data || res) as any;
						if (Array.isArray(data)) brokers = data;
						else if (data?.items) brokers = data.items;
					})
					.catch(() => (brokers = []))
					.finally(() => (brokersLoading = false));
			}
		}
	});

	$effect(() => {
		if (!open) {
			error = null;
			loading = false;
			selectedFile = null;
			return;
		}
		if (item) {
			formData = {
				e_document: item.e_document ?? null,
				num_operacion: item.num_operacion ?? null,
				tipo_documento: item.tipo_documento ?? null,
				archivo_digitalizado_en: item.archivo_digitalizado_en ?? null,
				fecha_digitalizacion: item.fecha_digitalizacion ?? null,
				agente_aduanal: item.agente_aduanal ?? null,
				pedimento: item.pedimento ?? null,
				rfc_consulta: item.rfc_consulta ?? null,
				nombre_archivo: item.nombre_archivo ?? null
			};
		} else {
			formData = {
				e_document: null,
				num_operacion: null,
				tipo_documento: null,
				archivo_digitalizado_en: null,
				fecha_digitalizacion: null,
				agente_aduanal: null,
				pedimento: null,
				rfc_consulta: null,
				nombre_archivo: null
			};
		}
	});

	$effect(() => {
		if (
			!open ||
			brokersLoading ||
			!formData.agente_aduanal ||
			!!formData.rfc_consulta ||
			brokers.length === 0
		) {
			return;
		}

		void onBrokerSelected(formData.agente_aduanal ?? undefined);
	});

	// ── Submit ─────────────────────────────────────────────────────────────── //
	async function handleSubmit() {
		if (loading) return;
		error = null;
		loading = true;

		try {
			const company = companyStore.activeCompany;
			if (!company) throw new Error('No hay una compañía seleccionada');

			if (!formData.tipo_documento?.trim())
				throw new Error('El Tipo de Documento es obligatorio');
			if (!formData.archivo_digitalizado_en?.trim())
				throw new Error('El campo "Archivo Digitalizado en" es obligatorio');

			const payload: ExpedienteArchivoCreateDTO = {
				e_document: formData.e_document || null,
				num_operacion: formData.num_operacion || null,
				tipo_documento: formData.tipo_documento || null,
				archivo_digitalizado_en: formData.archivo_digitalizado_en || null,
				fecha_digitalizacion: formData.fecha_digitalizacion || null,
				agente_aduanal: formData.agente_aduanal || null,
				pedimento: formData.pedimento || null,
				rfc_consulta: formData.rfc_consulta || null,
				nombre_archivo: formData.nombre_archivo || null
			};

			let response;
			let createdId: number | null = null;
			if (isEdit && item) {
				response = await expedienteArchivosApi.update(item.id, payload, company.id);
			} else {
				response = await expedienteArchivosApi.create(payload, company.id);
			}

			if (response.error) {
				const ve = (response as any).validationErrors;
				if (ve?.length) throw new Error(ve.map((e: any) => e.msg).join(' · '));
				throw new Error(response.error);
			}

			createdId = response.data?.id ?? item?.id ?? null;
			if (selectedFile && createdId) {
				const uploadResponse = await expedienteArchivosApi.uploadFile(createdId, selectedFile, company.id);
				if (uploadResponse.error) {
					if (!isEdit) {
						await expedienteArchivosApi.delete(createdId, company.id);
					}
					throw new Error(uploadResponse.error);
				}
			}

			open = false;
			onSuccess?.();
		} catch (e) {
			if (e && typeof e === 'object' && 'message' in e) {
				error = (e as Error).message;
			} else {
				error = 'Error desconocido';
			}
		} finally {
			loading = false;
		}
	}
</script>

<Dialog.Root bind:open>
	<Dialog.Content class="max-h-[90vh] overflow-y-auto sm:max-w-[700px]">
		<Dialog.Header>
			<Dialog.Title>{title}</Dialog.Title>
			{#if isEdit}
				<Dialog.Description>
					Modifica el documento digitalizado <span class="font-mono font-semibold">{item?.id}</span>.
				</Dialog.Description>
			{:else}
				<Dialog.Description>
					Captura un nuevo documento digitalizado.
				</Dialog.Description>
			{/if}
		</Dialog.Header>

		<form onsubmit={(e) => { e.preventDefault(); handleSubmit(); }} class="space-y-6">
			{#if error}
				<div class="rounded-lg border border-destructive bg-destructive/10 p-3 text-sm text-destructive">
					{error}
				</div>
			{/if}

			<div class="grid gap-6 py-4">
				<div class="space-y-4">
					<h4 class="text-sm leading-none font-medium text-muted-foreground">Documento</h4>
					<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
						<div class="space-y-2">
							<Label for="tipo_documento">{m['sidebar.digitalizacion.form_tipo_documento']()} *</Label>
							<Select.Root
								type="single"
								value={formData.tipo_documento ?? ''}
								onValueChange={(v) => (formData.tipo_documento = v || null)}
								disabled={loading || docTypesLoading}
							>
								<Select.Trigger id="tipo_documento" class="w-full">
									<span class="truncate">
										{docTypesLoading
											? 'Cargando tipos...'
											: selectedDocType
												? `${selectedDocType.code}${selectedDocType.description ? ` — ${selectedDocType.description}` : ''}`
												: 'Selecciona tipo...'}
									</span>
								</Select.Trigger>
								<Select.Content class="max-h-[300px]">
									{#each docTypes as dt}
										<Select.Item value={dt.code}>
											{dt.code}{dt.description ? ` — ${dt.description}` : ''}
										</Select.Item>
									{/each}
								</Select.Content>
							</Select.Root>
						</div>

						<div class="space-y-2">
							<Label for="fecha_digitalizacion">{m['sidebar.digitalizacion.form_fecha']()}</Label>
							<Input
								id="fecha_digitalizacion"
								type="date"
								value={formData.fecha_digitalizacion ?? ''}
								onchange={(e) => (formData.fecha_digitalizacion = (e.target as HTMLInputElement).value || null)}
								disabled={loading}
							/>
						</div>

						<div class="space-y-2">
							<Label for="rfc_consulta">{m['sidebar.digitalizacion.form_rfc_consulta']()}</Label>
							<Input
								id="rfc_consulta"
								value={formData.rfc_consulta ?? ''}
								oninput={(e) => (formData.rfc_consulta = (e.target as HTMLInputElement).value.toUpperCase())}
								placeholder="RFC para consulta"
								maxlength={13}
								disabled={loading}
							/>
						</div>

						<div class="space-y-2 md:col-span-2">
							<Label for="archivo_digitalizado_en">{m['sidebar.digitalizacion.form_archivo_digitalizado_en']()} *</Label>
							<FilePickerInput
								id="archivo_digitalizado_en"
								value={formData.nombre_archivo ?? formData.archivo_digitalizado_en ?? ''}
								placeholder="Seleccionar archivo..."
								disabled={loading}
								onchange={(file) => {
									selectedFile = file;
									formData.archivo_digitalizado_en = file.name;
									formData.nombre_archivo = file.name;
								}}
							/>
						</div>
					</div>
				</div>

				<Separator />

				<div class="space-y-4">
					<h4 class="text-sm leading-none font-medium text-muted-foreground">Consulta y referencia</h4>
					<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
						<div class="space-y-2">
							<Label for="e_document">{m['sidebar.digitalizacion.form_e_document']()}</Label>
							<Input
								id="e_document"
								value={formData.e_document ?? ''}
								oninput={(e) => (formData.e_document = (e.target as HTMLInputElement).value)}
								placeholder="E-Document"
								disabled={loading}
							/>
						</div>

						<div class="space-y-2">
							<Label for="num_operacion">{m['sidebar.digitalizacion.form_num_operacion']()}</Label>
							<Input
								id="num_operacion"
								value={formData.num_operacion ?? ''}
								oninput={(e) => (formData.num_operacion = (e.target as HTMLInputElement).value)}
								placeholder="Número de operación"
								disabled={loading}
							/>
						</div>

						<div class="space-y-2">
							<Label for="agente_aduanal">{m['sidebar.digitalizacion.form_agente_aduanal']()}</Label>
							<Select.Root
								type="single"
								value={formData.agente_aduanal ?? ''}
								onValueChange={(v) => onBrokerSelected(v || undefined)}
								disabled={loading || brokersLoading}
							>
								<Select.Trigger id="agente_aduanal" class="w-full">
									<span class="truncate">
										{brokersLoading
											? 'Cargando agentes...'
											: selectedBroker
												? `${selectedBroker.license}${selectedBroker.name ? ` — ${selectedBroker.name}` : ''}`
												: 'Selecciona agente...'}
									</span>
								</Select.Trigger>
								<Select.Content class="max-h-[300px]">
									{#each brokers as broker}
										<Select.Item value={broker.license}>
											{broker.license}{broker.name ? ` — ${broker.name}` : ''}
										</Select.Item>
									{/each}
								</Select.Content>
							</Select.Root>
						</div>

						<div class="space-y-2 md:col-span-2">
							<Label for="pedimento">{m['sidebar.digitalizacion.form_pedimento']()}</Label>
							<div class="flex gap-2">
								<Input
									id="pedimento"
									value={formData.pedimento ?? ''}
									placeholder="Selecciona desde el catálogo de pedimentos"
									class="flex-1 bg-muted"
									readonly
									disabled
								/>
								<Button
									type="button"
									variant="outline"
									size="icon"
									onclick={() => (isPedimentoDialogOpen = true)}
									disabled={loading}
								>
									<Search class="h-4 w-4" />
								</Button>
							</div>
						</div>
					</div>
				</div>
			</div>

			<Dialog.Footer class="flex justify-end gap-2 pt-2">
				<Button type="button" variant="outline" onclick={() => (open = false)} disabled={loading}>
					Cancelar
				</Button>
				<Button type="submit" disabled={loading}>
					{#if loading}
						<LoaderCircle class="mr-2 h-4 w-4 animate-spin" />
					{/if}
					{isEdit ? 'Guardar' : 'Crear'}
				</Button>
			</Dialog.Footer>
		</form>
	</Dialog.Content>
</Dialog.Root>

<PedimentoSelectorDialog bind:open={isPedimentoDialogOpen} onSelect={handlePedimentoSelect} />
