<script lang="ts">
	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 Select from "$lib/components/ui/select";
	import { invoicesApi, type Invoice, type CreateInvoiceData, type UpdateInvoiceData } from "$lib/api/dashboard/a76/invoices";
	import { getExchangeRates } from "$lib/api/dashboard/a76/general_catalogs/exchange-rate";
	import { companyStore } from "$lib/stores/company.svelte";
	import { LoaderCircle } from 'lucide-svelte';
	import * as Tabs from "$lib/components/ui/tabs";
	import ExchangeRateDialog from "$lib/components/dashboard/exchange_rate/create-edit-dialog.svelte";

	let {
		open = $bindable(false),
		item = $bindable<Invoice | null>(null),
		defaultOperationType,
		defaultInvoiceType,
		onSuccess
	}: {
		open: boolean;
		item?: Invoice | null;
		defaultOperationType?: 'imp' | 'exp';
		defaultInvoiceType?: string;
		onSuccess?: () => void;
	} = $props();

	let formData = $state({
		// Header fields
		operation_type: "imp" as "imp" | "exp",
		invoice_type: "",
		invoice_number: "",
		project_number: "",
		purchase_order: "",
		related_doc_id: null as number | null,
		invoice_date: "",
		traffic_light_status: "",
		observation_es: "",
		observation_en: "",
		comments_status: "",
		cfdi_uuid: "",
		path_pdf: "",
		path_xml: "",
		// Compliance MX fields
		remesa: null as number | null,
		aduana: "",
		customs_broker_id: "",
		provider_id: "",
		sold_to_id: "",
		shipped_to_id: "",
		shipped_by_id: "",
		is_mixed: false,
		waste_type: "",
		appendix_17: null as number | null,
		edocument: "",
		// Financials fields
		currency: "MXN",
		exchange_rate: null as number | null,
		value_mn: null as number | null,
		value_me: null as number | null,
		customs_value_mn: null as number | null,
		freight: null as number | null,
		insurance: null as number | null,
		iva_mn: null as number | null,
		iva_factor: null as string | null,
		total_quantity: null as number | null,
		gross_weight: null as number | null,
		net_weight: null as number | null,
		bundle_count: null as number | null
	});

	let loading = $state(false);
	let error = $state<string | null>(null);

	let showExchangeRateDialog = $state(false);
	let missingExchangeRateDate = $state("");

	// Actualizar formData cuando item cambia
	$effect(() => {
		if (item) {
			formData = {
				operation_type: item.operation_type || "imp",
				invoice_type: item.invoice_type || "",
				invoice_number: item.invoice_number || "",
				project_number: item.project_number || "",
				purchase_order: item.purchase_order || "",
				related_doc_id: item.related_doc_id || null,
				invoice_date: item.invoice_date || "",
				traffic_light_status: item.traffic_light_status || "",
				observation_es: item.observation_es || "",
				observation_en: item.observation_en || "",
				comments_status: item.comments_status || "",
				cfdi_uuid: item.cfdi_uuid || "",
				path_pdf: item.path_pdf || "",
				path_xml: item.path_xml || "",
				remesa: item.compliance_mx?.remesa || null,
				aduana: item.compliance_mx?.aduana || "",
				customs_broker_id: item.compliance_mx?.customs_broker_id?.toString() || "",
				provider_id: item.compliance_mx?.provider_id?.toString() || "",
				sold_to_id: item.compliance_mx?.sold_to_id?.toString() || "",
				shipped_to_id: item.compliance_mx?.shipped_to_id?.toString() || "",
				shipped_by_id: item.compliance_mx?.shipped_by_id?.toString() || "",
				is_mixed: item.compliance_mx?.is_mixed || false,
				waste_type: item.compliance_mx?.waste_type || "",
				appendix_17: item.compliance_mx?.appendix_17 || null,
				edocument: item.compliance_mx?.edocument || "",
				currency: item.financials?.currency || "MXN",
				exchange_rate: item.financials?.exchange_rate || null,
				value_mn: item.financials?.value_mn || null,
				value_me: item.financials?.value_me || null,
				customs_value_mn: item.financials?.customs_value_mn || null,
				freight: item.financials?.freight || null,
				insurance: item.financials?.insurance || null,
				iva_mn: item.financials?.iva_mn || null,
				iva_factor: item.financials?.iva_factor || null,
				total_quantity: item.financials?.total_quantity || null,
				gross_weight: item.financials?.gross_weight || null,
				net_weight: item.financials?.net_weight || null,
				bundle_count: item.financials?.bundle_count || null
			};
		} else {
			resetForm();
		}
	});

	const isEditing = $derived(!!item);

	function resetForm() {
		formData = {
			operation_type: defaultOperationType || "imp",
			invoice_type: defaultInvoiceType || "",
			invoice_number: "",
			project_number: "",
			purchase_order: "",
			related_doc_id: null,
			invoice_date: "",
			traffic_light_status: "",
			observation_es: "",
			observation_en: "",
			comments_status: "",
			cfdi_uuid: "",
			path_pdf: "",
			path_xml: "",
			remesa: null,
			aduana: "",
			customs_broker_id: "",
			provider_id: "",
			sold_to_id: "",
			shipped_to_id: "",
			shipped_by_id: "",
			is_mixed: false,
			waste_type: "",
			appendix_17: null,
			edocument: "",
			currency: "MXN",
			exchange_rate: null,
			value_mn: null,
			value_me: null,
			customs_value_mn: null,
			freight: null,
			insurance: null,
			iva_mn: null,
			iva_factor: null,
			total_quantity: null,
			gross_weight: null,
			net_weight: null,
			bundle_count: null
		};
	}

	async function handleSubmit(e: Event) {
		e.preventDefault();
		
		if (!companyStore.activeCompany) {
			error = "No hay compañía seleccionada";
			return;
		}

		loading = true;
		error = null;

		try {
            // Verificar tipo de cambio antes de guardar
            if (formData.invoice_date) {
                const rateExists = await checkExchangeRate(formData.invoice_date);
                if (!rateExists) {
                    loading = false;
                    return;
                }
            }

			let response;
			if (isEditing && item) {
				const payload: UpdateInvoiceData = {
					id: item.id,
					operation_type: formData.operation_type,
					invoice_type: formData.invoice_type || null,
					invoice_number: formData.invoice_number || null,
					project_number: formData.project_number || null,
					purchase_order: formData.purchase_order || null,
					related_doc_id: formData.related_doc_id,
					invoice_date: formData.invoice_date || null,
					traffic_light_status: formData.traffic_light_status || null,
					observation_es: formData.observation_es || null,
					observation_en: formData.observation_en || null,
					comments_status: formData.comments_status || null,
					cfdi_uuid: formData.cfdi_uuid || null,
					path_pdf: formData.path_pdf || null,
					path_xml: formData.path_xml || null,
					compliance_mx: {
						remesa: formData.remesa,
						aduana: formData.aduana || null,
						customs_broker_id: formData.customs_broker_id ? parseInt(formData.customs_broker_id) : null,
						provider_id: formData.provider_id ? parseInt(formData.provider_id) : null,
						sold_to_id: formData.sold_to_id ? parseInt(formData.sold_to_id) : null,
						shipped_to_id: formData.shipped_to_id ? parseInt(formData.shipped_to_id) : null,
						shipped_by_id: formData.shipped_by_id ? parseInt(formData.shipped_by_id) : null,
						is_mixed: formData.is_mixed,
						waste_type: formData.waste_type || null,
						appendix_17: formData.appendix_17 || null,
						edocument: formData.edocument || null
					},
					financials: {
						currency: formData.currency || null,
						exchange_rate: formData.exchange_rate,
						value_mn: formData.value_mn,
						value_me: formData.value_me,
						customs_value_mn: formData.customs_value_mn,
						freight: formData.freight,
						insurance: formData.insurance,
						iva_mn: formData.iva_mn,
						iva_factor: formData.iva_factor,
						total_quantity: formData.total_quantity,
						gross_weight: formData.gross_weight,
						net_weight: formData.net_weight,
						bundle_count: formData.bundle_count
					}
				};
				response = await invoicesApi.update(item.id, companyStore.activeCompany.id, payload);
			} else {
				const payload: CreateInvoiceData = {					
					system: "a76",
					document_type: "invoice",					
					operation_type: formData.operation_type,
					invoice_type: formData.invoice_type,
					invoice_number: formData.invoice_number,
					project_number: formData.project_number || null,
					purchase_order: formData.purchase_order || null,
					related_doc_id: formData.related_doc_id,
					invoice_date: formData.invoice_date || null,
					traffic_light_status: formData.traffic_light_status || null,
					observation_es: formData.observation_es || null,
					observation_en: formData.observation_en || null,
					comments_status: formData.comments_status || null,
					cfdi_uuid: formData.cfdi_uuid || null,
					path_pdf: formData.path_pdf || null,
					path_xml: formData.path_xml || null,
					compliance_mx: {
						remesa: formData.remesa,
						aduana: formData.aduana || null,
						customs_broker_id: formData.customs_broker_id ? parseInt(formData.customs_broker_id) : null,
						provider_id: formData.provider_id ? parseInt(formData.provider_id) : null,
						sold_to_id: formData.sold_to_id ? parseInt(formData.sold_to_id) : null,
						shipped_to_id: formData.shipped_to_id ? parseInt(formData.shipped_to_id) : null,
						shipped_by_id: formData.shipped_by_id ? parseInt(formData.shipped_by_id) : null,
						is_mixed: formData.is_mixed,
						waste_type: formData.waste_type || null,
						appendix_17: formData.appendix_17 || null,
						edocument: formData.edocument || null
					},
					financials: {
						currency: formData.currency || null,
						exchange_rate: formData.exchange_rate,
						value_mn: formData.value_mn,
						value_me: formData.value_me,
						customs_value_mn: formData.customs_value_mn,
						freight: formData.freight,
						insurance: formData.insurance,
						iva_mn: formData.iva_mn,
						iva_factor: formData.iva_factor,
						total_quantity: formData.total_quantity,
						gross_weight: formData.gross_weight,
						net_weight: formData.net_weight,
						bundle_count: formData.bundle_count
					}
				};
				response = await invoicesApi.create(companyStore.activeCompany.id, payload);
			}

			if (response.error) {
				if (response.status === 401) {
					error = 'Sesión expirada. Recargando página...';
					setTimeout(() => {
						window.location.reload();
					}, 1500);
				} else {
                    // Convertir el error a string para buscar mensajes específicos (maneja objetos/arrays de DRF)
                    const errorStr = typeof response.error === 'string' 
                        ? response.error 
                        : JSON.stringify(response.error);
                        
                    if (errorStr.includes('No existe un Tipo de Cambio registrado') || errorStr.includes('financials.exchange_rate')) {
                        // Interceptar error de tipo de cambio                        
                        error = null;
                        
                        const dateMatch = errorStr.match(/(\d{4}-\d{2}-\d{2})/);
                        missingExchangeRateDate = dateMatch ? dateMatch[0] : (formData.invoice_date || "");
                        
                        showExchangeRateDialog = true;
                        return;
                    }

					error = response.error;
				}
				return;
			}

			// Check exchange rate BEFORE calling API to avoid 400 error
            if (formData.invoice_date) {
                const rateExists = await checkExchangeRate(formData.invoice_date);
                if (!rateExists) {
                    loading = false;
                    return;
                }
            }

			// Éxito
			open = false;
			if (onSuccess) {
				onSuccess();
			}
		} catch (e) {
			error = e instanceof Error ? e.message : "Error al guardar";
			console.error("Error saving:", e);
		} finally {
			loading = false;
		}
	}

	async function checkExchangeRate(date: string): Promise<boolean> {
		if (!date || !companyStore.activeCompany?.id) return true;

		try {
			const response = await getExchangeRates(companyStore.activeCompany.id, {
				date: date,
				page_size: 1
			});
            
			// api.get returns { data: ..., status: ... } and types now reflect that
			const items = response.data?.items || [];
			
            // Verificar estrictamente que haya items
			if (items.length === 0) {
				missingExchangeRateDate = date;
				showExchangeRateDialog = true;
				return false;
			}
			return true;
		} catch (error) {
			console.error('Error checking exchange rate:', error);
			missingExchangeRateDate = date;
			showExchangeRateDialog = true;
			return false; 
		}
	}

	function handleOpenChange(newOpen: boolean) {
		if (!newOpen) {
			resetForm();
			error = null;
		}
		open = newOpen;
	}
</script>

<Dialog.Root {open} onOpenChange={handleOpenChange}>
    <Dialog.Content class="sm:max-w-full max-h-[90vh] overflow-y-auto">
		<Dialog.Header>
			<Dialog.Title>
				{isEditing ? "Editar Factura" : "Nueva Factura"}
			</Dialog.Title>
			<Dialog.Description>
				{isEditing 
					? "Modifica los datos de la factura"
					: "Ingresa los datos de la nueva factura"}
			</Dialog.Description>
		</Dialog.Header>

		<form onsubmit={handleSubmit} class="space-y-4">
			<Tabs.Root value="general" class="w-full">
				<Tabs.List class="grid w-full grid-cols-3">
					<Tabs.Trigger value="general">General</Tabs.Trigger>
					<Tabs.Trigger value="compliance">Cumplimiento</Tabs.Trigger>
					<Tabs.Trigger value="financials">Financieros</Tabs.Trigger>
				</Tabs.List>

				<!-- General Tab -->
				<Tabs.Content value="general" class="space-y-4">
					<div class="grid grid-cols-2 gap-4">
					<div class="space-y-2">
						<Label for="operation_type">Tipo de Operación *</Label>
						<Select.Root
							type="single"
							value={formData.operation_type}
							onValueChange={(v: string) => {
								if (v) formData.operation_type = v as "imp" | "exp";
							}}
						>
							<Select.Trigger>
								{formData.operation_type === 'imp' ? 'Importación' : formData.operation_type === 'exp' ? 'Exportación' : 'Seleccionar tipo'}
							</Select.Trigger>
							<Select.Content>
								<Select.Item value="imp">Importación</Select.Item>
								<Select.Item value="exp">Exportación</Select.Item>
							</Select.Content>
						</Select.Root>
					</div>						<div class="space-y-2">
							<Label for="invoice_number">Número de Factura</Label>
							<Input
								id="invoice_number"
								bind:value={formData.invoice_number}
								placeholder="Número de factura"
							/>
						</div>

						<div class="space-y-2">
							<Label for="invoice_type">Tipo de Factura</Label>
							<Input
								id="invoice_type"
								bind:value={formData.invoice_type}
								placeholder="Tipo de factura"
							/>
						</div>

						<div class="space-y-2">
							<Label for="project_number">Número de Proyecto</Label>
							<Input
								id="project_number"
								bind:value={formData.project_number}
								placeholder="Número de proyecto"
							/>
						</div>

						<div class="space-y-2">
							<Label for="purchase_order">Orden de Compra</Label>
							<Input
								id="purchase_order"
								bind:value={formData.purchase_order}
								placeholder="Orden de compra"
							/>
						</div>

						<div class="space-y-2">
							<Label for="invoice_date">Fecha de Factura</Label>
							<Input
								id="invoice_date"
								type="date"
								bind:value={formData.invoice_date}
							/>
						</div>

						<div class="space-y-2">
							<Label for="traffic_light_status">Semáforo</Label>
							<Input
								id="traffic_light_status"
								bind:value={formData.traffic_light_status}
								placeholder="Estado del semáforo"
							/>
						</div>

						<div class="space-y-2">
							<Label for="cfdi_uuid">CFDI UUID</Label>
							<Input
								id="cfdi_uuid"
								bind:value={formData.cfdi_uuid}
								placeholder="UUID del CFDI"
							/>
						</div>
					</div>

					<div class="grid grid-cols-1 gap-4">
						<div class="space-y-2">
							<Label for="observation_es">Observaciones (Español)</Label>
							<Input
								id="observation_es"
								bind:value={formData.observation_es}
								placeholder="Observaciones en español"
							/>
						</div>

						<div class="space-y-2">
							<Label for="observation_en">Observaciones (Inglés)</Label>
							<Input
								id="observation_en"
								bind:value={formData.observation_en}
								placeholder="Observaciones en inglés"
							/>
						</div>
					</div>
				</Tabs.Content>

				<!-- Compliance Tab -->
				<Tabs.Content value="compliance" class="space-y-4">
					<div class="grid grid-cols-2 gap-4">
						<div class="space-y-2">
							<Label for="remesa">Remesa</Label>
							<Input
								id="remesa"
								type="number"
								bind:value={formData.remesa}
								placeholder="Número de remesa"
							/>
						</div>

						<div class="space-y-2">
							<Label for="aduana">Aduana</Label>
							<Input
								id="aduana"
								bind:value={formData.aduana}
								placeholder="Código de aduana"
							/>
						</div>

						<div class="space-y-2">
							<Label for="customs_broker_id">Agente Aduanal</Label>
							<Input
								id="customs_broker_id"
								bind:value={formData.customs_broker_id}
								placeholder="ID del agente aduanal"
							/>
						</div>

						<div class="space-y-2">
							<Label for="provider_id">Proveedor</Label>
							<Input
								id="provider_id"
								bind:value={formData.provider_id}
								placeholder="ID del proveedor"
							/>
						</div>

						<div class="space-y-2">
							<Label for="edocument">E-Document</Label>
							<Input
								id="edocument"
								bind:value={formData.edocument}
								placeholder="Número de e-document"
							/>
						</div>

						<div class="space-y-2 flex items-center gap-2 pt-8">
							<input
								id="is_mixed"
								type="checkbox"
								bind:checked={formData.is_mixed}
								class="h-4 w-4"
							/>
							<Label for="is_mixed" class="!mt-0">Operación Mixta</Label>
						</div>
					</div>
				</Tabs.Content>

				<!-- Financials Tab -->
				<Tabs.Content value="financials" class="space-y-4">
					<div class="grid grid-cols-2 gap-4">
						<div class="space-y-2">
							<Label for="currency">Moneda</Label>
							<Input
								id="currency"
								bind:value={formData.currency}
								placeholder="MXN, USD, etc."
							/>
						</div>

						<div class="space-y-2">
							<Label for="exchange_rate">Tipo de Cambio</Label>
							<Input
								id="exchange_rate"
								type="number"
								step="0.000001"
								bind:value={formData.exchange_rate}
								placeholder="Tipo de cambio"
							/>
						</div>

						<div class="space-y-2">
							<Label for="value_mn">Valor MN</Label>
							<Input
								id="value_mn"
								type="number"
								step="0.01"
								bind:value={formData.value_mn}
								placeholder="Valor en moneda nacional"
							/>
						</div>

						<div class="space-y-2">
							<Label for="value_me">Valor ME</Label>
							<Input
								id="value_me"
								type="number"
								step="0.01"
								bind:value={formData.value_me}
								placeholder="Valor en moneda extranjera"
							/>
						</div>

						<div class="space-y-2">
							<Label for="customs_value_mn">Valor Aduana MN</Label>
							<Input
								id="customs_value_mn"
								type="number"
								step="0.01"
								bind:value={formData.customs_value_mn}
								placeholder="Valor de aduana en MN"
							/>
						</div>

						<div class="space-y-2">
							<Label for="freight">Flete</Label>
							<Input
								id="freight"
								type="number"
								step="0.01"
								bind:value={formData.freight}
								placeholder="Costo de flete"
							/>
						</div>

						<div class="space-y-2">
							<Label for="insurance">Seguro</Label>
							<Input
								id="insurance"
								type="number"
								step="0.01"
								bind:value={formData.insurance}
								placeholder="Costo de seguro"
							/>
						</div>

						<div class="space-y-2">
							<Label for="iva_mn">IVA MN</Label>
							<Input
								id="iva_mn"
								type="number"
								step="0.01"
								bind:value={formData.iva_mn}
								placeholder="IVA en MN"
							/>
						</div>

						<div class="space-y-2">
							<Label for="total_quantity">Cantidad Total</Label>
							<Input
								id="total_quantity"
								type="number"
								step="0.01"
								bind:value={formData.total_quantity}
								placeholder="Cantidad total"
							/>
						</div>

						<div class="space-y-2">
							<Label for="gross_weight">Peso Bruto</Label>
							<Input
								id="gross_weight"
								type="number"
								step="0.01"
								bind:value={formData.gross_weight}
								placeholder="Peso bruto"
							/>
						</div>

						<div class="space-y-2">
							<Label for="net_weight">Peso Neto</Label>
							<Input
								id="net_weight"
								type="number"
								step="0.01"
								bind:value={formData.net_weight}
								placeholder="Peso neto"
							/>
						</div>

						<div class="space-y-2">
							<Label for="bundle_count">Número de Bultos</Label>
							<Input
								id="bundle_count"
								type="number"
								bind:value={formData.bundle_count}
								placeholder="Número de bultos"
							/>
						</div>
					</div>
				</Tabs.Content>
			</Tabs.Root>

			{#if error}
				<div class="p-3 text-sm text-destructive bg-destructive/10 rounded-md">
					{error}
				</div>
			{/if}

			<Dialog.Footer>
				<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}
					{isEditing ? "Actualizar" : "Crear"}
				</Button>
			</Dialog.Footer>
		</form>
	</Dialog.Content>
</Dialog.Root>

<ExchangeRateDialog 
	bind:open={showExchangeRateDialog} 
	initialDate={missingExchangeRateDate}
	overlayClass="bg-black/20"
	onSuccess={() => {/* Optional: maybe refresh something or just let user continue */}} 
/>
