<script lang="ts">
	import { Button } from '$lib/components/ui/button';
	import {
		satCatalogsAPI,
		type ConceptInput,
		type SatCatalogItem,
		type SatUnitOfMeasure
	} from '$lib/api/fin';
	import { toast } from 'svelte-sonner';

	let {
		form = $bindable(),
		companyId,
		/** Clave ProdServ ya elegida; se muestra resuelta en vez del buscador. */
		productService = $bindable(),
		/** Error del 409 del backend, mostrado junto al campo de clave ProdServ. */
		productServiceError = $bindable()
	}: {
		form: ConceptInput;
		companyId: number | null;
		productService: SatCatalogItem | null;
		productServiceError: string;
	} = $props();

	let unitsOfMeasure = $state<SatUnitOfMeasure[]>([]);
	let taxObjects = $state<SatCatalogItem[]>([]);

	let productServiceQuery = $state('');
	let productServiceOptions = $state<SatCatalogItem[]>([]);
	let searchingProductService = $state(false);

	$effect(() => {
		const cid = companyId;
		if (!cid) return;
		void loadCatalogs(cid);
	});

	async function loadCatalogs(cid: number) {
		try {
			[unitsOfMeasure, taxObjects] = await Promise.all([
				satCatalogsAPI.unitsOfMeasure(cid),
				satCatalogsAPI.taxObjects(cid)
			]);
		} catch (e) {
			toast.error(e instanceof Error ? e.message : 'No se pudieron cargar los catálogos del SAT');
		}
	}

	/** Busca claves ProdServ; a partir de 2 caracteres para no traer el catálogo completo. */
	async function searchProductServices() {
		const cid = companyId;
		const term = productServiceQuery.trim();
		if (!cid || term.length < 2) {
			productServiceOptions = [];
			return;
		}
		searchingProductService = true;
		try {
			productServiceOptions = await satCatalogsAPI.productsServices(cid, {
				search: term,
				limit: 20
			});
		} catch (e) {
			toast.error(
				e instanceof Error ? e.message : 'No se pudo buscar la clave de producto/servicio'
			);
		} finally {
			searchingProductService = false;
		}
	}

	function pick(option: SatCatalogItem) {
		productService = option;
		form.product_service_id = option.id;
		productServiceQuery = '';
		productServiceOptions = [];
		productServiceError = '';
	}

	function clearProductService() {
		productService = null;
		form.product_service_id = 0;
		productServiceOptions = [];
	}

	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="grid gap-4 sm:grid-cols-2">
	<label class="flex flex-col gap-1 text-sm">
		<span class="font-medium">Clave *</span>
		<input class="font-mono {inputCls}" bind:value={form.code} maxlength="40" required />
	</label>
	<label class="flex flex-col gap-1 text-sm">
		<span class="font-medium">Precio unitario</span>
		<input type="number" step="0.01" min="0" class={inputCls} bind:value={form.unit_price} />
	</label>

	<label class="flex flex-col gap-1 text-sm sm:col-span-2">
		<span class="font-medium">Descripción *</span>
		<input class={inputCls} bind:value={form.description} maxlength="500" required />
	</label>

	<div class="flex flex-col gap-1 text-sm sm:col-span-2">
		<span class="font-medium">Clave de producto/servicio del SAT *</span>
		<p class="text-xs text-muted-foreground">
			Una clave del SAT solo puede estar asignada a un concepto de la empresa.
		</p>
		{#if productService}
			<div class="flex items-center justify-between gap-2 rounded-md border px-3 py-2">
				<span class="text-sm">
					<span class="font-mono">{productService.code}</span>
					<span class="text-muted-foreground"> — {productService.description}</span>
				</span>
				<Button type="button" variant="ghost" size="sm" onclick={clearProductService}
					>Cambiar</Button
				>
			</div>
		{:else}
			<input
				class={inputCls}
				placeholder="Escribe al menos 2 caracteres (clave o descripción)…"
				bind:value={productServiceQuery}
				oninput={searchProductServices}
			/>
			{#if searchingProductService}
				<p class="text-xs text-muted-foreground">Buscando…</p>
			{:else if productServiceOptions.length > 0}
				<ul class="max-h-48 overflow-y-auto rounded-md border">
					{#each productServiceOptions as option (option.id)}
						<li>
							<button
								type="button"
								class="w-full px-3 py-2 text-left text-sm hover:bg-muted"
								onclick={() => pick(option)}
							>
								<span class="font-mono">{option.code}</span>
								<span class="text-muted-foreground"> — {option.description}</span>
							</button>
						</li>
					{/each}
				</ul>
			{:else if productServiceQuery.trim().length >= 2}
				<p class="text-xs text-muted-foreground">Sin coincidencias en el catálogo.</p>
			{/if}
		{/if}
		{#if productServiceError}
			<p class="text-xs text-destructive">{productServiceError}</p>
		{/if}
	</div>

	<label class="flex flex-col gap-1 text-sm">
		<span class="font-medium">Unidad de medida</span>
		<select class={inputCls} bind:value={form.unit_of_measure_id}>
			<option value={null}>Sin especificar</option>
			{#each unitsOfMeasure as unit (unit.id)}
				<option value={unit.id}>{unit.code} — {unit.name}</option>
			{/each}
		</select>
	</label>
	<label class="flex flex-col gap-1 text-sm">
		<span class="font-medium">Objeto de impuesto</span>
		<select class={inputCls} bind:value={form.tax_object_id}>
			<option value={null}>Sin especificar</option>
			{#each taxObjects as taxObject (taxObject.id)}
				<option value={taxObject.id}>{taxObject.code} — {taxObject.description}</option>
			{/each}
		</select>
	</label>

	<label class="flex flex-col gap-1 text-sm">
		<span class="font-medium">Moneda</span>
		<input class={inputCls} bind:value={form.currency} maxlength="3" />
	</label>
	<label class="flex items-center gap-2 self-end text-sm">
		<input type="checkbox" class="h-4 w-4 rounded border" bind:checked={form.is_active} />
		<span class="font-medium">Activo</span>
	</label>

	<label class="flex flex-col gap-1 text-sm sm:col-span-2">
		<span class="font-medium">Notas</span>
		<textarea rows="3" class={inputCls} bind:value={form.notes}></textarea>
	</label>
</div>
