<script lang="ts">
	import { onMount } from 'svelte';
	import type { ServiceRequestInput, Account, Contact, Supplier } from '$lib/api/crm';
	import { crmCatalogs } from '$lib/stores/crm-catalogs.svelte';
	import { OPERATION_TYPES, TRANSPORT_MODES, SERVICE_TYPES, LOAD_TYPES, PRIORITIES, SR_STATUS } from '$lib/components/crm/format';

	let {
		form = $bindable(),
		tab,
		accounts = [],
		contacts = [],
		suppliers = []
	}: {
		form: ServiceRequestInput;
		tab: string;
		accounts?: Account[];
		contacts?: Contact[];
		suppliers?: Supplier[];
	} = $props();

	const inputCls =
		'rounded-md border bg-transparent px-3 py-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring';

	// Modalidad de carga según el tipo de transporte (solo se habilita lo que corresponde)
	const MODALIDAD_BY_TRANSPORT: Record<string, string[]> = {
		maritimo: ['FCL', 'LCL', 'AMBAS'],
		aereo: ['AEREO'],
		terrestre: ['FTL', 'LTL']
		// ferroviario / multimodal: sin modalidad
	};
	const modalidadOptions = $derived(
		LOAD_TYPES.filter((l) => (MODALIDAD_BY_TRANSPORT[form.transport_mode ?? ''] ?? []).includes(l.value))
	);
	const showModalidad = $derived(modalidadOptions.length > 0);

	// Reglas: al cambiar el transporte, la modalidad inválida se limpia; si solo hay una (aéreo), se autoselecciona
	$effect(() => {
		const allowed = MODALIDAD_BY_TRANSPORT[form.transport_mode ?? ''] ?? [];
		if (allowed.length === 0) {
			if (form.load_type) form.load_type = undefined;
			return;
		}
		if (form.load_type && !allowed.includes(form.load_type)) form.load_type = undefined;
		if (!form.load_type && allowed.length === 1) form.load_type = allowed[0];
	});
	// La modalidad aérea fija el medio de transporte en "aéreo"
	$effect(() => {
		if (form.load_type === 'AEREO' && form.transport_mode !== 'aereo') form.transport_mode = 'aereo';
	});

	const isFcl = $derived(form.load_type === 'FCL' || form.load_type === 'AMBAS');
	const isLcl = $derived(form.load_type === 'LCL' || form.load_type === 'AMBAS');
	const isAir = $derived(form.load_type === 'AEREO');

	// Conversión de dimensiones a cm según la unidad de medida (para volumen m³ y P/Vol)
	const UNIT_TO_CM: Record<string, number> = { cm: 1, m: 100, in: 2.54, ft: 30.48 };
	const unitCm = $derived(UNIT_TO_CM[form.measurement_unit ?? 'cm'] ?? 1);
	const airQty = $derived(Number(form.pallets_count) || Number(form.pieces_count) || 1);
	const dimL = $derived((Number(form.length_cm) || 0) * unitCm);
	const dimW = $derived((Number(form.width_cm) || 0) * unitCm);
	const dimH = $derived((Number(form.height_cm) || 0) * unitCm);
	const hasDims = $derived(dimL > 0 && dimW > 0 && dimH > 0);
	// Volumen SIEMPRE en m³ (cm³ / 1,000,000)
	const volumeM3 = $derived(hasDims ? (dimL * dimW * dimH * airQty) / 1_000_000 : 0);
	// P/Vol aéreo (kg) = (L×A×H cm × bultos) / 6000; a cobrar = max(bruto, P/Vol)
	const airVolumetric = $derived(hasDims ? (dimL * dimW * dimH * airQty) / 6000 : 0);
	const airChargeable = $derived(Math.max(Number(form.weight) || 0, airVolumetric));

	// Autocompletar el volumen en m³ a partir de las dimensiones/unidad
	$effect(() => {
		if (hasDims) form.volume = Math.round(volumeM3 * 1000) / 1000;
	});

	// Ciudad y puerto/aeropuerto dependen del país (catálogos dependientes, como estado←país)
	$effect(() => {
		if (form.origin_country) {
			void crmCatalogs.ensure('ciudad', form.origin_country);
			void crmCatalogs.ensure('puerto', form.origin_country);
			void crmCatalogs.ensure('aeropuerto', form.origin_country);
		}
	});
	$effect(() => {
		if (form.destination_country) {
			void crmCatalogs.ensure('ciudad', form.destination_country);
			void crmCatalogs.ensure('puerto', form.destination_country);
			void crmCatalogs.ensure('aeropuerto', form.destination_country);
		}
	});
	// Campo "Puerto/Aeropuerto": une puertos + aeropuertos del país
	function portOptions(country: string | null | undefined) {
		return [
			...crmCatalogs.options('puerto', country ?? undefined),
			...crmCatalogs.options('aeropuerto', country ?? undefined)
		];
	}

	// Agente en destino: solo proveedores clasificados como corresponsal/aduanal (fallback: todos)
	const destinationAgents = $derived(
		suppliers.filter((s) => (s.classifications ?? []).some((c) => c === 'agente_corresponsal' || c === 'agente_aduanal'))
	);
	const agentList = $derived(destinationAgents.length ? destinationAgents : suppliers);

	// Contactos del cliente seleccionado (o todos si no hay cliente)
	const clientContacts = $derived(
		form.account_id ? contacts.filter((c) => c.account_id === form.account_id) : contacts
	);

	function contactName(c: Contact): string {
		return [c.first_name, c.last_name].filter(Boolean).join(' ');
	}

	// Costo estimado por servicio adicional (se traspasa a la cotización)
	function serviceCost(code: string): number | undefined {
		return form.additional_service_costs?.[code];
	}
	function setServiceCost(code: string, value: string) {
		const map = { ...(form.additional_service_costs ?? {}) };
		const n = value === '' ? NaN : Number(value);
		if (Number.isNaN(n)) delete map[code];
		else map[code] = n;
		form.additional_service_costs = map;
	}

	onMount(() => {
		void crmCatalogs.preload([
			'pais', 'moneda', 'prioridad', 'tipo_mercancia', 'unidad_medida',
			'tipo_embalaje', 'servicio_adicional', 'forma_pago', 'tipo_equipo',
			'puerto', 'aeropuerto', 'incoterm', 'medio_transporte'
		]);
		if (!form.additional_services) form.additional_services = [];
		if (!form.additional_service_costs) form.additional_service_costs = {};
	});
</script>

{#if tab === 'datos'}
	<div class="grid gap-4 sm:grid-cols-2">
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Folio</span><input class="{inputCls} bg-muted/40" bind:value={form.reference} readonly placeholder="Se asigna automáticamente al guardar (ej. S2026-08-001-E)" /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tipo de operación *</span><select class={inputCls} bind:value={form.operation_type}>{#each OPERATION_TYPES as o (o.value)}<option value={o.value}>{o.label}</option>{/each}</select></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Cliente</span><select class={inputCls} bind:value={form.account_id}><option value={undefined}>—</option>{#each accounts as a (a.id)}<option value={a.id}>{a.name}</option>{/each}</select></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Contacto</span><select class={inputCls} bind:value={form.contact_id}><option value={undefined}>—</option>{#each clientContacts as c (c.id)}<option value={c.id}>{contactName(c)}</option>{/each}</select></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Fecha de la solicitud</span><input type="date" class={inputCls} bind:value={form.request_date} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Prioridad</span><select class={inputCls} bind:value={form.priority}><option value={undefined}>—</option>{#each (crmCatalogs.options('prioridad').length ? crmCatalogs.options('prioridad') : PRIORITIES) as p (p.value)}<option value={p.value}>{p.label}</option>{/each}</select></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Moneda</span><select class={inputCls} bind:value={form.currency}><option value={undefined}>—</option>{#each crmCatalogs.options('moneda') as m (m.value)}<option value={m.value}>{m.value} — {m.label}</option>{/each}</select></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Ejecutivo (responsable)</span><input class={inputCls} bind:value={form.owner_user_id} placeholder="Usuario responsable" /></label>
		{#if form.status}
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Estatus</span><select class={inputCls} bind:value={form.status}>{#each SR_STATUS as s (s.value)}<option value={s.value}>{s.label}</option>{/each}</select></label>
		{/if}
	</div>
{:else if tab === 'ruta'}
	<div class="grid gap-4 sm:grid-cols-2">
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tipo de transporte</span><select class={inputCls} bind:value={form.transport_mode}><option value={undefined}>—</option>{#each (crmCatalogs.options('medio_transporte').length ? crmCatalogs.options('medio_transporte') : TRANSPORT_MODES) as m (m.value)}<option value={m.value}>{m.label}</option>{/each}</select></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tipo de servicio</span><select class={inputCls} bind:value={form.service_type}><option value={undefined}>—</option>{#each SERVICE_TYPES as s (s.value)}<option value={s.value}>{s.label}</option>{/each}</select></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Incoterm</span><select class={inputCls} bind:value={form.incoterm}><option value={undefined}>—</option>{#each crmCatalogs.options('incoterm') as i (i.value)}<option value={i.value}>{i.label}</option>{/each}</select></label>
		{#if showModalidad}
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Modalidad de carga</span><select class={inputCls} bind:value={form.load_type}><option value={undefined}>—</option>{#each modalidadOptions as l (l.value)}<option value={l.value}>{l.label}</option>{/each}</select></label>
		{/if}

		<p class="mt-1 text-xs font-semibold uppercase text-muted-foreground sm:col-span-2">Origen</p>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">País de origen</span><select class={inputCls} bind:value={form.origin_country}><option value={undefined}>—</option>{#each crmCatalogs.options('pais') as p (p.value)}<option value={p.value}>{p.label}</option>{/each}</select></label>
		{#if crmCatalogs.options('ciudad', form.origin_country ?? undefined).length}
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Ciudad de origen</span><select class={inputCls} bind:value={form.origin_city}><option value={undefined}>—</option>{#each crmCatalogs.options('ciudad', form.origin_country ?? undefined) as c (c.value)}<option value={c.value}>{c.label}</option>{/each}</select></label>
		{:else}
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Ciudad de origen</span><input class={inputCls} bind:value={form.origin_city} /></label>
		{/if}
		{#if portOptions(form.origin_country).length}
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Puerto/Aeropuerto de origen</span><select class={inputCls} bind:value={form.origin_port}><option value={undefined}>—</option>{#each portOptions(form.origin_country) as p (p.value)}<option value={p.value}>{p.label}</option>{/each}</select></label>
		{:else}
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Puerto/Aeropuerto de origen</span><input class={inputCls} bind:value={form.origin_port} /></label>
		{/if}
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Lugar de recolección</span><input class={inputCls} bind:value={form.pickup_location} /></label>

		<p class="mt-1 text-xs font-semibold uppercase text-muted-foreground sm:col-span-2">Destino</p>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">País de destino</span><select class={inputCls} bind:value={form.destination_country}><option value={undefined}>—</option>{#each crmCatalogs.options('pais') as p (p.value)}<option value={p.value}>{p.label}</option>{/each}</select></label>
		{#if crmCatalogs.options('ciudad', form.destination_country ?? undefined).length}
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Ciudad de destino</span><select class={inputCls} bind:value={form.destination_city}><option value={undefined}>—</option>{#each crmCatalogs.options('ciudad', form.destination_country ?? undefined) as c (c.value)}<option value={c.value}>{c.label}</option>{/each}</select></label>
		{:else}
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Ciudad de destino</span><input class={inputCls} bind:value={form.destination_city} /></label>
		{/if}
		{#if portOptions(form.destination_country).length}
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Puerto/Aeropuerto de destino</span><select class={inputCls} bind:value={form.destination_port}><option value={undefined}>—</option>{#each portOptions(form.destination_country) as p (p.value)}<option value={p.value}>{p.label}</option>{/each}</select></label>
		{:else}
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Puerto/Aeropuerto de destino</span><input class={inputCls} bind:value={form.destination_port} /></label>
		{/if}
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Lugar de entrega</span><input class={inputCls} bind:value={form.delivery_location} /></label>

		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Fecha estimada de embarque</span><input type="date" class={inputCls} bind:value={form.estimated_shipment_date} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Fecha requerida</span><input type="date" class={inputCls} bind:value={form.required_date} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Agente en destino</span><select class={inputCls} bind:value={form.destination_agent_id}><option value={undefined}>—</option>{#each agentList as s (s.id)}<option value={s.id}>{s.name}</option>{/each}</select></label>
	</div>
{:else if tab === 'mercancia'}
	<div class="grid gap-4 sm:grid-cols-2">
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tipo de mercancía</span><select class={inputCls} bind:value={form.cargo_type}><option value={undefined}>—</option>{#each crmCatalogs.options('tipo_mercancia') as t (t.value)}<option value={t.value}>{t.label}</option>{/each}</select></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Fracción arancelaria (HS)</span><input class="font-mono {inputCls}" maxlength="20" bind:value={form.hs_code} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">País de origen de la mercancía</span><select class={inputCls} bind:value={form.goods_origin_country}><option value={undefined}>—</option>{#each crmCatalogs.options('pais') as p (p.value)}<option value={p.value}>{p.label}</option>{/each}</select></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Valor de la mercancía</span><div class="flex items-center gap-1"><input type="number" min="0" step="0.01" class="{inputCls} w-full" bind:value={form.cargo_value} /><span class="text-xs text-muted-foreground">{form.currency ?? 'moneda'}</span></div></label>
		<label class="flex flex-col gap-1 text-sm sm:col-span-2"><span class="font-medium">Descripción de la mercancía</span><textarea rows="2" class={inputCls} bind:value={form.commodity}></textarea></label>
		<div class="flex flex-wrap gap-5 sm:col-span-2">
			<label class="flex items-center gap-2 text-sm"><input type="checkbox" class="h-4 w-4 rounded border" bind:checked={form.insurance_required} /><span>Requiere seguro</span></label>
			<label class="flex items-center gap-2 text-sm"><input type="checkbox" class="h-4 w-4 rounded border" bind:checked={form.hazardous_imo} /><span>Mercancía peligrosa (IMO)</span></label>
			<label class="flex items-center gap-2 text-sm"><input type="checkbox" class="h-4 w-4 rounded border" bind:checked={form.refrigerated} /><span>Refrigerada</span></label>
			<label class="flex items-center gap-2 text-sm"><input type="checkbox" class="h-4 w-4 rounded border" bind:checked={form.stackable} /><span>Estibable</span></label>
		</div>
	</div>
{:else if tab === 'dimensiones'}
	<div class="grid gap-4 sm:grid-cols-3">
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Piezas</span><input type="number" min="0" class={inputCls} bind:value={form.pieces_count} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Cajas</span><input type="number" min="0" class={inputCls} bind:value={form.boxes_count} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Pallets</span><input type="number" min="0" class={inputCls} bind:value={form.pallets_count} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Peso bruto (kg)</span><input type="number" min="0" step="0.001" class={inputCls} bind:value={form.weight} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Peso neto (kg)</span><input type="number" min="0" step="0.001" class={inputCls} bind:value={form.net_weight} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Volumen (m³)</span><input type="number" min="0" step="0.001" class={inputCls} bind:value={form.volume} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Largo</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={form.length_cm} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Ancho</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={form.width_cm} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Alto</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={form.height_cm} /></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Unidad de medida</span><select class={inputCls} bind:value={form.measurement_unit}><option value={undefined}>—</option>{#each crmCatalogs.options('unidad_medida') as u (u.value)}<option value={u.value}>{u.label}</option>{/each}</select></label>
	</div>
	{#if isFcl}
		<div class="mt-5 grid gap-4 rounded-md border p-4 sm:grid-cols-2">
			<p class="text-sm font-semibold sm:col-span-2">FCL — Contenedor completo</p>
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tipo de contenedor / equipo</span>
				{#if crmCatalogs.options('tipo_equipo').length}
					<select class={inputCls} bind:value={form.container_equipment}><option value={undefined}>—</option>{#each crmCatalogs.options('tipo_equipo') as e (e.value)}<option value={e.value}>{e.label}</option>{/each}</select>
				{:else}
					<input class={inputCls} bind:value={form.container_equipment} placeholder="40'HC, 20'DV…" />
				{/if}
			</label>
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Cantidad de contenedores</span><input type="number" min="0" class={inputCls} bind:value={form.container_count} /></label>
		</div>
	{/if}
	{#if isLcl}
		<div class="mt-4 grid gap-4 rounded-md border p-4 sm:grid-cols-2">
			<p class="text-sm font-semibold sm:col-span-2">LCL — Carga consolidada</p>
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tipo de embalaje</span><select class={inputCls} bind:value={form.packaging_type}><option value={undefined}>—</option>{#each crmCatalogs.options('tipo_embalaje') as e (e.value)}<option value={e.value}>{e.label}</option>{/each}</select></label>
			<label class="flex items-center gap-2 pt-6 text-sm"><input type="checkbox" class="h-4 w-4 rounded border" bind:checked={form.oversized} /><span>Sobredimensionada</span></label>
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Peso por pallet (kg)</span><input type="number" min="0" step="0.001" class={inputCls} bind:value={form.weight_per_pallet} /></label>
			<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Volumen por pallet (m³)</span><input type="number" min="0" step="0.001" class={inputCls} bind:value={form.volume_per_pallet} /></label>
		</div>
	{/if}
	{#if isAir}
		<div class="mt-4 grid gap-3 rounded-md border p-4 sm:grid-cols-2">
			<p class="text-sm font-semibold sm:col-span-2">Aéreo — Peso / Volumen (P/Vol)</p>
			<p class="text-xs text-muted-foreground sm:col-span-2">P/Vol = (Largo × Ancho × Alto en cm) × cantidad de bultos ÷ 6000 (factor internacional). Se cobra el mayor entre el peso bruto y el P/Vol. Captura Largo/Ancho/Alto y piezas/pallets arriba; el resultado se recalcula solo.</p>
			<div class="rounded-md bg-muted/40 p-3 text-sm sm:col-span-2">
				<div class="flex justify-between"><span class="text-muted-foreground">Cantidad de bultos</span><span class="font-medium">{airQty}</span></div>
				<div class="flex justify-between"><span class="text-muted-foreground">Peso volumétrico (P/Vol)</span><span class="font-medium">{airVolumetric.toFixed(2)} kg</span></div>
				<div class="flex justify-between"><span class="text-muted-foreground">Peso bruto</span><span class="font-medium">{(Number(form.weight) || 0).toFixed(2)} kg</span></div>
				<div class="mt-1 flex justify-between border-t pt-1"><span class="font-medium">Peso a cobrar (P/Vol)</span><span class="font-semibold">{airChargeable.toFixed(2)} kg</span></div>
			</div>
		</div>
	{/if}
{:else if tab === 'servicios'}
	<p class="mb-1 text-sm font-medium">Servicios adicionales</p>
	<p class="mb-3 text-xs text-muted-foreground">Marca los servicios requeridos e indica su costo estimado (opcional). Al cotizar, cada servicio marcado se agrega como concepto de la cotización con ese costo de partida.</p>
	<div class="space-y-2">
		{#each crmCatalogs.options('servicio_adicional') as s (s.value)}
			{@const checked = (form.additional_services ?? []).includes(s.value)}
			<div class="flex flex-wrap items-center gap-3">
				<label class="flex w-60 items-center gap-2 text-sm"><input type="checkbox" class="h-4 w-4 rounded border" value={s.value} bind:group={form.additional_services} /><span>{s.label}</span></label>
				{#if checked}
					<div class="flex items-center gap-1">
						<input type="number" min="0" step="0.01" class="{inputCls} w-40" placeholder="Costo estimado" value={serviceCost(s.value) ?? ''} oninput={(e) => setServiceCost(s.value, e.currentTarget.value)} />
						<span class="text-xs text-muted-foreground">{form.currency ?? ''}</span>
					</div>
				{/if}
			</div>
		{/each}
	</div>
	<label class="mt-5 flex max-w-md flex-col gap-1 text-sm"><span class="font-medium">Forma de pago</span><select class={inputCls} bind:value={form.payment_method}><option value={undefined}>—</option>{#each crmCatalogs.options('forma_pago') as f (f.value)}<option value={f.value}>{f.value} — {f.label}</option>{/each}</select></label>
{:else if tab === 'notas'}
	<div class="grid gap-4 sm:grid-cols-2">
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Notas del cliente</span><textarea rows="4" class={inputCls} bind:value={form.client_notes}></textarea></label>
		<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Notas internas</span><textarea rows="4" class={inputCls} bind:value={form.internal_notes}></textarea></label>
		<label class="flex flex-col gap-1 text-sm sm:col-span-2"><span class="font-medium">Otros requerimientos</span><textarea rows="3" class={inputCls} bind:value={form.requirements}></textarea></label>
	</div>
{/if}
