<script lang="ts">
	import { ArrowLeft, Receipt, Plus, Trash2, Send, Check, X, Ship, FileText, Mail, Calculator } 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 {
		quotesAPI, quoteItemsAPI, accountsAPI, serviceRequestsAPI, suppliersAPI,
		type Quote, type QuoteInput, type QuoteItem, type QuoteItemInput, type Account, type ServiceRequest, type Supplier
	} from '$lib/api/crm';
	import { shipmentsAPI } from '$lib/api/ops';
	import { QUOTE_STATUS, QUOTE_CONCEPTS, labelOf, formatMoney } from '$lib/components/crm/format';
	import { crmCatalogs } from '$lib/stores/crm-catalogs.svelte';
	import { toast } from 'svelte-sonner';

	const quoteId = $derived(Number(page.params.id));
	const companyId = $derived(companyStore.activeCompany?.id ?? null);

	let quote = $state<Quote | null>(null);
	let items = $state<QuoteItem[]>([]);
	let accounts = $state<Account[]>([]);
	let requests = $state<ServiceRequest[]>([]);
	let suppliers = $state<Supplier[]>([]);
	let form = $state<QuoteInput>({});
	let tab = $state('conceptos');
	let loading = $state(false);
	let saving = $state(false);
	let adding = $state(false);
	let busy = $state(false);
	let newItem = $state<QuoteItemInput>({ quote_id: 0, concept: 'flete_internacional', quantity: 1, unit_cost: 0, unit_sale: 0 });

	$effect(() => {
		const cid = companyId;
		const id = quoteId;
		if (!cid || !id) return;
		void load(cid, id);
	});

	async function load(cid: number, id: number) {
		loading = true;
		void crmCatalogs.preload(['moneda']);
		try {
			[quote, items, accounts, requests, suppliers] = await Promise.all([
				quotesAPI.get(id, cid),
				quotesAPI.items(id, cid),
				accountsAPI.list(cid),
				serviceRequestsAPI.list(cid),
				suppliersAPI.list(cid)
			]);
			form = { ...quote };
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo cargar la cotización');
		} finally {
			loading = false;
		}
	}

	async function reload() {
		if (companyId) {
			[quote, items] = await Promise.all([quotesAPI.get(quoteId, companyId), quotesAPI.items(quoteId, companyId)]);
			form = { ...quote };
		}
	}

	async function saveHeader() {
		if (!companyId || !quote) return;
		saving = true;
		try {
			quote = await quotesAPI.update(quote.id, form, companyId);
			form = { ...quote };
			toast.success('Cambios guardados');
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo guardar');
		} finally {
			saving = false;
		}
	}

	function startAdd() {
		newItem = { quote_id: quoteId, concept: 'flete_internacional', quantity: 1, unit_cost: 0, unit_sale: 0, currency: quote?.currency };
		adding = true;
	}

	async function saveItem() {
		if (!companyId) return;
		try {
			await quoteItemsAPI.create({ ...newItem, quote_id: quoteId }, companyId);
			toast.success('Concepto agregado');
			adding = false;
			await reload();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo agregar');
		}
	}

	async function removeItem(it: QuoteItem) {
		if (!companyId || !confirm('¿Eliminar concepto?')) return;
		await quoteItemsAPI.remove(it.id, companyId);
		await reload();
	}

	async function doAction(action: 'send' | 'accept' | 'reject') {
		if (!companyId || !quote) return;
		busy = true;
		try {
			quote = await quotesAPI[action](quote.id, companyId);
			form = { ...quote };
			toast.success('Cotización actualizada');
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo actualizar');
		} finally {
			busy = false;
		}
	}

	let showRelease = $state(false);
	let releaseDir = $state<'importacion' | 'exportacion'>('exportacion');

	function openRelease() {
		if (!quote) return;
		// Prefija la dirección desde la solicitud asociada (si la hay)
		const sr = requests.find((r) => r.id === quote?.service_request_id);
		releaseDir = (sr?.operation_type as 'importacion' | 'exportacion') ?? 'exportacion';
		showRelease = true;
	}

	async function confirmRelease() {
		if (!companyId || !quote) return;
		busy = true;
		try {
			const shipment = await shipmentsAPI.createFromQuote(quote.id, companyId, releaseDir);
			toast.success('Embarque creado');
			showRelease = false;
			await goto(`/dashboard/ops/embarques/${shipment.id}`);
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo liberar');
		} finally {
			busy = false;
		}
	}

	async function clone() {
		if (!companyId || !quote) return;
		busy = true;
		try {
			const nq = await quotesAPI.clone(quote.id, companyId);
			toast.success('Cotización clonada como borrador');
			await goto(`/dashboard/crm/cotizaciones/${nq.id}`);
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo clonar');
		} finally {
			busy = false;
		}
	}

	async function openPdf() {
		if (!companyId || !quote) return;
		busy = true;
		try {
			const blob = await quotesAPI.pdfBlob(quote.id, companyId);
			const url = URL.createObjectURL(blob);
			window.open(url, '_blank', 'noopener');
			setTimeout(() => URL.revokeObjectURL(url), 60000);
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo generar el PDF');
		} finally {
			busy = false;
		}
	}

	let showEmail = $state(false);
	let emailForm = $state({ to: '', subject: '', message: '' });
	function openEmail() {
		emailForm = {
			to: accounts.find((a) => a.id === quote?.account_id)?.email ?? '',
			subject: `Cotización ${quote?.reference ?? ''}`.trim(),
			message: 'Adjunto la cotización solicitada. Quedamos atentos a sus comentarios.'
		};
		showEmail = true;
	}
	async function sendEmail() {
		if (!companyId || !quote) return;
		if (!emailForm.to.trim()) { toast.error('Indica el correo destino'); return; }
		busy = true;
		try {
			const res = await quotesAPI.sendEmail(quote.id, companyId, {
				to: emailForm.to.trim(), subject: emailForm.subject || null, message: emailForm.message || null
			});
			toast.success(`Cotización enviada a ${res.sent_to}`);
			showEmail = false;
			await reload();
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo enviar el correo');
		} finally {
			busy = false;
		}
	}

	function supplierName(id: number | null | undefined): string {
		return suppliers.find((s) => s.id === id)?.name ?? '—';
	}

	const statusClass: Record<string, string> = {
		borrador: 'bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-400',
		enviada: 'bg-blue-100 text-blue-700 dark:bg-blue-950/40 dark:text-blue-400',
		aceptada: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-950/40 dark:text-emerald-400',
		rechazada: 'bg-red-100 text-red-700 dark:bg-red-950/40 dark:text-red-400'
	};
	const inputCls = 'rounded-md border bg-transparent px-3 py-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring';
</script>

<div class="space-y-6">
	<Button variant="ghost" size="sm" href="/dashboard/crm/cotizaciones"><ArrowLeft class="mr-1 h-4 w-4" /> Cotizaciones</Button>

	{#if loading && !quote}
		<p class="text-sm text-muted-foreground">Cargando…</p>
	{:else if quote}
		<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"><Receipt class="h-6 w-6" /> {quote.reference ?? `Cotización #${quote.id}`}</h1>
				<p class="mt-1 flex items-center gap-2 text-sm">
					<span class="inline-flex rounded-full px-2 py-0.5 text-xs font-medium {statusClass[quote.status] ?? ''}">{labelOf(QUOTE_STATUS, quote.status)}</span>
					{#if quote.case_id}<a class="inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 font-mono text-[11px] hover:underline" href={`/dashboard/crm/expedientes/${quote.case_id}`}>📁 Expediente</a>{/if}
				</p>
			</div>
			<div class="flex flex-wrap gap-2">
				<Button size="sm" variant="outline" href={`/dashboard/crm/cotizador?quote_id=${quote.id}${quote.service_request_id ? `&service_request_id=${quote.service_request_id}` : ''}`}><Calculator class="mr-1 h-4 w-4" /> Cotizador</Button>
				<Button size="sm" variant="outline" onclick={openPdf} disabled={busy}><FileText class="mr-1 h-4 w-4" /> Ver PDF</Button>
				<Button size="sm" variant="outline" onclick={openEmail} disabled={busy}><Mail class="mr-1 h-4 w-4" /> Enviar por correo</Button>
				{#if quote.status === 'borrador'}
					<Button size="sm" variant="outline" onclick={() => doAction('send')} disabled={busy}><Send class="mr-1 h-4 w-4" /> Marcar enviada</Button>
				{/if}
				{#if quote.status === 'enviada'}
					<Button size="sm" variant="outline" onclick={() => doAction('accept')} disabled={busy}><Check class="mr-1 h-4 w-4" /> Aceptar</Button>
					<Button size="sm" variant="outline" onclick={() => doAction('reject')} disabled={busy}><X class="mr-1 h-4 w-4" /> Rechazar</Button>
				{/if}
				{#if quote.status === 'aceptada'}
					<Button size="sm" onclick={openRelease} disabled={busy}><Ship class="mr-1 h-4 w-4" /> Liberar a Operaciones</Button>
				{/if}
				{#if quote.status === 'rechazada'}
					<Button size="sm" variant="outline" onclick={clone} disabled={busy}><Plus class="mr-1 h-4 w-4" /> Re-cotizar (clonar)</Button>
				{/if}
			</div>
		</div>

		<div class="grid gap-4 sm:grid-cols-3">
			<Card.Root><Card.Header><Card.Description>Costo total</Card.Description><Card.Title class="text-xl">{formatMoney(quote.total_cost, quote.currency)}</Card.Title></Card.Header></Card.Root>
			<Card.Root><Card.Header><Card.Description>Venta total</Card.Description><Card.Title class="text-xl">{formatMoney(quote.total_sale, quote.currency)}</Card.Title></Card.Header></Card.Root>
			<Card.Root><Card.Header><Card.Description>Margen</Card.Description><Card.Title class="text-xl text-emerald-600">{formatMoney(quote.margin, quote.currency)}</Card.Title></Card.Header></Card.Root>
		</div>

		<Card.Root>
			<Card.Content class="pt-6">
				<div class="mb-5 flex flex-wrap gap-1 border-b">
					{#each [{ id: 'conceptos', label: 'Conceptos' }, { id: 'datos', label: 'Datos' }] as t (t.id)}
						<button type="button" class="border-b-2 px-3 py-2 text-sm font-medium transition-colors {tab === t.id ? 'border-primary text-foreground' : 'border-transparent text-muted-foreground hover:text-foreground'}" onclick={() => (tab = t.id)}>{t.label}</button>
					{/each}
				</div>

				{#if tab === 'conceptos'}
					<div class="mb-3 flex justify-end"><Button size="sm" variant="outline" onclick={startAdd}><Plus class="mr-1 h-4 w-4" /> Agregar concepto</Button></div>
					{#if adding}
						<div class="mb-4 grid gap-3 rounded-md border p-3 sm:grid-cols-3">
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Concepto</span><select class={inputCls} bind:value={newItem.concept}>{#each QUOTE_CONCEPTS 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">Proveedor</span><select class={inputCls} bind:value={newItem.supplier_id}><option value={undefined}>—</option>{#each suppliers as s (s.id)}<option value={s.id}>{s.name}</option>{/each}</select></label>
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Descripción</span><input class={inputCls} bind:value={newItem.description} /></label>
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Cantidad</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={newItem.quantity} /></label>
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Costo unitario</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={newItem.unit_cost} /></label>
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Venta unitaria</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={newItem.unit_sale} /></label>
							<div class="flex justify-end gap-2 sm:col-span-3"><Button variant="outline" size="sm" onclick={() => (adding = false)}>Cancelar</Button><Button size="sm" onclick={saveItem}>Guardar</Button></div>
						</div>
					{/if}
					{#if items.length === 0}
						<p class="text-sm text-muted-foreground">Sin conceptos. Agrega el flete, despacho, gastos, etc.</p>
					{:else}
						<div class="overflow-x-auto">
							<Table.Root>
								<Table.Header><Table.Row><Table.Head>Concepto</Table.Head><Table.Head>Proveedor</Table.Head><Table.Head class="text-right">Cant.</Table.Head><Table.Head class="text-right">Costo</Table.Head><Table.Head class="text-right">Venta</Table.Head><Table.Head></Table.Head></Table.Row></Table.Header>
								<Table.Body>
									{#each items as it (it.id)}
										<Table.Row>
											<Table.Cell class="font-medium">{labelOf(QUOTE_CONCEPTS, it.concept)}{#if it.description}<span class="block text-xs text-muted-foreground">{it.description}</span>{/if}</Table.Cell>
											<Table.Cell>{supplierName(it.supplier_id)}</Table.Cell>
											<Table.Cell class="text-right">{it.quantity}</Table.Cell>
											<Table.Cell class="text-right">{formatMoney(it.line_cost, quote.currency)}</Table.Cell>
											<Table.Cell class="text-right">{formatMoney(it.line_sale, quote.currency)}</Table.Cell>
											<Table.Cell class="text-right"><Button variant="ghost" size="sm" onclick={() => removeItem(it)} aria-label="Eliminar"><Trash2 class="h-4 w-4 text-destructive" /></Button></Table.Cell>
										</Table.Row>
									{/each}
								</Table.Body>
							</Table.Root>
						</div>
					{/if}
				{:else}
					<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} bind:value={form.reference} /></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">Solicitud (RFQ)</span><select class={inputCls} bind:value={form.service_request_id}><option value={undefined}>—</option>{#each requests as r (r.id)}<option value={r.id}>{r.reference ?? `#${r.id}`}</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}>{#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">Fecha de la cotización</span><input type="date" class={inputCls} bind:value={form.issue_date} /></label>
						<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Vigencia</span><input type="date" class={inputCls} bind:value={form.valid_until} /></label>
						{#if quote.load_type}<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Variante</span><input class="{inputCls} bg-muted/40" value={quote.load_type} readonly /></label>{/if}
						<label class="flex flex-col gap-1 text-sm sm:col-span-2"><span class="font-medium">Notas</span><textarea rows="2" class={inputCls} bind:value={form.notes}></textarea></label>
						<label class="flex flex-col gap-1 text-sm sm:col-span-2"><span class="font-medium">Términos y condiciones</span><textarea rows="2" class={inputCls} bind:value={form.terms}></textarea></label>
					</div>
					<div class="mt-6 flex justify-end border-t pt-4"><Button onclick={saveHeader} disabled={saving}>{saving ? 'Guardando…' : 'Guardar cambios'}</Button></div>
				{/if}
			</Card.Content>
		</Card.Root>
	{/if}
</div>

{#if showEmail && quote}
	<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4" role="presentation" onclick={() => (showEmail = false)}>
		<div class="w-full max-w-lg rounded-lg border bg-card p-6 shadow-lg" role="dialog" aria-modal="true" tabindex="-1" onclick={(e) => e.stopPropagation()}>
			<h3 class="mb-4 flex items-center gap-2 text-base font-semibold"><Mail class="h-4 w-4" /> Enviar cotización por correo</h3>
			<div class="grid gap-3">
				<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Para *</span><input type="email" class={inputCls} bind:value={emailForm.to} placeholder="cliente@empresa.com" /></label>
				<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Asunto</span><input class={inputCls} bind:value={emailForm.subject} /></label>
				<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Mensaje</span><textarea rows="4" class={inputCls} bind:value={emailForm.message}></textarea></label>
				<p class="text-xs text-muted-foreground">Se adjunta el PDF de la cotización con el formato y la marca configurados.</p>
			</div>
			<div class="mt-5 flex justify-end gap-2 border-t pt-4">
				<Button variant="outline" onclick={() => (showEmail = false)}>Cancelar</Button>
				<Button onclick={sendEmail} disabled={busy}>{busy ? 'Enviando…' : 'Enviar'}</Button>
			</div>
		</div>
	</div>
{/if}

{#if showRelease && quote}
	<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4" role="presentation" onclick={() => (showRelease = false)}>
		<div class="w-full max-w-md rounded-lg border bg-card p-6 shadow-lg" role="dialog" aria-modal="true" tabindex="-1" onclick={(e) => e.stopPropagation()}>
			<h3 class="mb-1 flex items-center gap-2 text-base font-semibold"><Ship class="h-4 w-4" /> Liberar a Operaciones</h3>
			<p class="mb-4 text-sm text-muted-foreground">Confirma la dirección de la operación; se creará el embarque con sus hitos.</p>
			<div class="grid gap-3">
				<label class="flex flex-col gap-1 text-sm">
					<span class="font-medium">Tipo de operación</span>
					<select class={inputCls} bind:value={releaseDir}>
						<option value="importacion">Importación</option>
						<option value="exportacion">Exportación</option>
					</select>
					<span class="text-xs text-muted-foreground">Prefijada desde la solicitud; los hitos se generan según esta dirección.</span>
				</label>
			</div>
			<div class="mt-5 flex justify-end gap-2 border-t pt-4">
				<Button variant="outline" onclick={() => (showRelease = false)}>Cancelar</Button>
				<Button onclick={confirmRelease} disabled={busy}>{busy ? 'Liberando…' : 'Liberar'}</Button>
			</div>
		</div>
	</div>
{/if}
