<script lang="ts">
	import { ArrowLeft, FileText, Plus, Trash2 } 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 {
		serviceRequestsAPI, rateRequestsAPI, accountsAPI, suppliersAPI,
		type ServiceRequest, type ServiceRequestInput, type RateRequest, type RateRequestInput,
		type Account, type Supplier
	} from '$lib/api/crm';
	import {
		OPERATION_TYPES, TRANSPORT_MODES, SERVICE_TYPES, LOAD_TYPES, SR_STATUS,
		QUOTE_CONCEPTS, RATE_STATUS, labelOf
	} from '$lib/components/crm/format';
	import { toast } from 'svelte-sonner';

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

	let sr = $state<ServiceRequest | null>(null);
	let form = $state<ServiceRequestInput>({ operation_type: 'exportacion' });
	let accounts = $state<Account[]>([]);
	let suppliers = $state<Supplier[]>([]);
	let rates = $state<RateRequest[]>([]);
	let tab = $state('requerimientos');
	let loading = $state(false);
	let saving = $state(false);
	let busy = $state(false);
	let adding = $state(false);
	let newRate = $state<RateRequestInput>({ service_request_id: 0, concept: 'flete_internacional', status: 'solicitada' });

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

	async function load(cid: number, id: number) {
		loading = true;
		try {
			[sr, accounts, suppliers, rates] = await Promise.all([
				serviceRequestsAPI.get(id, cid),
				accountsAPI.list(cid),
				suppliersAPI.list(cid),
				rateRequestsAPI.list(cid, id)
			]);
			form = { ...sr };
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo cargar la solicitud');
		} finally {
			loading = false;
		}
	}

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

	async function registerContact() {
		if (!companyId || !sr) return;
		const notes = window.prompt('Nota del contacto al cliente (opcional):') ?? null;
		busy = true;
		try {
			sr = await serviceRequestsAPI.registerContact(sr.id, companyId, notes);
			form = { ...sr };
			toast.success('Contacto registrado');
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo registrar el contacto');
		} finally {
			busy = false;
		}
	}

	async function requote() {
		if (!companyId || !sr) return;
		busy = true;
		try {
			sr = await serviceRequestsAPI.requote(sr.id, companyId);
			form = { ...sr };
			toast.success('Solicitud reabierta para re-cotizar');
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo reabrir');
		} finally {
			busy = false;
		}
	}

	function startAdd() {
		newRate = { service_request_id: srId, concept: 'flete_internacional', status: 'solicitada', currency: 'USD' };
		adding = true;
	}

	async function saveRate() {
		if (!companyId) return;
		try {
			await rateRequestsAPI.create({ ...newRate, service_request_id: srId }, companyId);
			toast.success('Tarifa agregada');
			adding = false;
			rates = await rateRequestsAPI.list(companyId, srId);
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudo agregar');
		}
	}

	async function removeRate(r: RateRequest) {
		if (!companyId || !confirm('¿Eliminar tarifa?')) return;
		await rateRequestsAPI.remove(r.id, companyId);
		rates = await rateRequestsAPI.list(companyId, srId);
	}

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

	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/solicitudes"><ArrowLeft class="mr-1 h-4 w-4" /> Solicitudes</Button>

	{#if loading && !sr}
		<p class="text-sm text-muted-foreground">Cargando…</p>
	{:else if sr}
		<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"><FileText class="h-6 w-6" /> {sr.reference ?? `Solicitud #${sr.id}`}</h1>
				<p class="mt-1 text-sm text-muted-foreground">{labelOf(OPERATION_TYPES, sr.operation_type)} · {labelOf(SR_STATUS, sr.status)}</p>
			</div>
			<div class="flex flex-wrap gap-2">
				{#if sr.status === 'nueva' || sr.status === 'contacto'}<Button size="sm" variant="outline" onclick={registerContact} disabled={busy}>Registrar contacto</Button>{/if}
				{#if sr.status === 'rechazada' || sr.status === 'cotizada'}<Button size="sm" variant="outline" onclick={requote} disabled={busy}>Re-cotizar</Button>{/if}
			</div>
		</div>
		{#if sr.first_contact_at}<p class="text-xs text-muted-foreground">Contacto registrado{#if sr.first_contact_notes}: {sr.first_contact_notes}{/if}</p>{/if}

		<Card.Root>
			<Card.Content class="pt-6">
				<div class="mb-5 flex flex-wrap gap-1 border-b">
					{#each [{ id: 'requerimientos', label: 'Requerimientos' }, { id: 'tarifas', label: 'Tarifas' }] 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 === 'requerimientos'}
					<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">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">Medio de transporte</span><select class={inputCls} bind:value={form.transport_mode}><option value={undefined}>—</option>{#each 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><input class={inputCls} maxlength="10" bind:value={form.incoterm} /></label>
						<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Origen</span><input class={inputCls} bind:value={form.origin} /></label>
						<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Destino</span><input class={inputCls} bind:value={form.destination} /></label>
						<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Tipo de carga</span><input class={inputCls} bind:value={form.cargo_type} /></label>
						<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Modalidad</span><select class={inputCls} bind:value={form.load_type}><option value={undefined}>—</option>{#each LOAD_TYPES as l (l.value)}<option value={l.value}>{l.label}</option>{/each}</select></label>
						<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Peso (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">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">Contenedor / Equipo</span><input class={inputCls} bind:value={form.container_equipment} /></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 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">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>
						<label class="flex flex-col gap-1 text-sm sm:col-span-2"><span class="font-medium">Mercancía</span><textarea rows="2" class={inputCls} bind:value={form.commodity}></textarea></label>
						<label class="flex flex-col gap-1 text-sm sm:col-span-2"><span class="font-medium">Otros requerimientos</span><textarea rows="2" class={inputCls} bind:value={form.requirements}></textarea></label>
					</div>
					<div class="mt-6 flex justify-end border-t pt-4"><Button onclick={save} disabled={saving}>{saving ? 'Guardando…' : 'Guardar cambios'}</Button></div>
				{:else}
					<div class="mb-3 flex justify-end"><Button size="sm" variant="outline" onclick={startAdd}><Plus class="mr-1 h-4 w-4" /> Agregar tarifa</Button></div>
					{#if adding}
						<div class="mb-4 grid gap-3 rounded-md border p-3 sm:grid-cols-2">
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Concepto</span><select class={inputCls} bind:value={newRate.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={newRate.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">Tarifa</span><input type="number" min="0" step="0.01" class={inputCls} bind:value={newRate.rate_amount} /></label>
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Moneda</span><input class={inputCls} maxlength="3" bind:value={newRate.currency} /></label>
							<label class="flex flex-col gap-1 text-sm"><span class="font-medium">Estatus</span><select class={inputCls} bind:value={newRate.status}>{#each RATE_STATUS 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">Descripción</span><input class={inputCls} bind:value={newRate.description} /></label>
							<div class="flex justify-end gap-2 sm:col-span-2"><Button variant="outline" size="sm" onclick={() => (adding = false)}>Cancelar</Button><Button size="sm" onclick={saveRate}>Guardar</Button></div>
						</div>
					{/if}
					{#if rates.length === 0}
						<p class="text-sm text-muted-foreground">Sin solicitudes de tarifa.</p>
					{:else}
						<Table.Root>
							<Table.Header><Table.Row><Table.Head>Concepto</Table.Head><Table.Head>Proveedor</Table.Head><Table.Head class="text-right">Tarifa</Table.Head><Table.Head>Estatus</Table.Head><Table.Head></Table.Head></Table.Row></Table.Header>
							<Table.Body>
								{#each rates as r (r.id)}
									<Table.Row>
										<Table.Cell>{labelOf(QUOTE_CONCEPTS, r.concept)}</Table.Cell>
										<Table.Cell>{supplierName(r.supplier_id)}</Table.Cell>
										<Table.Cell class="text-right">{r.rate_amount != null ? `${r.rate_amount} ${r.currency ?? ''}` : '—'}</Table.Cell>
										<Table.Cell>{labelOf(RATE_STATUS, r.status)}</Table.Cell>
										<Table.Cell class="text-right"><Button variant="ghost" size="sm" onclick={() => removeRate(r)} aria-label="Eliminar"><Trash2 class="h-4 w-4 text-destructive" /></Button></Table.Cell>
									</Table.Row>
								{/each}
							</Table.Body>
						</Table.Root>
					{/if}
				{/if}
			</Card.Content>
		</Card.Root>
	{/if}
</div>
