<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 { Switch } from '$lib/components/ui/switch';
	import * as Select from '$lib/components/ui/select';
	import { transportersApi, type Transporter } from '$lib/api/dashboard/a76/transporters';
	import { countriesApi, type Country } from '$lib/api/dashboard/reference_data/countries';
	import { statesApi, type State } from '$lib/api/dashboard/reference_data/states';
	import { companyStore } from '$lib/stores/company.svelte';
	import { browser } from '$app/environment';
	import { onMount, onDestroy } from 'svelte';

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

	// Determinar si es modo edición o creación
	const isEdit = $derived(!!item);
	const title = $derived(isEdit ? 'Editar Transportista' : 'Nuevo Transportista');

	// Estado del formulario
	let formData = $state<Transporter>({
		transporter_key: '',
		name: '',
		short_name: '',
		responsible: '',
		rfc: '',
		streets: '',
		postal_code: '',
		city: '',
		state: '',
		country: '',
		loader_code: '',
		caat_code: '',
		transport_code: '',
		transport_interface_type: '',
		ftp_server: '',
		ftp_user: '',
		ftp_password: '',
		ftp_directory: '',
		filler_code: '',
		has_express_line: false
	});

	let loading = $state(false);
	let error = $state<string | null>(null);
	let countries = $state<Country[]>([]);
	let states = $state<State[]>([]);
	let refsLoading = $state(false);

	const countryM3 = $derived(
		countries.find((c) => c.ame_key === formData.country)?.m3_key ?? null
	);
	const statesFiltered = $derived(
		countryM3 ? states.filter((s) => s.m3_key === countryM3) : states
	);

	async function loadReferenceData() {
		if (!browser) return;
		refsLoading = true;
		try {
			const [cc, ss] = await Promise.all([
				countriesApi.list(1, 100),
				statesApi.list(1, 100)
			]);
			if (cc.data?.items) countries = cc.data.items;
			if (ss.data?.items) states = ss.data.items;
		} catch {
			countries = [];
			states = [];
		} finally {
			refsLoading = false;
		}
	}

	function emptyTransporterForm(): Transporter {
		return {
			transporter_key: '',
			name: '',
			short_name: '',
			responsible: '',
			rfc: '',
			streets: '',
			postal_code: '',
			city: '',
			state: '',
			country: '',
			loader_code: '',
			caat_code: '',
			transport_code: '',
			transport_interface_type: '',
			ftp_server: '',
			ftp_user: '',
			ftp_password: '',
			ftp_directory: '',
			filler_code: '',
			has_express_line: false
		};
	}

	$effect(() => {
		if (!open) {
			error = null;
			loading = false;
			return;
		}
		if (item) {
			formData = { ...item, has_express_line: item.has_express_line ?? false };
		} else {
			formData = emptyTransporterForm();
		}
		void loadReferenceData();
	});

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

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

			// Validación básica
			if (!formData.transporter_key.trim()) {
				throw new Error('La clave es requerida');
			}

			let response;
			if (isEdit && item) {
				response = await transportersApi.update(item.transporter_key, formData, companyId);
			} else {
				response = await transportersApi.create(formData, companyId);
			}

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

			// Cerrar diálogo y notificar éxito
			open = false;
			if (onSuccess) {
				onSuccess();
			}
		} catch (e) {
			error = e instanceof Error ? e.message : 'Error al guardar el transportista';
		} finally {
			loading = false;
		}
	}

	function handleCancel() {
		open = false;
		error = null;
	}

	function onSaveFormEvent() {
		void handleSubmit();
	}

	$effect(() => {
		if (!browser) return;
		document.addEventListener('save-form', onSaveFormEvent);
		return () => document.removeEventListener('save-form', onSaveFormEvent);
	});
</script>

<Dialog.Root bind:open>
	<Dialog.Content class="max-h-[90vh] overflow-y-auto sm:max-w-5xl">
		<Dialog.Header>
			<Dialog.Title>{title}</Dialog.Title>
			<Dialog.Description>
				{isEdit
					? 'Modifica los datos del transportista'
					: 'Completa los datos para crear un nuevo transportista'}
			</Dialog.Description>
		</Dialog.Header>

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

			<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
				<!-- Información General -->
				<section class="space-y-4">
					<h3 class="border-b pb-2 text-sm font-semibold">Información General</h3>

					<div class="grid gap-2">
						<Label for="transporter_key">Clave <span class="text-destructive">*</span></Label>
						<Input
							id="transporter_key"
							bind:value={formData.transporter_key}
							disabled={isEdit}
							required
							maxlength={30}
						/>
					</div>

					<div class="grid gap-2">
						<Label for="name">Nombre / Razón Social</Label>
						<Input id="name" bind:value={formData.name} maxlength={256} />
					</div>

					<div class="grid gap-2">
						<Label for="short_name">Nombre Corto</Label>
						<Input
							id="short_name"
							bind:value={formData.short_name}
							maxlength={10}
							placeholder="Máx. 10 car."
						/>
					</div>

					<div class="grid gap-2">
						<Label for="rfc">RFC</Label>
						<Input id="rfc" bind:value={formData.rfc} maxlength={30} />
					</div>

					<div class="grid gap-2">
						<Label for="responsible">Responsable</Label>
						<Input id="responsible" bind:value={formData.responsible} maxlength={100} />
					</div>
				</section>

				<!-- Códigos y Transporte -->
				<section class="space-y-4">
					<h3 class="border-b pb-2 text-sm font-semibold">Códigos de Transporte</h3>

					<div class="grid gap-2">
						<Label for="caat_code">Código CAAT</Label>
						<Input id="caat_code" bind:value={formData.caat_code} maxlength={49} />
					</div>

					<div class="grid gap-2">
						<Label for="transport_code">Código de Transporte</Label>
						<Input
							id="transport_code"
							bind:value={formData.transport_code}
							maxlength={8}
							placeholder="Máx. 8 car."
						/>
					</div>

					<div class="grid gap-2">
						<Label for="loader_code">Código Cargador</Label>
						<Input
							id="loader_code"
							bind:value={formData.loader_code}
							maxlength={9}
							placeholder="Máx. 9 car."
						/>
					</div>

					<div class="grid gap-2">
						<Label for="transport_interface_type">Tipo Interfaz</Label>
						<Input
							id="transport_interface_type"
							bind:value={formData.transport_interface_type}
							maxlength={20}
						/>
					</div>

					<div class="grid gap-2">
						<Label for="filler_code">Código Relleno</Label>
						<Input id="filler_code" bind:value={formData.filler_code} maxlength={20} />
					</div>

					<div class="flex items-center justify-between gap-3 rounded-lg border p-4">
						<Label for="has_express_line" class="text-sm font-medium">Carril express</Label>
						<Switch id="has_express_line" bind:checked={formData.has_express_line} />
					</div>
				</section>

				<!-- Dirección -->
				<section class="space-y-4">
					<h3 class="border-b pb-2 text-sm font-semibold">Dirección</h3>

					<div class="grid gap-2">
						<Label for="streets">Calle y Número</Label>
						<Input id="streets" bind:value={formData.streets} maxlength={100} />
					</div>

					<div class="grid grid-cols-2 gap-4">
						<div class="grid gap-2">
							<Label for="city">Ciudad</Label>
							<Input id="city" bind:value={formData.city} maxlength={30} />
						</div>
						<div class="grid gap-2">
							<Label for="country">País (clave americana)</Label>
							<Select.Root type="single" bind:value={formData.country} disabled={refsLoading}>
								<Select.Trigger class="w-full" id="country">
									{refsLoading
										? '...'
										: formData.country
											? `${formData.country} — ${countries.find((c) => c.ame_key === formData.country)?.description_es ?? ''}`
											: '— Opcional —'}
								</Select.Trigger>
								<Select.Content class="max-h-60">
									<Select.Item value="" label="Vacío">— Vacío —</Select.Item>
									{#each countries as c}
										<Select.Item value={c.ame_key} label={c.ame_key}>
											{c.ame_key} — {c.description_es}
										</Select.Item>
									{/each}
								</Select.Content>
							</Select.Root>
						</div>
					</div>

					<div class="grid grid-cols-2 gap-4">
						<div class="grid gap-2">
							<Label for="state">Estado / provincia</Label>
							<Select.Root type="single" bind:value={formData.state} disabled={refsLoading}>
								<Select.Trigger class="w-full" id="state">
									{refsLoading
										? '...'
										: formData.state ||
											(formData.country ? '— Selecciona —' : '— Primero el país —')}
								</Select.Trigger>
								<Select.Content class="max-h-60">
									<Select.Item value="" label="Vacío">— Vacío —</Select.Item>
									{#each statesFiltered as s}
										<Select.Item value={s.description} label={s.description}>
											{s.description}
										</Select.Item>
									{/each}
								</Select.Content>
							</Select.Root>
						</div>
						<div class="grid gap-2">
							<Label for="postal_code">C.P.</Label>
							<Input id="postal_code" bind:value={formData.postal_code} maxlength={15} />
						</div>
					</div>
				</section>

				<!-- Configuración FTP -->
				<section class="space-y-4">
					<h3 class="border-b pb-2 text-sm font-semibold">Configuración FTP</h3>

					<div class="grid gap-2">
						<Label for="ftp_server">Servidor FTP</Label>
						<Input id="ftp_server" bind:value={formData.ftp_server} maxlength={200} />
					</div>

					<div class="grid grid-cols-2 gap-4">
						<div class="grid gap-2">
							<Label for="ftp_user">Usuario</Label>
							<Input id="ftp_user" bind:value={formData.ftp_user} maxlength={200} />
						</div>
						<div class="grid gap-2">
							<Label for="ftp_password">Contraseña</Label>
							<Input id="ftp_password" type="password" bind:value={formData.ftp_password} maxlength={100} />
						</div>
					</div>

					<div class="grid gap-2">
						<Label for="ftp_directory">Directorio</Label>
						<Input id="ftp_directory" bind:value={formData.ftp_directory} maxlength={1000} />
					</div>
				</section>
			</div>

			<Dialog.Footer>
				<Button type="button" variant="outline" onclick={handleCancel} disabled={loading}>
					Cancelar
				</Button>
				<Button type="submit" disabled={loading}>
					{loading ? 'Guardando...' : isEdit ? 'Actualizar' : 'Crear'}
				</Button>
			</Dialog.Footer>
		</form>
	</Dialog.Content>
</Dialog.Root>
