import { router } from '@inertiajs/react';
import { Plus, Trash2 } from 'lucide-react';
import type { Dispatch, SetStateAction } from 'react';
import { useEffect, useState } from 'react';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { DatePickerField } from '@/components/common/DatePickerField';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableHeaderRow,
    TableRow,
} from '@/components/ui/table';
import { Textarea } from '@/components/ui/textarea';
import {
    ChartOfAccountAsyncSelect,
    ChartOfAccountCodeDisplay,
} from '@/features/documents/components/chart-of-account-async-select';
import { ClientAsyncSelect, type ClientSearchRow } from '@/features/documents/components/client-async-select';
import { DocumentLineItemsBulkBar } from '@/features/documents/components/document-line-items-bulk-bar';
import { SupplierAsyncSelect, type SupplierSearchRow } from '@/features/documents/components/supplier-async-select';
import type { DocumentDetail, StructuredAccountingExtractionData } from '@/features/documents/types';
import { useAuthorization } from '@/hooks/use-authorization';
import { useI18n } from '@/hooks/use-i18n';
import {
    decimalPlacesFromValue,
    formatCalculatedMoney,
    formatDisplayMoney,
    isIncompleteDecimalInput,
    resolveLineCalculationDecimals,
    roundToDecimals,
} from '@/lib/money-precision';
import { IconButton } from '@/components/common/IconButton';

type DocumentExtractionPanelProps = {
    document: DocumentDetail;
    /** `split`: summary + lines side by side (default). `details` / `products`: single column. */
    layout?: 'split' | 'details' | 'products';
    /**
     * When set, keeps both summary and line editors mounted but visually hidden (off-screen).
     * Use while another main workspace tab (e.g. activity) is active so form state is preserved.
     */
    preserveOffscreen?: boolean;
};

type ExtractionData = StructuredAccountingExtractionData;

type LineItemForm = {
    description: string;
    chart_of_account_code: string;
    vat_rate: string;
    vat_amount: string;
    quantity: string;
    discount_percent: string;
    unit_price: string;
    line_total: string;
};

type ExtractionForm = {
    document_type: string;
    issuer_name: string;
    issuer_identifier: string;
    issuer_vat_number: string;
    customer_name: string;
    customer_identifier: string;
    customer_vat_number: string;
    document_direction: 'outgoing' | 'incoming' | 'unknown' | '';
    direction_reason: string;
    document_number: string;
    issue_date: string;
    due_date: string;
    currency: string;
    total_amount: string;
    discount_amount: string;
    discount_percent: string;
    vat_amount: string;
    notes: string;
    confidence: string;
    line_items: LineItemForm[];
};

const EMPTY_DIRECTION_VALUE = '__empty__';
const EMPTY_SELECT_VALUE = '__none__';

function normalizeVatRateValue(
    vatRates: Array<{ code: string; name: string; rate_percent: string }>,
    raw: unknown,
): string {
    if (raw === null || raw === undefined) {
        return '';
    }

    const normalized =
        typeof raw === 'string'
            ? raw.trim().replace(',', '.').replace('%', '')
            : typeof raw === 'number'
                ? String(raw)
                : '';

    if (normalized === '') {
        return '';
    }

    const numeric = Number(normalized);
    if (Number.isNaN(numeric)) {
        return '';
    }

    // Handle fraction format (e.g. 0.19 => 19%).
    const percent = numeric > 0 && numeric <= 1 ? numeric * 100 : numeric;

    const match = vatRates.find((r) => Number(r.rate_percent) === Number(percent));
    if (match) {
        return match.rate_percent;
    }

    // Fallback: keep a stable representation (2 decimals) so Select can still display consistently.
    return percent % 1 === 0 ? `${percent.toFixed(0)}.00` : percent.toFixed(2);
}

export function DocumentExtractionPanel({
    document,
    layout = 'split',
    preserveOffscreen = false,
}: DocumentExtractionPanelProps) {
    const { t } = useI18n();
    const { can, hasRole } = useAuthorization();
    const canEditExtraction = can('review documents') || hasRole('admin') || hasRole('accountant');
    const [form, setForm] = useState<ExtractionForm>(
        buildFormFromData(document.extracted_data, document.extraction_options.vat_rates),
    );
    const [isSaving, setIsSaving] = useState(false);
    const [isLinesSaving, setIsLinesSaving] = useState(false);
    const [errors, setErrors] = useState<Record<string, string>>({});
    const [selectedLineIndices, setSelectedLineIndices] = useState<Set<number>>(() => new Set());
    const lineItems = form.line_items;
    const firstError = Object.values(errors)[0] ?? null;
    const vatRates = document.extraction_options.vat_rates;
    const currencies = document.extraction_options.currencies;
    const accountingDocumentTypes = document.extraction_options.accounting_document_types ?? [];
    const lineItemsBusy = isSaving || isLinesSaving;
    const allLinesSelected = lineItems.length > 0 && selectedLineIndices.size === lineItems.length;
    const someLinesSelected = selectedLineIndices.size > 0 && !allLinesSelected;

    useEffect(() => {
        setSelectedLineIndices((previous) => {
            const next = new Set<number>();
            previous.forEach((index) => {
                if (index < lineItems.length) {
                    next.add(index);
                }
            });

            return next.size === previous.size ? previous : next;
        });
    }, [lineItems.length]);

    const toggleLineSelection = (index: number) => {
        setSelectedLineIndices((previous) => {
            const next = new Set(previous);
            if (next.has(index)) {
                next.delete(index);
            } else {
                next.add(index);
            }

            return next;
        });
    };

    const toggleSelectAllLines = () => {
        if (allLinesSelected) {
            setSelectedLineIndices(new Set());

            return;
        }

        setSelectedLineIndices(new Set(lineItems.map((_, index) => index)));
    };

    const clearLineSelection = () => {
        setSelectedLineIndices(new Set());
    };

    const applyBulkLineItemsUpdate = (nextLineItems: LineItemForm[]) => {
        const nextForm = applyDocumentTotalsFromLineItems({
            ...form,
            line_items: nextLineItems,
        });

        setForm(nextForm);
        persistExtractionData(nextForm, { lineItemsOnly: true });
    };

    const bulkSetChartForSelected = (code: string) => {
        const selected = selectedLineIndices;
        const nextLineItems = form.line_items.map((item, index) =>
            selected.has(index) ? { ...item, chart_of_account_code: code } : item,
        );

        applyBulkLineItemsUpdate(nextLineItems);
    };

    const bulkSetVatForSelected = (vatRate: string) => {
        const selected = selectedLineIndices;
        const nextLineItems = form.line_items.map((item, index) => {
            if (!selected.has(index)) {
                return item;
            }

            const updated: LineItemForm = {
                ...item,
                vat_rate: vatRate,
            };

            return recalculateLineItemTotals(updated, 'vat_rate', form.currency, true);
        });

        applyBulkLineItemsUpdate(nextLineItems);
    };

    const bulkDeleteSelectedLines = () => {
        const nextForm = applyDocumentTotalsFromLineItems({
            ...form,
            line_items: form.line_items.filter((_, index) => !selectedLineIndices.has(index)),
        });

        setForm(nextForm);
        setSelectedLineIndices(new Set());
        persistExtractionData(nextForm, { lineItemsOnly: true });
    };

    const persistExtractionData = (
        nextForm: ExtractionForm,
        options?: {
            lineItemsOnly?: boolean;
            clientId?: number;
        },
    ) => {
        router.patch(
            `/admin/documents/${document.id}/extracted-data`,
            {
                extracted_data: serializeFormData(nextForm),
                ...(options?.clientId !== undefined ? { client_id: options.clientId } : {}),
            },
            {
                preserveScroll: true,
                preserveState: true,
                onStart: () => {
                    if (options?.lineItemsOnly) {
                        setIsLinesSaving(true);
                    } else {
                        setIsSaving(true);
                    }

                    setErrors({});
                },
                onError: (pageErrors) => {
                    const extractedErrors: Record<string, string> = {};
                    Object.entries(pageErrors).forEach(([key, value]) => {
                        if (key.startsWith('extracted_data')) {
                            extractedErrors[key] = String(value);
                        }
                    });
                    setErrors(extractedErrors);
                },
                onFinish: () => {
                    if (options?.lineItemsOnly) {
                        setIsLinesSaving(false);
                    } else {
                        setIsSaving(false);
                    }
                },
            },
        );
    };

    const handleSave = () => {
        persistExtractionData(form);
    };

    const addLineItem = () => {
        const nextForm = applyDocumentTotalsFromLineItems({
            ...form,
            line_items: [
                ...form.line_items,
                {
                    description: '',
                    chart_of_account_code: '',
                    vat_rate: '',
                    vat_amount: '',
                    quantity: '',
                    discount_percent: '',
                    unit_price: '',
                    line_total: '',
                },
            ],
        });

        setForm(nextForm);
        persistExtractionData(nextForm, { lineItemsOnly: true });
    };

    const removeLineItem = (index: number) => {
        const nextForm = applyDocumentTotalsFromLineItems({
            ...form,
            line_items: form.line_items.filter((_, itemIndex) => itemIndex !== index),
        });

        setForm(nextForm);
        persistExtractionData(nextForm, { lineItemsOnly: true });
    };

    const updateLineItem = (
        index: number,
        key: keyof LineItemForm,
        value: string,
        persistNow = false,
        finalizeLine = false,
    ) => {
        const nextLineItems = form.line_items.map((item, itemIndex) => {
            if (itemIndex !== index) {
                return item;
            }

            const updatedItem: LineItemForm = {
                ...item,
                [key]: value,
            };

            return recalculateLineItemTotals(updatedItem, key, form.currency, finalizeLine);
        });

        const nextForm = applyDocumentTotalsFromLineItems({
            ...form,
            line_items: nextLineItems,
        });

        setForm(nextForm);

        if (persistNow) {
            persistExtractionData(nextForm, { lineItemsOnly: true });
        }
    };

    const saveLineItemsOnUnitPriceBlur = () => {
        persistExtractionData(form, { lineItemsOnly: true });
    };

    const roundLineItemMoneyFieldOnBlur = (index: number, key: 'unit_price' | 'vat_amount') => {
        const raw = form.line_items[index]?.[key] ?? '';
        const parsed = parseNullableNumber(raw);
        if (parsed === null) {
            return;
        }

        updateLineItem(
            index,
            key,
            formatCalculatedMoney(parsed, decimalPlacesFromValue(raw)),
            true,
            true,
        );
    };

    const renderDetailsCard = () => (
        <Card className="flex max-h-none flex-col overflow-hidden max-lg:max-h-[min(62vh,32rem)]">
            <CardHeader className="shrink-0">
                <CardTitle>{t('documents.admin_show.extraction.summary_title')}</CardTitle>
            </CardHeader>
            <CardContent className="min-h-0 flex-1 space-y-4 overflow-y-auto overscroll-contain">
                {firstError ? (
                    <div className="rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive">
                        {firstError}
                    </div>
                ) : null}

                <div className="grid gap-3 text-sm md:grid-cols-2">
                    <div className="space-y-1.5">
                        <Label>{t('documents.admin_show.extraction.document_type')}</Label>
                        <Select
                            value={form.document_type || EMPTY_SELECT_VALUE}
                            disabled={!canEditExtraction || isSaving}
                            onValueChange={(value) =>
                                setField(setForm, 'document_type', value === EMPTY_SELECT_VALUE ? '' : value)
                            }
                        >
                            <SelectTrigger className="w-full">
                                <SelectValue
                                    placeholder={t('documents.admin_show.extraction.document_type_placeholder')}
                                />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value={EMPTY_SELECT_VALUE}>
                                    {t('documents.admin_show.extraction.direction_empty')}
                                </SelectItem>
                                {accountingDocumentTypes.map((row) => (
                                    <SelectItem key={row.code} value={row.code}>
                                        {row.label}
                                    </SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                    </div>
                    <FieldInput
                        label={t('documents.admin_show.extraction.document_number')}
                        value={form.document_number}
                        disabled={!canEditExtraction || isSaving}
                        onChange={(value) => setField(setForm, 'document_number', value)}
                    />

                    {/* Issuer / Supplier */}
                    <div className="col-span-full space-y-2 rounded-md border border-border/60 bg-muted/20 p-3">
                        <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                            {t('documents.admin_show.extraction.issuer_section')}
                        </p>
                        {canEditExtraction ? (
                            <SupplierAsyncSelect
                                initialCif={form.issuer_identifier || null}
                                disabled={isSaving}
                                onSelect={(supplier: SupplierSearchRow | null) => {
                                    if (!supplier) return;
                                    const next = {
                                        ...form,
                                        issuer_name: supplier.name,
                                        issuer_identifier: supplier.cif,
                                        issuer_vat_number: supplier.vat_number,
                                    };
                                    setForm(next);
                                    persistExtractionData(next);
                                }}
                            />
                        ) : null}
                        <div className="grid gap-3 md:grid-cols-3">
                            <FieldInput
                                label={t('documents.admin_show.extraction.issuer_name')}
                                value={form.issuer_name}
                                disabled={!canEditExtraction || isSaving}
                                onChange={(value) => setField(setForm, 'issuer_name', value)}
                            />
                            <FieldInput
                                label={t('documents.admin_show.extraction.issuer_identifier')}
                                value={form.issuer_identifier}
                                disabled={!canEditExtraction || isSaving}
                                onChange={(value) => setField(setForm, 'issuer_identifier', value)}
                            />
                            <FieldInput
                                label={t('documents.admin_show.extraction.issuer_vat')}
                                value={form.issuer_vat_number}
                                disabled={!canEditExtraction || isSaving}
                                onChange={(value) => setField(setForm, 'issuer_vat_number', value)}
                            />
                        </div>
                    </div>

                    {/* Customer / Client */}
                    <div className="col-span-full space-y-2 rounded-md border border-border/60 bg-muted/20 p-3">
                        <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                            {t('documents.admin_show.extraction.customer_section')}
                        </p>
                        {canEditExtraction ? (
                            <ClientAsyncSelect
                                initialCif={form.customer_identifier || null}
                                disabled={isSaving}
                                onSelect={(client: ClientSearchRow | null) => {
                                    if (!client) return;
                                    const next = {
                                        ...form,
                                        customer_name: client.name,
                                        customer_identifier: client.cif,
                                        customer_vat_number: client.vat_number,
                                    };
                                    setForm(next);
                                    persistExtractionData(next, { clientId: client.id });
                                }}
                            />
                        ) : null}
                        <div className="grid gap-3 md:grid-cols-3">
                            <FieldInput
                                label={t('documents.admin_show.extraction.customer_name')}
                                value={form.customer_name}
                                disabled={!canEditExtraction || isSaving}
                                onChange={(value) => setField(setForm, 'customer_name', value)}
                            />
                            <FieldInput
                                label={t('documents.admin_show.extraction.customer_identifier')}
                                value={form.customer_identifier}
                                disabled={!canEditExtraction || isSaving}
                                onChange={(value) => setField(setForm, 'customer_identifier', value)}
                            />
                            <FieldInput
                                label={t('documents.admin_show.extraction.customer_vat')}
                                value={form.customer_vat_number}
                                disabled={!canEditExtraction || isSaving}
                                onChange={(value) => setField(setForm, 'customer_vat_number', value)}
                            />
                        </div>
                    </div>
                    <DatePickerField
                        label={t('documents.admin_show.extraction.issue_date')}
                        value={form.issue_date}
                        disabled={!canEditExtraction || isSaving}
                        placeholder={t('documents.admin_show.extraction.date_placeholder')}
                        onChange={(value) => setField(setForm, 'issue_date', value)}
                    />
                    <DatePickerField
                        label={t('documents.admin_show.extraction.due_date')}
                        value={form.due_date}
                        disabled={!canEditExtraction || isSaving}
                        placeholder={t('documents.admin_show.extraction.date_placeholder')}
                        onChange={(value) => setField(setForm, 'due_date', value)}
                    />
                    <div className="space-y-1.5">
                        <Label>{t('documents.admin_show.extraction.currency')}</Label>
                        {canEditExtraction && currencies.length > 0 ? (
                            <Select
                                value={form.currency || EMPTY_SELECT_VALUE}
                                disabled={isSaving}
                                onValueChange={(value) =>
                                    setField(setForm, 'currency', value === EMPTY_SELECT_VALUE ? '' : value)
                                }
                            >
                                <SelectTrigger className="w-full">
                                    <SelectValue placeholder={t('documents.admin_show.extraction.currency_placeholder')} />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value={EMPTY_SELECT_VALUE}>
                                        {t('documents.admin_show.extraction.direction_empty')}
                                    </SelectItem>
                                    {currencies.map((c) => (
                                        <SelectItem key={c.code} value={c.code}>
                                            {c.code} — {c.name} ({c.symbol})
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        ) : (
                            <Input
                                value={form.currency}
                                disabled={!canEditExtraction || isSaving}
                                onChange={(e) => setField(setForm, 'currency', e.target.value)}
                                placeholder={t('documents.admin_show.extraction.currency_placeholder')}
                            />
                        )}
                    </div>
                    <FieldInput
                        label={t('documents.admin_show.extraction.total')}
                        type="number"
                        value={form.total_amount}
                        disabled={!canEditExtraction || isSaving}
                        onChange={(value) => setField(setForm, 'total_amount', value)}
                    />
                    <FieldInput
                        label={t('documents.admin_show.extraction.discount_amount')}
                        type="number"
                        value={form.discount_amount}
                        disabled={!canEditExtraction || isSaving}
                        onChange={(value) => setField(setForm, 'discount_amount', value)}
                    />
                    <FieldInput
                        label={t('documents.admin_show.extraction.discount_percent')}
                        type="number"
                        value={form.discount_percent}
                        disabled={!canEditExtraction || isSaving}
                        onChange={(value) => setField(setForm, 'discount_percent', value)}
                    />
                    <FieldInput
                        label={t('documents.admin_show.extraction.vat')}
                        type="number"
                        value={form.vat_amount}
                        disabled={!canEditExtraction || isSaving}
                        onChange={(value) => setField(setForm, 'vat_amount', value)}
                    />
                    <FieldInput
                        label={t('documents.admin_show.extraction.confidence')}
                        type="number"
                        value={form.confidence}
                        disabled={!canEditExtraction || isSaving}
                        onChange={(value) => setField(setForm, 'confidence', value)}
                    />
                    <div className="space-y-1.5">
                        <Label>{t('documents.admin_show.extraction.direction_label')}</Label>
                        <Select
                            value={form.document_direction || EMPTY_DIRECTION_VALUE}
                            disabled={!canEditExtraction || isSaving}
                            onValueChange={(value) =>
                                setField(
                                    setForm,
                                    'document_direction',
                                    value === EMPTY_DIRECTION_VALUE
                                        ? ''
                                        : (value as ExtractionForm['document_direction']),
                                )
                            }
                        >
                            <SelectTrigger className="w-full">
                                <SelectValue placeholder={t('documents.admin_show.extraction.direction_placeholder')} />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value={EMPTY_DIRECTION_VALUE}>
                                    {t('documents.admin_show.extraction.direction_empty')}
                                </SelectItem>
                                <SelectItem value="outgoing">
                                    {t('documents.admin_show.extraction.direction_outgoing')}
                                </SelectItem>
                                <SelectItem value="incoming">
                                    {t('documents.admin_show.extraction.direction_incoming')}
                                </SelectItem>
                                <SelectItem value="unknown">
                                    {t('documents.admin_show.extraction.direction_unknown')}
                                </SelectItem>
                            </SelectContent>
                        </Select>
                    </div>
                    <FieldInput
                        label={t('documents.admin_show.extraction.direction_reason')}
                        value={form.direction_reason}
                        disabled={!canEditExtraction || isSaving}
                        onChange={(value) => setField(setForm, 'direction_reason', value)}
                    />
                </div>

                <div className="space-y-1.5">
                    <Label>{t('documents.admin_show.extraction.notes_label')}</Label>
                    <Textarea
                        rows={3}
                        value={form.notes}
                        disabled={!canEditExtraction || isSaving}
                        onChange={(event) => setField(setForm, 'notes', event.target.value)}
                        placeholder={t('documents.admin_show.extraction.notes_placeholder')}
                    />
                </div>

                {canEditExtraction ? (
                    <div className="flex flex-wrap items-center gap-2">
                        <Button type="button" onClick={handleSave} disabled={isSaving}>
                            {isSaving ? t('documents.admin_show.extraction.saving') : t('documents.admin_show.extraction.save')}
                        </Button>
                        <Button
                            type="button"
                            variant="outline"
                            disabled={isSaving}
                            onClick={() =>
                                setForm(buildFormFromData(document.extracted_data, document.extraction_options.vat_rates))
                            }
                        >
                            {t('documents.admin_show.extraction.reset_fields')}
                        </Button>
                    </div>
                ) : null}
            </CardContent>
        </Card>
    );

    const renderProductsCard = () => (
        <Card>
            <CardHeader>
                <div className="flex flex-wrap items-center justify-between gap-2">
                    <div className="flex min-w-0 items-center gap-2">
                        <CardTitle>{t('documents.admin_show.extraction.products_title')}</CardTitle>
                        {lineItems.length > 0 ? (
                            <span className="rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground tabular-nums">
                                {lineItems.length}
                            </span>
                        ) : null}
                    </div>
                    {canEditExtraction ? (
                        <DocumentLineItemsBulkBar
                            selectedCount={selectedLineIndices.size}
                            disabled={lineItemsBusy}
                            vatRates={vatRates}
                            onClearSelection={clearLineSelection}
                            onBulkDelete={bulkDeleteSelectedLines}
                            onBulkSetChart={bulkSetChartForSelected}
                            onBulkSetVat={bulkSetVatForSelected}
                        />
                    ) : null}
                </div>
            </CardHeader>
            <CardContent className="space-y-3 text-sm">
                {lineItems.length > 0 ? (
                    <Table variant="embedded" className="w-full min-w-[72rem]">
                        <TableHeader>
                            <TableHeaderRow>
                                {canEditExtraction ? (
                                    <TableHead className="w-10 min-w-[2.5rem]">
                                        <Checkbox
                                            checked={
                                                allLinesSelected
                                                    ? true
                                                    : someLinesSelected
                                                        ? 'indeterminate'
                                                        : false
                                            }
                                            onCheckedChange={toggleSelectAllLines}
                                            disabled={lineItemsBusy}
                                            aria-label={t('documents.admin_show.extraction.bulk.select_all_aria')}
                                        />
                                    </TableHead>
                                ) : null}
                                <TableHead className="min-w-[16rem]">
                                    {t('documents.admin_show.extraction.table_description')}
                                </TableHead>
                                <TableHead className="min-w-[11rem]">
                                    {t('documents.admin_show.extraction.table_chart')}
                                </TableHead>
                                <TableHead className="min-w-[6.5rem]">
                                    {t('documents.admin_show.extraction.table_quantity')}
                                </TableHead>
                                <TableHead className="min-w-[7.5rem]">
                                    {t('documents.admin_show.extraction.table_unit_price')}
                                </TableHead>
                                <TableHead className="min-w-[6rem]">
                                    {t('documents.admin_show.extraction.table_line_discount')}
                                </TableHead>
                                <TableHead className="min-w-[8rem]">
                                    {t('documents.admin_show.extraction.table_line_total')}
                                </TableHead>
                                <TableHead className="min-w-[9.5rem]">
                                    {t('documents.admin_show.extraction.table_vat')}
                                </TableHead>
                                <TableHead className="min-w-[7.5rem]">
                                    {t('documents.admin_show.extraction.table_line_vat_amount')}
                                </TableHead>
                                <TableHead className="min-w-[8rem]">
                                    {t('documents.admin_show.extraction.table_line_gross_total')}
                                </TableHead>
                                {canEditExtraction ? (
                                    <TableHead className="w-14 min-w-[3.5rem] text-right">
                                        {t('documents.admin_show.extraction.table_actions')}
                                    </TableHead>
                                ) : null}
                            </TableHeaderRow>
                        </TableHeader>
                        <TableBody>
                            {lineItems.map((item, index) => (
                                <TableRow
                                    key={`line-item-${index}`}
                                    data-state={selectedLineIndices.has(index) ? 'selected' : undefined}
                                >
                                    {canEditExtraction ? (
                                        <TableCell className="w-10 min-w-[2.5rem] align-center">
                                            <Checkbox
                                                checked={selectedLineIndices.has(index)}
                                                onCheckedChange={() => toggleLineSelection(index)}
                                                disabled={lineItemsBusy}
                                                aria-label={t('documents.admin_show.extraction.bulk.select_row_aria')}
                                            />
                                        </TableCell>
                                    ) : null}
                                    <TableCell className="min-w-[16rem] align-top">
                                        <Input
                                            value={item.description}
                                            disabled={!canEditExtraction || isSaving}
                                            onChange={(event) =>
                                                updateLineItem(index, 'description', event.target.value)
                                            }
                                            placeholder={t('documents.admin_show.extraction.line_placeholder')}
                                            className="w-full min-w-[14rem]"
                                        />
                                    </TableCell>
                                    <TableCell className="min-w-[11rem]">
                                        {canEditExtraction ? (
                                            <ChartOfAccountAsyncSelect
                                                value={item.chart_of_account_code}
                                                onValueChange={(code) =>
                                                    updateLineItem(index, 'chart_of_account_code', code, true)
                                                }
                                                disabled={isSaving || isLinesSaving}
                                            />
                                        ) : (
                                            <ChartOfAccountCodeDisplay code={item.chart_of_account_code} />
                                        )}
                                    </TableCell>
                                    <TableCell className="min-w-[6.5rem]">
                                        <Input
                                            type="number"
                                            value={item.quantity}
                                            disabled={!canEditExtraction || isSaving}
                                            onChange={(event) =>
                                                updateLineItem(index, 'quantity', event.target.value)
                                            }
                                            className="w-full min-w-[5.5rem]"
                                        />
                                    </TableCell>
                                    <TableCell className="min-w-[7.5rem]">
                                        <Input
                                            type="text"
                                            inputMode="decimal"
                                            value={item.unit_price}
                                            disabled={!canEditExtraction || isSaving}
                                            onChange={(event) =>
                                                updateLineItem(index, 'unit_price', event.target.value)
                                            }
                                            onBlur={() => roundLineItemMoneyFieldOnBlur(index, 'unit_price')}
                                            className="w-full min-w-[6.5rem]"
                                        />
                                    </TableCell>
                                    <TableCell className="min-w-[6rem]">
                                        <Input
                                            type="number"
                                            value={item.discount_percent}
                                            disabled={!canEditExtraction || isSaving}
                                            onChange={(event) =>
                                                updateLineItem(index, 'discount_percent', event.target.value)
                                            }
                                            onBlur={saveLineItemsOnUnitPriceBlur}
                                            placeholder={t('documents.admin_show.extraction.percent_placeholder')}
                                            className="w-full min-w-[5rem]"
                                        />
                                    </TableCell>
                                    <TableCell className="min-w-[8rem]">
                                        <Input
                                            type="number"
                                            value={formatDisplayMoney(item.line_total)}
                                            disabled={!canEditExtraction}
                                            readOnly
                                            className="w-full min-w-[7rem] bg-muted/40"
                                        />
                                    </TableCell>
                                    <TableCell className="min-w-[9.5rem]">
                                        {canEditExtraction ? (
                                            vatRates.length > 0 ? (
                                                <Select
                                                    value={
                                                        item.vat_rate.trim() === ''
                                                            ? EMPTY_SELECT_VALUE
                                                            : item.vat_rate
                                                    }
                                                    onValueChange={(value) =>
                                                        updateLineItem(
                                                            index,
                                                            'vat_rate',
                                                            value === EMPTY_SELECT_VALUE ? '' : value,
                                                            true,
                                                        )
                                                    }
                                                    disabled={isSaving || isLinesSaving}
                                                >
                                                    <SelectTrigger className="h-9 w-full">
                                                        <SelectValue placeholder={t('documents.admin_show.extraction.vat_placeholder')} />
                                                    </SelectTrigger>
                                                    <SelectContent>
                                                        <SelectItem value={EMPTY_SELECT_VALUE}>
                                                            {t('documents.admin_show.extraction.direction_empty')}
                                                        </SelectItem>
                                                        {vatRates.map((row) => (
                                                            <SelectItem key={row.code} value={row.rate_percent}>
                                                                {row.name} ({row.rate_percent}%)
                                                            </SelectItem>
                                                        ))}
                                                    </SelectContent>
                                                </Select>
                                            ) : (
                                                <Input
                                                    type="number"
                                                    value={item.vat_rate}
                                                    disabled={isSaving || isLinesSaving}
                                                    onChange={(event) =>
                                                        updateLineItem(index, 'vat_rate', event.target.value)
                                                    }
                                                    onBlur={saveLineItemsOnUnitPriceBlur}
                                                    placeholder={t('documents.admin_show.extraction.percent_placeholder')}
                                                    className="w-full min-w-[7rem]"
                                                />
                                            )
                                        ) : (
                                            <span className="text-xs tabular-nums text-foreground/90">
                                                {item.vat_rate.trim() === ''
                                                    ? '—'
                                                    : vatRateLabel(vatRates, item.vat_rate)}
                                            </span>
                                        )}
                                    </TableCell>
                                    <TableCell className="min-w-[7.5rem]">
                                        {canEditExtraction ? (
                                            <Input
                                                type="number"
                                                step="0.01"
                                                value={item.vat_amount}
                                                disabled={isSaving || isLinesSaving}
                                                onChange={(event) =>
                                                    updateLineItem(index, 'vat_amount', event.target.value)
                                                }
                                                onBlur={() => {
                                                    roundLineItemMoneyFieldOnBlur(index, 'vat_amount');
                                                    saveLineItemsOnUnitPriceBlur();
                                                }}
                                                className="w-full min-w-[6.5rem]"
                                            />
                                        ) : (
                                            <span className="text-xs tabular-nums text-foreground/90">
                                                {item.vat_amount.trim() === ''
                                                    ? '—'
                                                    : formatDisplayMoney(item.vat_amount)}
                                            </span>
                                        )}
                                    </TableCell>
                                    <TableCell className="min-w-[8rem]">
                                        <Input
                                            type="number"
                                            value={formatLineGrossTotal(item)}
                                            disabled
                                            readOnly
                                            className="w-full min-w-[7rem] bg-muted/40"
                                        />
                                    </TableCell>
                                    {canEditExtraction ? (
                                        <TableCell className="text-right">
                                            <IconButton
                                                color="danger"
                                                size="xs"
                                                icon="solar:trash-bin-minimalistic-bold-duotone"
                                                disabled={isSaving || isLinesSaving}
                                                onClick={() => removeLineItem(index)}
                                                aria-label={t('documents.admin_show.extraction.delete_line_aria')}
                                            >
                                            </IconButton>
                                        </TableCell>
                                    ) : null}
                                </TableRow>
                            ))}
                        </TableBody>
                    </Table>
                ) : (
                    <p className="text-muted-foreground">{t('documents.admin_show.extraction.empty_lines')}</p>
                )}
                {canEditExtraction ? (
                    <Button type="button" variant="outline" onClick={addLineItem} disabled={isSaving || isLinesSaving}>
                        <Plus className="mr-2 h-4 w-4" />
                        {isLinesSaving ? t('documents.admin_show.extraction.lines_saving') : t('documents.admin_show.extraction.add_line')}
                    </Button>
                ) : null}
            </CardContent>
        </Card>
    );

    if (preserveOffscreen) {
        return (
            <div
                className="pointer-events-none absolute left-0 top-0 -z-10 h-px w-px overflow-hidden opacity-0"
                aria-hidden
            >
                <div className="grid w-[960px] grid-cols-2 gap-4 p-2">
                    {renderDetailsCard()}
                    {renderProductsCard()}
                </div>
            </div>
        );
    }

    if (layout === 'details') {
        return <div className="min-h-0">{renderDetailsCard()}</div>;
    }

    if (layout === 'products') {
        return <div className="min-h-0">{renderProductsCard()}</div>;
    }

    return (
        <div className="grid min-h-0 grid-cols-1 gap-4 lg:grid-cols-2 lg:items-start lg:gap-5">
            {renderDetailsCard()}
            {renderProductsCard()}
        </div>
    );
}

function FieldInput({
    label,
    value,
    onChange,
    disabled,
    type = 'text',
}: {
    label: string;
    value: string;
    onChange: (value: string) => void;
    disabled: boolean;
    type?: 'text' | 'number';
}) {
    return (
        <div className="space-y-1.5">
            <Label>{label}</Label>
            <Input type={type} value={value} disabled={disabled} onChange={(event) => onChange(event.target.value)} />
        </div>
    );
}

function vatRateLabel(
    vatRates: Array<{ code: string; name: string; rate_percent: string }>,
    rate: string,
): string {
    const row = vatRates.find((r) => r.rate_percent === rate);

    return row ? `${row.name} (${row.rate_percent}%)` : `${rate}%`;
}

function buildFormFromData(
    data: ExtractionData | null,
    vatRates: Array<{ code: string; name: string; rate_percent: string }>,
): ExtractionForm {
    const built: ExtractionForm = {
        document_type: toText(data?.document_type),
        issuer_name: toText(data?.issuer_name),
        issuer_identifier: toText(data?.issuer_identifier),
        issuer_vat_number: toText(data?.issuer_vat_number),
        customer_name: toText(data?.customer_name),
        customer_identifier: toText(data?.customer_identifier),
        customer_vat_number: toText(data?.customer_vat_number),
        document_direction: data?.document_direction ?? '',
        direction_reason: toText(data?.direction_reason),
        document_number: toText(data?.document_number),
        issue_date: toText(data?.issue_date),
        due_date: toText(data?.due_date),
        currency: toText(data?.currency),
        total_amount: toSummaryMoneyText(data?.total_amount),
        discount_amount: toSummaryMoneyText(data?.discount_amount),
        discount_percent: toText(data?.discount_percent),
        vat_amount: toSummaryMoneyText(data?.vat_amount),
        notes: toText(data?.notes),
        confidence: toText(data?.confidence),
        line_items:
            data?.line_items?.map((line) => {
                let item: LineItemForm = {
                    description: toText(line.description),
                    chart_of_account_code: toText(line.chart_of_account_code),
                    vat_rate: normalizeVatRateValue(vatRates, line.vat_rate),
                    vat_amount: toMoneyText(line.vat_amount),
                    quantity: toText(line.quantity),
                    discount_percent: toText(line.discount_percent),
                    unit_price: toMoneyText(line.unit_price),
                    line_total: toMoneyText(line.line_total),
                };

                item = applyLineProductDiscount(item);

                const documentCurrency = toText(data?.currency);
                item = reconcileValoareStyleLineAmounts(item, documentCurrency);

                if (item.line_total.trim() === '') {
                    item = recalculateLineItemTotals(item, 'quantity', documentCurrency);
                }

                if (item.vat_amount.trim() === '') {
                    item = recalculateLineItemTotals(item, 'vat_rate', documentCurrency);
                }

                return item;
            }) ?? [],
    };

    return applyDocumentTotalsFromLineItems(built);
}

function toText(value: unknown): string {
    if (value === null || value === undefined) {
        return '';
    }

    if (typeof value === 'number') {
        return String(value);
    }

    if (typeof value === 'string') {
        return value;
    }

    return '';
}

function recalculateDocumentTotalsFromLineItems(
    lineItems: LineItemForm[],
): Pick<ExtractionForm, 'total_amount' | 'vat_amount'> {
    if (lineItems.length === 0) {
        return { total_amount: '', vat_amount: '' };
    }

    let netSum = 0;
    let vatSum = 0;
    let hasNet = false;
    let hasVat = false;

    for (const line of lineItems) {
        const lineNet = parseNullableNumber(line.line_total);
        const lineVat = parseNullableNumber(line.vat_amount);

        if (lineNet !== null) {
            netSum += lineNet;
            hasNet = true;
        }

        if (lineVat !== null) {
            vatSum += lineVat;
            hasVat = true;
        }
    }

    return {
        total_amount: hasNet ? formatDisplayMoney(netSum + (hasVat ? vatSum : 0)) : '',
        vat_amount: hasVat ? formatDisplayMoney(vatSum) : '',
    };
}

function applyDocumentTotalsFromLineItems(form: ExtractionForm): ExtractionForm {
    return {
        ...form,
        ...recalculateDocumentTotalsFromLineItems(form.line_items),
    };
}

function toMoneyText(value: unknown): string {
    if (value === null || value === undefined || value === '') {
        return '';
    }

    const parsed = typeof value === 'number'
        ? value
        : Number(String(value).trim().replace(',', '.'));

    if (Number.isNaN(parsed)) {
        return toText(value);
    }

    const decimals = decimalPlacesFromValue(
        typeof value === 'string' ? value : parsed,
    );

    return formatCalculatedMoney(parsed, decimals);
}

function toSummaryMoneyText(value: unknown): string {
    if (value === null || value === undefined || value === '') {
        return '';
    }

    const parsed = typeof value === 'number'
        ? value
        : Number(String(value).trim().replace(',', '.'));

    if (Number.isNaN(parsed)) {
        return toText(value);
    }

    return formatDisplayMoney(parsed);
}

function formatLineGrossTotal(item: LineItemForm): string {
    const net = parseNullableNumber(item.line_total);
    const vat = parseNullableNumber(item.vat_amount);

    if (net === null && vat === null) {
        return '';
    }

    return formatDisplayMoney((net ?? 0) + (vat ?? 0));
}

function computeLineVatAmount(
    net: number | null,
    ratePercent: number | null,
    decimals: number,
): number | null {
    if (net === null || ratePercent === null) {
        return null;
    }

    if (ratePercent <= 0) {
        return 0;
    }

    return roundToDecimals((net * ratePercent) / 100, decimals);
}

function amountsClose(left: number | null, right: number | null, tolerance = 0.11): boolean {
    if (left === null || right === null) {
        return false;
    }

    return Math.abs(left - right) <= tolerance;
}

function inferNetFromVat(
    vatAmount: number | null,
    vatRate: number | null,
    decimals: number,
): number | null {
    if (vatAmount === null || vatRate === null || vatRate <= 0) {
        return null;
    }

    return roundToDecimals(vatAmount / (vatRate / 100), decimals);
}

/** Digi-style invoices: "Valoare" is line net, often mistaken for unit_price by AI. */
function reconcileForeignCurrencyUnitPrice(item: LineItemForm): LineItemForm {
    const decimals = resolveLineCalculationDecimals(item);
    const quantity = parseNullableNumber(item.quantity);
    let unitPrice = parseNullableNumber(item.unit_price);
    const lineTotal = parseNullableNumber(item.line_total);

    if (quantity === null || quantity === 0 || unitPrice === null || lineTotal === null) {
        return item;
    }

    const extendedAmount = Math.abs(quantity * unitPrice);
    const lineAbs = Math.abs(lineTotal);

    if (amountsClose(extendedAmount, lineAbs) || lineAbs === 0) {
        return item;
    }

    if (extendedAmount <= lineAbs * 1.15) {
        return item;
    }

    const sign = lineTotal < 0 ? -1 : 1;
    unitPrice = roundToDecimals((sign * lineAbs) / Math.abs(quantity), decimals);

    return {
        ...item,
        unit_price: formatCalculatedMoney(unitPrice, decimals),
    };
}

function reconcileValoareStyleLineAmounts(item: LineItemForm, documentCurrency = ''): LineItemForm {
    const decimals = resolveLineCalculationDecimals(item);
    const quantity = parseNullableNumber(item.quantity);
    let unitPrice = parseNullableNumber(item.unit_price);
    let lineTotal = parseNullableNumber(item.line_total);
    let vatRate = parseNullableNumber(item.vat_rate);
    let vatAmount = parseNullableNumber(item.vat_amount);

    if (quantity === null || quantity <= 1) {
        return item;
    }

    let adjusted = false;
    const impliedNet = inferNetFromVat(vatAmount, vatRate, decimals);

    if (unitPrice !== null && amountsClose(impliedNet, unitPrice) && !amountsClose(unitPrice * quantity, impliedNet)) {
        lineTotal = unitPrice;
        unitPrice = roundToDecimals(unitPrice / quantity, decimals);
        adjusted = true;
    } else if (
        unitPrice !== null
        && lineTotal !== null
        && amountsClose(unitPrice, lineTotal)
        && !amountsClose(unitPrice * quantity, lineTotal)
    ) {
        unitPrice = roundToDecimals(lineTotal / quantity, decimals);
        adjusted = true;
    } else if (
        unitPrice !== null
        && lineTotal !== null
        && vatRate !== null
        && vatAmount !== null
        && amountsClose(lineTotal, unitPrice * quantity)
        && !amountsClose(unitPrice, lineTotal)
        && amountsClose(vatAmount / quantity, computeLineVatAmount(unitPrice, vatRate, decimals))
        && !amountsClose(vatAmount, computeLineVatAmount(lineTotal, vatRate, decimals), 0.05)
    ) {
        lineTotal = unitPrice;
        unitPrice = roundToDecimals(unitPrice / quantity, decimals);
        adjusted = true;
    }

    let result: LineItemForm = {
        ...item,
        unit_price: unitPrice !== null ? formatCalculatedMoney(unitPrice, decimals) : item.unit_price,
        line_total: lineTotal !== null ? formatCalculatedMoney(lineTotal, decimals) : item.line_total,
        vat_amount: vatAmount !== null ? formatCalculatedMoney(vatAmount, decimals) : item.vat_amount,
    };

    if (documentCurrency.toUpperCase() === 'RON') {
        const beforeForeign = result.unit_price;
        result = reconcileForeignCurrencyUnitPrice(result);
        if (result.unit_price !== beforeForeign) {
            adjusted = true;
        }
    }

    if (adjusted) {
        lineTotal = parseNullableNumber(result.line_total);
        vatRate = parseNullableNumber(result.vat_rate);
        vatAmount = parseNullableNumber(result.vat_amount);
        if (lineTotal !== null && vatRate !== null) {
            const expectedVat = computeLineVatAmount(lineTotal, vatRate, decimals);
            if (expectedVat !== null && !amountsClose(vatAmount, expectedVat)) {
                result = { ...result, vat_amount: formatCalculatedMoney(expectedVat, decimals) };
            }
        }
    }

    return result;
}

function recalculateLineItemTotals(
    item: LineItemForm,
    changedKey: keyof LineItemForm,
    documentCurrency = '',
    finalizeLine = false,
): LineItemForm {
    const deferLineHeuristics =
        !finalizeLine && (changedKey === 'unit_price' || changedKey === 'quantity');

    const updated: LineItemForm = deferLineHeuristics
        ? { ...item }
        : reconcileValoareStyleLineAmounts({ ...item }, documentCurrency);

    const decimals = resolveLineCalculationDecimals(updated);
    const quantity = parseNullableNumber(updated.quantity);
    const unitPrice = parseNullableNumber(updated.unit_price);
    let net = parseNullableNumber(updated.line_total);
    const rate = parseNullableNumber(updated.vat_rate);

    const unitPriceInputComplete =
        changedKey !== 'unit_price' || !isIncompleteDecimalInput(updated.unit_price);

    if (
        (changedKey === 'quantity' || changedKey === 'unit_price')
        && unitPriceInputComplete
    ) {
        if (quantity !== null && unitPrice !== null) {
            net = roundToDecimals(quantity * unitPrice, decimals);
            updated.line_total = formatCalculatedMoney(net, decimals);
        }
    }

    if (changedKey !== 'vat_amount' && unitPriceInputComplete) {
        const vat = computeLineVatAmount(net, rate, decimals);
        if (vat !== null) {
            updated.vat_amount = formatCalculatedMoney(vat, decimals);
        } else if (
            changedKey === 'vat_rate'
            || changedKey === 'quantity'
            || changedKey === 'unit_price'
        ) {
            updated.vat_amount = '';
        }
    }

    if (deferLineHeuristics) {
        return updated;
    }

    return applyLineProductDiscount(updated);
}

function applyLineProductDiscount(item: LineItemForm): LineItemForm {
    const decimals = resolveLineCalculationDecimals(item);
    const quantity = parseNullableNumber(item.quantity);
    const unitPrice = parseNullableNumber(item.unit_price);
    const discountPercent = parseNullableNumber(item.discount_percent);
    const lineTotal = parseNullableNumber(item.line_total);

    if (discountPercent === null || discountPercent <= 0 || quantity === null || quantity === 0 || unitPrice === null) {
        return item;
    }

    const grossLine = roundToDecimals(Math.abs(quantity) * Math.abs(unitPrice), decimals);
    const expectedNet = roundToDecimals(grossLine * (1 - discountPercent / 100), decimals);

    if (
        lineTotal === null
        || amountsClose(lineTotal, grossLine)
        || (quantity === 1 && amountsClose(lineTotal, unitPrice))
        || (lineTotal > expectedNet + 0.11)
    ) {
        return {
            ...item,
            line_total: formatCalculatedMoney(expectedNet, decimals),
            unit_price: formatCalculatedMoney(expectedNet / quantity, decimals),
        };
    }

    if (lineTotal !== null && amountsClose(lineTotal, expectedNet)) {
        return {
            ...item,
            unit_price: formatCalculatedMoney(Math.abs(lineTotal) / Math.abs(quantity), decimals),
        };
    }

    return item;
}

function parseNullableNumber(value: string): number | null {
    const trimmed = value.trim();

    if (trimmed === '') {
        return null;
    }

    const parsed = Number(trimmed);

    return Number.isNaN(parsed) ? null : parsed;
}

function serializeFormData(form: ExtractionForm): StructuredAccountingExtractionData {
    return {
        document_type: emptyToNull(form.document_type),
        issuer_name: emptyToNull(form.issuer_name),
        issuer_identifier: emptyToNull(form.issuer_identifier),
        issuer_vat_number: emptyToNull(form.issuer_vat_number),
        customer_name: emptyToNull(form.customer_name),
        customer_identifier: emptyToNull(form.customer_identifier),
        customer_vat_number: emptyToNull(form.customer_vat_number),
        document_direction: form.document_direction === '' ? null : form.document_direction,
        direction_reason: emptyToNull(form.direction_reason),
        document_number: emptyToNull(form.document_number),
        issue_date: emptyToNull(form.issue_date),
        due_date: emptyToNull(form.due_date),
        currency: emptyToNull(form.currency),
        total_amount: parseNullableNumber(form.total_amount),
        discount_amount: parseNullableNumber(form.discount_amount),
        discount_percent: parseNullableNumber(form.discount_percent),
        vat_amount: parseNullableNumber(form.vat_amount),
        line_items: form.line_items.map((line) => ({
            description: emptyToNull(line.description),
            chart_of_account_code: emptyToNull(line.chart_of_account_code),
            quantity: parseNullableNumber(line.quantity),
            unit_price: parseNullableNumber(line.unit_price),
            line_total: parseNullableNumber(line.line_total),
            vat_rate: parseNullableNumber(line.vat_rate),
            vat_amount: parseNullableNumber(line.vat_amount),
            discount_percent: parseNullableNumber(line.discount_percent),
        })),
        notes: emptyToNull(form.notes),
        confidence: parseNullableNumber(form.confidence),
    };
}

function emptyToNull(value: string): string | null {
    const trimmed = value.trim();

    return trimmed === '' ? null : trimmed;
}

function setField<K extends keyof ExtractionForm>(
    setForm: Dispatch<SetStateAction<ExtractionForm>>,
    key: K,
    value: ExtractionForm[K],
) {
    setForm((current) => ({
        ...current,
        [key]: value,
    }));
}
