<script lang="ts">
	import { onMount } from 'svelte';
	import { ArrowLeft, FileSpreadsheet, Trash2, CheckCircle2, Plus } from '@lucide/svelte';
	import { page } from '$app/state';
	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 RateSheet, type RateLane, type RateCharge } from '$lib/api/crm/rates';
	import { crmCatalogs } from '$lib/stores/crm-catalogs.svelte';
	import { formatDate } from '$lib/components/crm/format';
	import { toast } from 'svelte-sonner';

	const sheetId = $derived(Number(page.params.id));
	const companyId = $derived(companyStore.activeCompany?.id ?? null);
	const inputCls = 'rounded-md border bg-transparent px-2 py-1 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring';

	let sheet = $state<RateSheet | null>(null);
	let lanes = $state<RateLane[]>([]);
	let charges = $state<RateCharge[]>([]);
	let loading = $state(false);

	const isAir = $derived(sheet?.mode === 'aereo');
	const isLcl = $derived(sheet?.mode === 'maritimo_lcl');
	const isFcl = $derived(sheet?.mode === 'maritimo_fcl');
	const usesBreaks = $derived(isAir || isLcl);
	const rateUnit = $derived(sheet?.mode === 'aereo' ? 'per_kg' : sheet?.mode === 'maritimo_lcl' ? 'per_wm' : sheet?.mode === 'maritimo_fcl' ? 'per_container' : 'flat');

	// alta de ruta
	let showLane = $state(false);
	let lf = $state({ origin: '', destination: '', region: '', equipment_type: '', min_charge: null as number | null, flat_rate: null as number | null, transit_days: null as number | null, notes: '' });
	let brks = $state<{ from_qty: number | null; rate: number | null }[]>([{ from_qty: null, rate: null }]);
	// alta de cargo
	let cf = $state({ concept: '', charge_type: 'fijo', value: null as number | null, condition: '' });
	let working = $state(false);

	onMount(() => void crmCatalogs.preload(['modo_tarifario', 'tipo_equipo', 'concepto_cargo']));
	$effect(() => { const cid = companyId, id = sheetId; if (cid && id) void load(cid, id); });

	async function load(cid: number, id: number) {
		loading = true;
		try {
			sheet = await rateSheetsAPI.get(id, cid);
			[lanes, charges] = await Promise.all([rateSheetsAPI.lanes(id, cid), rateSheetsAPI.charges(id, cid)]);
		} catch (e) { toast.error(e instanceof Error ? e.message : 'No se pudo cargar el tarifario'); }
		finally { loading = false; }
	}
	async function setStatus(status: string) {
		if (!companyId || !sheet) return;
		try { sheet = await rateSheetsAPI.update(sheet.id, { status }, companyId); toast.success(`Tarifario ${status}`); }
		catch (e) { toast.error(e instanceof Error ? e.message : 'No se pudo actualizar'); }
	}
	async function delLane(l: RateLane) {
		if (!companyId || !sheet || !confirm('¿Eliminar esta ruta?')) return;
		try { await rateSheetsAPI.removeLane(sheet.id, l.id, companyId); await load(companyId, sheet.id); }
		catch (e) { toast.error(e instanceof Error ? e.message : 'No se pudo eliminar'); }
	}

	function openLane() {
		lf = { origin: sheet?.default_origin ?? '', destination: '', region: '', equipment_type: '', min_charge: null, flat_rate: null, transit_days: null, notes: '' };
		brks = [{ from_qty: null, rate: null }];
		showLane = true;
	}
	async function saveLane() {
		if (!companyId || !sheet) return;
		if (!lf.destination.trim()) { toast.error('Indica el destino'); return; }
		const breaks = usesBreaks
			? brks.filter((b) => b.rate != null).map((b) => ({ from_qty: b.from_qty ?? 0, rate: b.rate as number }))
			: [];
		working = true;
		try {
			await rateSheetsAPI.addLane(sheet.id, {
				origin: lf.origin || null, destination: lf.destination, region: lf.region || null,
				equipment_type: isFcl ? (lf.equipment_type || null) : null, rate_unit: rateUnit,
				min_charge: usesBreaks ? lf.min_charge : null,
				flat_rate: usesBreaks ? null : lf.flat_rate,
				transit_days: lf.transit_days, notes: lf.notes || null, breaks
			} as any, companyId);
			toast.success('Ruta agregada');
			showLane = false;
			await load(companyId, sheet.id);
		} catch (e) { toast.error(e instanceof Error ? e.message : 'No se pudo guardar la ruta'); }
		finally { working = false; }
	}

	async function addCharge() {
		if (!companyId || !sheet) return;
		if (!cf.concept) { toast.error('Elige el concepto del cargo'); return; }
		working = true;
		try {
			await rateSheetsAPI.addCharge(sheet.id, { concept: cf.concept, charge_type: cf.charge_type, value: cf.value, condition: cf.condition || null }, companyId);
			toast.success('Cargo agregado');
			cf = { concept: '', charge_type: 'fijo', value: null, condition: '' };
			charges = await rateSheetsAPI.charges(sheet.id, companyId);
		} catch (e) { toast.error(e instanceof Error ? e.message : 'No se pudo agregar el cargo'); }
		finally { working = false; }
	}
	async function delCharge(c: RateCharge) {
		if (!companyId || !sheet) return;
		try { await rateSheetsAPI.removeCharge(sheet.id, c.id, companyId); charges = await rateSheetsAPI.charges(sheet.id, companyId); }
		catch (e) { toast.error(e instanceof Error ? e.message : 'No se pudo eliminar'); }
	}

	const eq = (c: string | null) => c ? crmCatalogs.label('tipo_equipo', c) : '—';
	const conceptLabel = (c: string) => crmCatalogs.label('concepto_cargo', c);
	const breaksTxt = (l: RateLane) => (l.breaks ?? []).map((b) => `${b.from_qty}: ${b.rate}`).join('  ·  ') || '—';
	const CHARGE_TYPES = [
		{ v: 'fijo', l: 'Fijo' }, { v: 'por_kg', l: 'Por kg' }, { v: 'por_guia', l: 'Por guía' },
		{ v: 'por_contenedor', l: 'Por contenedor' }, { v: 'porcentaje', l: '% sobre tarifa' }
	];
	const chargeTypeLabel = (t: string) => CHARGE_TYPES.find((x) => x.v === t)?.l ?? t;
</script>

<div class="space-y-6">
	<Button variant="ghost" size="sm" href="/dashboard/crm/tarifarios"><ArrowLeft class="mr-1 h-4 w-4" /> Tarifarios</Button>
	{#if loading && !sheet}
		<p class="text-sm text-muted-foreground">Cargando…</p>
	{:else if sheet}
		<div class="flex flex-wrap items-start justify-between gap-3">
			<div>
				<h1 class="flex items-center gap-2 text-2xl font-bold tracking-tight"><FileSpreadsheet class="h-6 w-6" /> {sheet.name}</h1>
				<p class="mt-1 text-sm text-muted-foreground">
					{crmCatalogs.label('modo_tarifario', sheet.mode)} · {sheet.currency ?? '—'} · {lanes.length} rutas
					· vigencia {sheet.valid_from ? formatDate(sheet.valid_from) : '—'} → {sheet.valid_to ? formatDate(sheet.valid_to) : '—'}
					· estatus <b>{sheet.status}</b>
				</p>
			</div>
			<div class="flex gap-2">
				{#if sheet.status !== 'activo'}
					<Button size="sm" onclick={() => setStatus('activo')}><CheckCircle2 class="mr-1 h-4 w-4" /> Activar</Button>
				{:else}
					<Button size="sm" variant="outline" onclick={() => setStatus('vencido')}>Marcar vencido</Button>
				{/if}
			</div>
		</div>

		<Card.Root>
			<Card.Header class="flex flex-row items-center justify-between">
				<div><Card.Title class="text-base">Rutas ({lanes.length})</Card.Title>
					<Card.Description>El motor de cotización usa estas rutas cuando el tarifario está <b>activo</b> y vigente.</Card.Description>
				</div>
				<Button size="sm" variant="outline" onclick={openLane}><Plus class="mr-1 h-4 w-4" /> Agregar ruta</Button>
			</Card.Header>
			<Card.Content>
				{#if lanes.length === 0}
					<p class="text-sm text-muted-foreground">Sin rutas. Agrega una o importa por Excel.</p>
				{:else}
					<div class="overflow-x-auto">
						<Table.Root>
							<Table.Header><Table.Row><Table.Head>Región</Table.Head><Table.Head>Origen</Table.Head><Table.Head>Destino</Table.Head><Table.Head>Equipo</Table.Head><Table.Head>Mínimo</Table.Head><Table.Head>Tarifa / Quiebres</Table.Head><Table.Head>Tránsito</Table.Head><Table.Head></Table.Head></Table.Row></Table.Header>
							<Table.Body>
								{#each lanes as l (l.id)}
									<Table.Row>
										<Table.Cell class="text-xs">{l.region ?? '—'}</Table.Cell>
										<Table.Cell>{l.origin ?? sheet.default_origin ?? '—'}</Table.Cell>
										<Table.Cell class="font-medium">{l.destination ?? '—'}</Table.Cell>
										<Table.Cell class="text-xs">{eq(l.equipment_type)}</Table.Cell>
										<Table.Cell>{l.min_charge ?? '—'}</Table.Cell>
										<Table.Cell class="text-xs">{l.flat_rate != null ? l.flat_rate : breaksTxt(l)}</Table.Cell>
										<Table.Cell>{l.transit_days ?? '—'}</Table.Cell>
										<Table.Cell class="text-right"><Button variant="ghost" size="sm" onclick={() => delLane(l)} aria-label="Eliminar"><Trash2 class="h-4 w-4 text-destructive" /></Button></Table.Cell>
									</Table.Row>
								{/each}
							</Table.Body>
						</Table.Root>
					</div>
				{/if}
			</Card.Content>
		</Card.Root>

		<Card.Root>
			<Card.Header><Card.Title class="text-base">Cargos adicionales ({charges.length})</Card.Title>
				<Card.Description>Recargos que el motor suma a la tarifa base (combustible, DGR, THC, maniobras…).</Card.Description>
			</Card.Header>
			<Card.Content>
				<div class="mb-4 flex flex-wrap items-end gap-2">
					<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Concepto</span>
						<select class={inputCls} bind:value={cf.concept}><option value="">—</option>{#each crmCatalogs.options('concepto_cargo') as c (c.value)}<option value={c.value}>{c.label}</option>{/each}</select>
					</label>
					<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tipo</span>
						<select class={inputCls} bind:value={cf.charge_type}>{#each CHARGE_TYPES as t (t.v)}<option value={t.v}>{t.l}</option>{/each}</select>
					</label>
					<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Valor</span><input type="number" step="0.01" class="{inputCls} w-28" bind:value={cf.value} placeholder="monto o %" /></label>
					<label class="flex flex-1 flex-col gap-1 text-sm"><span class="font-medium">Condición</span><input class={inputCls} bind:value={cf.condition} placeholder="opcional (ej. solo DGR)" /></label>
					<Button size="sm" onclick={addCharge} disabled={working}><Plus class="mr-1 h-4 w-4" /> Agregar</Button>
				</div>
				{#if charges.length === 0}
					<p class="text-sm text-muted-foreground">Sin cargos adicionales.</p>
				{:else}
					<Table.Root>
						<Table.Header><Table.Row><Table.Head>Concepto</Table.Head><Table.Head>Tipo</Table.Head><Table.Head>Valor</Table.Head><Table.Head>Condición</Table.Head><Table.Head></Table.Head></Table.Row></Table.Header>
						<Table.Body>
							{#each charges as c (c.id)}
								<Table.Row>
									<Table.Cell class="font-medium">{conceptLabel(c.concept)}</Table.Cell>
									<Table.Cell class="text-xs">{chargeTypeLabel(c.charge_type)}</Table.Cell>
									<Table.Cell>{c.value ?? '—'}{c.charge_type === 'porcentaje' ? ' %' : ''}</Table.Cell>
									<Table.Cell class="text-xs text-muted-foreground">{c.condition ?? '—'}</Table.Cell>
									<Table.Cell class="text-right"><Button variant="ghost" size="sm" onclick={() => delCharge(c)} aria-label="Eliminar"><Trash2 class="h-4 w-4 text-destructive" /></Button></Table.Cell>
								</Table.Row>
							{/each}
						</Table.Body>
					</Table.Root>
				{/if}
			</Card.Content>
		</Card.Root>
	{/if}
</div>

{#if showLane && sheet}
	<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4" role="presentation" onclick={() => (showLane = false)}>
		<div class="max-h-[92vh] w-full max-w-xl overflow-y-auto rounded-lg border bg-card p-6 shadow-lg" role="dialog" aria-modal="true" tabindex="-1" onclick={(e) => e.stopPropagation()}>
			<h3 class="mb-4 text-base font-semibold">Nueva ruta</h3>
			<div class="grid gap-3 sm:grid-cols-3">
				<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Origen</span><input class={inputCls} bind:value={lf.origin} placeholder={sheet.default_origin ?? 'NLU'} /></label>
				<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Destino *</span><input class={inputCls} bind:value={lf.destination} placeholder="FRA / CNSHA" /></label>
				<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Región</span><input class={inputCls} bind:value={lf.region} /></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={lf.equipment_type}><option value="">—</option>{#each crmCatalogs.options('tipo_equipo') as t (t.value)}<option value={t.value}>{t.label}</option>{/each}</select>
					</label>
				{/if}
				{#if usesBreaks}
					<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Cargo mínimo</span><input type="number" step="0.01" class={inputCls} bind:value={lf.min_charge} /></label>
				{:else}
					<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tarifa</span><input type="number" step="0.01" class={inputCls} bind:value={lf.flat_rate} /></label>
				{/if}
				<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tránsito (días)</span><input type="number" class={inputCls} bind:value={lf.transit_days} /></label>
			</div>

			{#if usesBreaks}
				<div class="mt-4">
					<div class="mb-1 flex items-center justify-between"><span class="text-sm font-medium">Quiebres ({isAir ? 'kg' : 'W/M'} → tarifa)</span>
						<Button size="sm" variant="ghost" onclick={() => (brks = [...brks, { from_qty: null, rate: null }])}><Plus class="mr-1 h-4 w-4" /> Fila</Button>
					</div>
					{#each brks as b, i (i)}
						<div class="mb-1 flex items-center gap-2">
							<input type="number" step="0.001" class="{inputCls} w-32" bind:value={b.from_qty} placeholder="desde (100)" />
							<input type="number" step="0.0001" class="{inputCls} w-32" bind:value={b.rate} placeholder="tarifa (1.00)" />
							<button type="button" class="text-destructive" onclick={() => (brks = brks.filter((_, j) => j !== i))} aria-label="Quitar">×</button>
						</div>
					{/each}
				</div>
			{/if}
			<label class="mt-3 flex flex-col gap-1 text-sm"><span class="font-medium">Notas</span><input class={inputCls} bind:value={lf.notes} /></label>

			<div class="mt-5 flex justify-end gap-2 border-t pt-4">
				<Button variant="outline" onclick={() => (showLane = false)}>Cancelar</Button>
				<Button onclick={saveLane} disabled={working}>{working ? 'Guardando…' : 'Guardar ruta'}</Button>
			</div>
		</div>
	</div>
{/if}
