<script lang="ts">
	import { onMount } from 'svelte';
	import { Calculator, Plus } from '@lucide/svelte';
	import { page } from '$app/state';
	import { goto } from '$app/navigation';
	import * as Card from '$lib/components/ui/card';
	import * as Table from '$lib/components/ui/table';
	import { Button } from '$lib/components/ui/button';
	import { companyStore } from '$lib/stores/company.svelte';
	import { rateSheetsAPI, type CostOption, type RateMode } from '$lib/api/crm/rates';
	import { serviceRequestsAPI, quoteItemsAPI } from '$lib/api/crm';
	import { crmCatalogs } from '$lib/stores/crm-catalogs.svelte';
	import { formatMoney } from '$lib/components/crm/format';
	import { toast } from 'svelte-sonner';

	const companyId = $derived(companyStore.activeCompany?.id ?? null);
	// Vinculación: ?service_request_id= (prellenar) y ?quote_id= (enviar resultado a concepto)
	const srId = $derived(Number(page.url.searchParams.get('service_request_id')) || null);
	const quoteId = $derived(Number(page.url.searchParams.get('quote_id')) || null);

	// transport_mode + load_type de la solicitud → modo del tarifario
	function transportModeToRateMode(transport: string | null, load: string | null): RateMode {
		if (transport === 'aereo') return 'aereo';
		if (transport === 'terrestre') return 'terrestre';
		if (transport === 'maritimo') return load === 'LCL' ? 'maritimo_lcl' : 'maritimo_fcl';
		return 'aereo';
	}
	const inputCls = 'rounded-md border bg-transparent px-3 py-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring';

	let f = $state({
		mode: 'aereo' as RateMode, origin: '', destination: '', on_date: '',
		gross_weight_kg: null as number | null, volume_m3: null as number | null,
		length_cm: null as number | null, width_cm: null as number | null, height_cm: null as number | null,
		equipment_type: '', quantity: 1, dangerous: false
	});
	let options = $state<CostOption[]>([]);
	let calculated = $state(false);
	let working = $state(false);
	// Orígenes/destinos alineados a las rutas de los tarifarios activos del modo
	let locs = $state<{ origins: string[]; destinations: string[] }>({ origins: [], destinations: [] });

	$effect(() => {
		const cid = companyId;
		const mode = f.mode;
		if (!cid) return;
		void (async () => {
			try { locs = await rateSheetsAPI.locations(cid, mode); }
			catch { locs = { origins: [], destinations: [] }; }
		})();
	});

	const isFcl = $derived(f.mode === 'maritimo_fcl' || f.mode === 'terrestre');
	const isAir = $derived(f.mode === 'aereo');

	// P/Vol aéreo en vivo: (L×A×H cm × cantidad) / 6000; a cobrar = max(bruto, P/Vol)
	const airVolumetric = $derived(
		Number(f.length_cm) > 0 && Number(f.width_cm) > 0 && Number(f.height_cm) > 0
			? (Number(f.length_cm) * Number(f.width_cm) * Number(f.height_cm) * (Number(f.quantity) || 1)) / 6000
			: 0
	);
	const airChargeable = $derived(Math.max(Number(f.gross_weight_kg) || 0, airVolumetric));

	onMount(() => void crmCatalogs.preload(['modo_tarifario', 'tipo_equipo']));

	// Prellenar desde la solicitud vinculada (si viene ?service_request_id=)
	$effect(() => {
		const cid = companyId;
		const id = srId;
		if (!cid || !id) return;
		void (async () => {
			try {
				const sr = await serviceRequestsAPI.get(id, cid);
				f = {
					...f,
					mode: transportModeToRateMode(sr.transport_mode, sr.load_type),
					origin: sr.origin_port || sr.origin || '',
					destination: sr.destination_port || sr.destination || '',
					on_date: sr.estimated_shipment_date || sr.required_date || '',
					gross_weight_kg: sr.weight ?? null,
					volume_m3: sr.volume ?? null,
					length_cm: sr.length_cm ?? null,
					width_cm: sr.width_cm ?? null,
					height_cm: sr.height_cm ?? null,
					equipment_type: sr.container_equipment || '',
					quantity: sr.container_count || sr.pallets_count || sr.pieces_count || 1,
					dangerous: !!sr.hazardous_imo
				};
			} catch (e) {
				toast.error(e instanceof Error ? e.message : 'No se pudo cargar la solicitud');
			}
		})();
	});

	// Enviar una opción del cotizador como concepto(s) de la cotización vinculada
	async function addToQuote(o: CostOption) {
		if (!companyId || !quoteId) return;
		working = true;
		try {
			// Línea base (flete) + una línea por cada cargo adicional
			await quoteItemsAPI.create({
				quote_id: quoteId, concept: 'flete_internacional',
				description: `${o.rate_sheet_name}${o.detail ? ' — ' + o.detail : ''}`,
				supplier_id: o.supplier_id ?? undefined, quantity: 1,
				unit_cost: o.base_cost, unit_sale: o.base_cost, currency: o.currency ?? undefined
			}, companyId);
			for (const c of o.charges) {
				await quoteItemsAPI.create({
					quote_id: quoteId, concept: 'otros', description: c.concept,
					quantity: 1, unit_cost: c.amount, unit_sale: c.amount, currency: o.currency ?? undefined
				}, companyId);
			}
			toast.success('Concepto(s) agregado(s) a la cotización');
			await goto(`/dashboard/crm/cotizaciones/${quoteId}`);
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo agregar a la cotización');
		} finally {
			working = false;
		}
	}

	async function calc() {
		if (!companyId) return;
		if (!f.destination.trim()) { toast.error('Indica el destino'); return; }
		working = true; calculated = false;
		try {
			const res = await rateSheetsAPI.quote({
				mode: f.mode, origin: f.origin || null, destination: f.destination || null,
				on_date: f.on_date || null, gross_weight_kg: f.gross_weight_kg, volume_m3: f.volume_m3,
				length_cm: f.length_cm, width_cm: f.width_cm, height_cm: f.height_cm,
				equipment_type: f.equipment_type || null, quantity: f.quantity || 1, dangerous: f.dangerous
			}, companyId);
			options = res.options; calculated = true;
		} catch (e) { toast.error(e instanceof Error ? e.message : 'No se pudo calcular'); }
		finally { working = false; }
	}
	const money = (v: number, c: string | null) => formatMoney(v, c ?? 'USD');
</script>

<div class="space-y-6">
	<div>
		<h1 class="flex items-center gap-2 text-2xl font-bold tracking-tight"><Calculator class="h-6 w-6" /> Cotizador</h1>
		<p class="mt-1 text-sm text-muted-foreground">Calcula el costo por proveedor a partir de los tarifarios vigentes.</p>
	</div>

	{#if !companyId}
		<Card.Root><Card.Content class="pt-6 text-sm text-muted-foreground">Selecciona una compañía activa.</Card.Content></Card.Root>
	{:else}
		<Card.Root>
			<Card.Header><Card.Title class="text-base">Datos de la carga</Card.Title></Card.Header>
			<Card.Content>
				<div class="grid gap-4 sm:grid-cols-3">
					<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Modo *</span>
						<select class={inputCls} bind:value={f.mode}>{#each crmCatalogs.options('modo_tarifario') 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">Origen</span>
						{#if locs.origins.length}
							<select class={inputCls} bind:value={f.origin}><option value="">—</option>{#each locs.origins as o (o)}<option value={o}>{o}</option>{/each}</select>
						{:else}
							<input class={inputCls} bind:value={f.origin} placeholder="NLU / MXZLO" />
						{/if}
					</label>
					<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Destino *</span>
						{#if locs.destinations.length}
							<select class={inputCls} bind:value={f.destination}><option value="">—</option>{#each locs.destinations as d (d)}<option value={d}>{d}</option>{/each}</select>
						{:else}
							<input class={inputCls} bind:value={f.destination} placeholder="FRA / CNSHA" />
						{/if}
					</label>

					{#if isFcl}
						<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tipo de equipo</span>
							<select class={inputCls} bind:value={f.equipment_type}><option value="">—</option>{#each crmCatalogs.options('tipo_equipo') 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">Cantidad</span><input type="number" min="1" class={inputCls} bind:value={f.quantity} /></label>
					{:else}
						<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Peso bruto (kg)</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={f.gross_weight_kg} /></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={f.volume_m3} /></label>
						{#if isAir}
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Largo (cm)</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={f.length_cm} /></label>
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Ancho (cm)</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={f.width_cm} /></label>
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Alto (cm)</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={f.height_cm} /></label>
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Cantidad de bultos</span><input type="number" min="1" class={inputCls} bind:value={f.quantity} /></label>
						{/if}
					{/if}

					<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Fecha embarque</span><input type="date" class={inputCls} bind:value={f.on_date} /></label>
					<label class="flex items-center gap-2 pt-6 text-sm"><input type="checkbox" class="h-4 w-4 rounded border" bind:checked={f.dangerous} /><span>Mercancía peligrosa (DGR)</span></label>
				</div>
				{#if isAir && airVolumetric > 0}
					<div class="mt-3 flex flex-wrap gap-6 rounded-md bg-muted/40 p-3 text-sm">
						<span>P/Vol (volumétrico): <b>{airVolumetric.toFixed(2)}</b></span>
						<span>Peso bruto: <b>{(Number(f.gross_weight_kg) || 0).toFixed(2)} kg</b></span>
						<span>Peso a cobrar: <b>{airChargeable.toFixed(2)} kg</b></span>
						<span class="text-xs text-muted-foreground">P/Vol = (L×A×H) × bultos ÷ 6000</span>
					</div>
				{/if}
				<div class="mt-4 flex justify-end"><Button onclick={calc} disabled={working}>{working ? 'Calculando…' : 'Calcular costo'}</Button></div>
			</Card.Content>
		</Card.Root>

		{#if calculated}
			<Card.Root>
				<Card.Header><Card.Title class="text-base">Opciones ({options.length})</Card.Title>
					<Card.Description>Ordenadas por costo total. El precio de venta se define en la cotización (costo + margen).</Card.Description>
				</Card.Header>
				<Card.Content>
					{#if options.length === 0}
						<p class="text-sm text-muted-foreground">No hay tarifas vigentes para esa ruta/modo. Verifica que exista un tarifario <b>activo</b> con esa ruta.</p>
					{:else}
						<div class="overflow-x-auto">
							<Table.Root>
								<Table.Header><Table.Row><Table.Head>Tarifario</Table.Head><Table.Head>Base</Table.Head><Table.Head>Cargos</Table.Head><Table.Head>Total</Table.Head><Table.Head>Detalle</Table.Head><Table.Head>Tránsito</Table.Head>{#if quoteId}<Table.Head></Table.Head>{/if}</Table.Row></Table.Header>
								<Table.Body>
									{#each options as o, i (o.rate_sheet_id + '-' + i)}
										<Table.Row class={i === 0 ? 'bg-emerald-50/60 dark:bg-emerald-950/20' : ''}>
											<Table.Cell class="font-medium">{o.rate_sheet_name}</Table.Cell>
											<Table.Cell>{money(o.base_cost, o.currency)}</Table.Cell>
											<Table.Cell class="text-xs">{o.charges.length ? o.charges.map((c) => `${c.concept}: ${money(c.amount, o.currency)}`).join(', ') : '—'}</Table.Cell>
											<Table.Cell class="font-semibold">{money(o.total_cost, o.currency)}</Table.Cell>
											<Table.Cell class="text-xs text-muted-foreground">{o.detail ?? '—'}</Table.Cell>
											<Table.Cell>{o.transit_days ?? '—'}</Table.Cell>
											{#if quoteId}<Table.Cell class="text-right"><Button size="sm" variant="outline" onclick={() => addToQuote(o)} disabled={working}><Plus class="mr-1 h-4 w-4" /> Agregar</Button></Table.Cell>{/if}
										</Table.Row>
									{/each}
								</Table.Body>
							</Table.Root>
						</div>
					{/if}
				</Card.Content>
			</Card.Root>
		{/if}
	{/if}
</div>
