<script lang="ts">
	import { Button } from '$lib/components/ui/button';
	import * as Dialog from '$lib/components/ui/dialog';
	import * as AlertDialog from '$lib/components/ui/alert-dialog';
	import { Input } from '$lib/components/ui/input';
	import { Label } from '$lib/components/ui/label';
	import { toast } from 'svelte-sonner';
	import {
		createExchangeRate,
		updateExchangeRate,
		type ExchangeRate,
		getDofExchangeRate
	} from '$lib/api/dashboard/a76/general_catalogs/exchange-rate';
	import { companyStore } from '$lib/stores/company.svelte';
	import {
		Scale,
		BadgeDollarSign,
		Info,
		AlertCircle,
		ArrowRight,
		CloudDownload
	} from 'lucide-svelte';
	import { fly, scale } from 'svelte/transition';
	import { cubicOut } from 'svelte/easing';
	import { m } from '$lib/i18n/messages';

	let {
		open = $bindable(false),
		item = null,
		onSuccess,
		overlayClass = 'bg-black/80 backdrop-blur-sm',
		initialDate = ''
	}: {
		open: boolean;
		item?: ExchangeRate | null;
		onSuccess?: () => void;
		overlayClass?: string;
		initialDate?: string;
	} = $props();

	const isEdit = $derived(!!item);
	const isMissingRateContext = $derived(!isEdit && initialDate);
	const title = $derived(
		isEdit
			? m.exchange_rate_edit_title()
			: isMissingRateContext
				? m.exchange_rate_required_title()
				: m.exchange_rate_new_title()
	);

	let formData = $state({
		date: '',
		value: null as number | null,
		local_currency: '',
		foreign_currency: ''
	});

	let loading = $state(false);
	let scraping = $state(false);
	let error = $state<string | null>(null);
	let showConfirmation = $state(false);

	// Cargar datos al abrir
	$effect(() => {
		if (open) {
			if (item && item.date) {
				const formattedDate = item.date.includes('T') ? item.date.split('T')[0] : item.date;
				formData = {
					date: formattedDate,
					value: item.value,
					local_currency: item.local_currency || '',
					foreign_currency: item.foreign_currency || ''
				};
			} else {
				formData = {
					date: initialDate || new Date().toISOString().split('T')[0],
					value: null,
					local_currency: 'MXN',
					foreign_currency: 'USD'
				};

				// Si es modo contexto (falta dato) y tenemos fecha, intentar cargar automáticamente del DOF
				if (initialDate && !item) {
					// Opcional: Auto-consultar
					// fetchFromDof(initialDate);
				}
			}
			error = null;
		}
	});

	async function fetchFromDof(date: string) {
		if (!date) return;
		scraping = true;
		error = null;
		try {
			const response = await getDofExchangeRate(date);
			// The API returns an ApiResponse object, so we need to access response.data
			// response.data contains { success: boolean, value: number, message: string }
			if (response.data?.success && response.data?.value) {
				formData.value = response.data.value;
				toast.success(m.exchange_rate_toast_dof_success({ value: String(response.data.value) }));
			} else {
				toast.error(
					response.data?.message || response.error || m.exchange_rate_toast_dof_error()
				);
				// No bloquear, permitir manual
			}
		} catch (e) {
			console.error(e);
			toast.error(m.exchange_rate_toast_dof_service_error());
		} finally {
			scraping = false;
		}
	}

	function handleSubmit() {
		error = null;
		try {
			const companyId = companyStore.activeCompany?.id;
			if (!companyId) throw new Error(m.exchange_rate_error_no_company());
			if (!formData.date) throw new Error(m.exchange_rate_error_date_required());
			if (
				formData.value === null ||
				formData.value === undefined ||
				String(formData.value).trim() === ''
			)
				throw new Error(m.exchange_rate_error_value_required());
			if (Number(formData.value) <= 0)
				throw new Error(m.exchange_rate_error_value_positive());

			showConfirmation = true;
		} catch (e) {
			error = e instanceof Error ? e.message : 'Error';
		}
	}

	async function confirmSubmit() {
		loading = true;
		error = null;
		try {
			const companyId = companyStore.activeCompany?.id;
			if (!companyId) throw new Error(m.exchange_rate_error_no_company());

			const dataToSend = {
				date: formData.date,
				value: Number(formData.value),
				local_currency: formData.local_currency?.trim().toUpperCase() || null,
				foreign_currency: formData.foreign_currency?.trim().toUpperCase() || null
			};

			if (isEdit && item) {
				await updateExchangeRate(item.id, dataToSend, companyId);
				toast.success(m.exchange_rate_toast_update_success());
			} else {
				await createExchangeRate(dataToSend, companyId);
				toast.success(m.exchange_rate_toast_create_success());
			}

			showConfirmation = false;
			open = false;
			if (onSuccess) onSuccess();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Error';
			showConfirmation = false;
		} finally {
			loading = false;
		}
	}
</script>

<Dialog.Root bind:open>
	<Dialog.Portal>
		<Dialog.Overlay class="fixed inset-0 z-[9999] {overlayClass}" />

		<Dialog.Content
			class="fixed top-[50%] left-[50%] z-[10000] w-full max-w-[480px] translate-x-[-50%] translate-y-[-50%] overflow-hidden border-0 bg-transparent p-0 shadow-2xl sm:rounded-xl"
		>
			<div
				class="flex h-full flex-col overflow-hidden rounded-xl border border-border bg-background"
			>
				{#if isMissingRateContext}
					<div
						class="flex gap-4 border-b border-amber-100 bg-amber-50 p-5 dark:border-amber-900/50 dark:bg-amber-950/40"
					>
						<div
							class="h-fit shrink-0 rounded-full bg-amber-100 p-2.5 shadow-sm dark:bg-amber-900/60"
						>
							<AlertCircle class="text-amber-600 dark:text-amber-400" size={24} />
						</div>
						<div class="space-y-1">
							<h3 class="text-lg leading-tight font-semibold text-amber-900 dark:text-amber-100">
								{title}
							</h3>
							<p class="text-sm leading-relaxed text-amber-800/80 dark:text-amber-200/80">
								{m.exchange_rate_required_description()}
							</p>
						</div>
					</div>
				{:else}
					<Dialog.Header class="p-6 pb-2">
						<Dialog.Title class="flex items-center gap-2 text-xl">
							<BadgeDollarSign class="text-primary" />
							{title}
						</Dialog.Title>
					</Dialog.Header>
				{/if}

				<form
					onsubmit={(e) => {
						e.preventDefault();
						handleSubmit();
					}}
					class="space-y-6 p-6 pt-4"
				>
					{#if error}
						<div
							class="flex gap-3 rounded-lg border border-destructive/20 bg-destructive/10 p-3 text-sm text-destructive"
							transition:fly={{ y: -10 }}
						>
							<AlertCircle size={16} class="mt-0.5 shrink-0" />
							<span class="font-medium">{error}</span>
						</div>
					{/if}

					<div class="grid gap-5">
						<div class="grid gap-2">
							<Label for="date" class="ml-1 text-sm font-medium text-muted-foreground"
								>{m.exchange_rate_applicable_date()}</Label
							>
							<div class="relative">
								<Input
									id="date"
									type="date"
									bind:value={formData.date}
									disabled={loading}
									required
									class="h-11 bg-muted/30 pl-3 text-base transition-colors focus:bg-background"
								/>
								{#if isMissingRateContext}
									<div
										class="absolute top-1/2 right-3 -translate-y-1/2 rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-600"
									>
										{m.exchange_rate_required_badge()}
									</div>
								{/if}
							</div>
						</div>

						<div class="grid gap-2">
							<Label for="value" class="ml-1 text-sm font-medium text-muted-foreground"
								>{m.exchange_rate_exchange_rate_label()}</Label
							>
							<div class="group relative">
								<div
									class="absolute top-1/2 left-3 -translate-y-1/2 font-semibold text-muted-foreground"
								>
									$
								</div>
								<Input
									id="value"
									type="number"
									step="0.0001"
									lang="en"
									bind:value={formData.value}
									disabled={loading}
									required
									placeholder="0.0000"
									class="h-11 pl-7 font-mono text-lg tracking-wide ring-primary/20 transition-all group-hover:border-primary/50 focus:ring-2"
									autofocus
								/>
							</div>
							<div class="mt-1 flex items-start justify-between">
								<Button
									type="button"
									variant="secondary"
									size="sm"
									class="h-8 font-medium shadow-sm transition-all"
									disabled={scraping || loading || !formData.date}
									onclick={() => fetchFromDof(formData.date)}
								>
									{#if scraping}
										<span class="mr-2 animate-spin">⟳</span> {m.exchange_rate_consulting()}
									{:else}
										<CloudDownload size={15} class="mr-2" /> {m.exchange_rate_consult_dof()}
									{/if}
								</Button>
								<p class="mt-2 px-1 text-right text-[11px] text-muted-foreground">{m.exchange_rate_example_suffix()} 24.1234</p>
							</div>
						</div>
					</div>

					<Dialog.Footer class="mt-4 grid grid-cols-2 gap-3 pt-2">
						<Button
							type="button"
							variant="outline"
							onclick={() => (open = false)}
							disabled={loading}
							class="w-full hover:bg-muted/50"
						>
							{m.exchange_rate_cancel()}
						</Button>
						<Button type="submit" disabled={loading} class="w-full font-medium shadow-sm">
							{#if loading}
								<span class="mr-2 animate-spin">⟳</span>
							{:else}
								{m.exchange_rate_ok()}
							{/if}
						</Button>
					</Dialog.Footer>
				</form>
			</div>
		</Dialog.Content>
	</Dialog.Portal>
</Dialog.Root>

<AlertDialog.Root bind:open={showConfirmation}>
	<AlertDialog.Content class="z-[10002]">
		<AlertDialog.Header>
			<AlertDialog.Title>{m.exchange_rate_confirm_title()}</AlertDialog.Title>
			<AlertDialog.Description>
				{#if isEdit}
					{m.exchange_rate_confirm_description_update({ value: String(formData.value), date: formData.date })}
				{:else}
					{m.exchange_rate_confirm_description_create({ value: String(formData.value), date: formData.date })}
				{/if}
			</AlertDialog.Description>
		</AlertDialog.Header>
		<AlertDialog.Footer>
			<AlertDialog.Cancel onclick={() => (showConfirmation = false)}>{m.exchange_rate_cancel()}</AlertDialog.Cancel>
			<AlertDialog.Action onclick={confirmSubmit}>{m.exchange_rate_confirm_action()}</AlertDialog.Action>
		</AlertDialog.Footer>
	</AlertDialog.Content>
</AlertDialog.Root>
