'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import * as PopoverPrimitive from '@radix-ui/react-popover';
import { LuRefreshCw, LuEllipsisVertical } from 'react-icons/lu';
import { format_extracted_field, prettify_key } from '../utils/format_extracted_field.js';
function resolve_classification(item, classification_results) {
    return item.classification_result ?? classification_results?.get(item.content_id);
}
function get_renderable_entries(fields) {
    if (!fields || typeof fields !== 'object')
        return [];
    return Object.entries(fields).filter(([, v]) => v !== null && v !== undefined && v !== '');
}
function is_plain_object(v) {
    return typeof v === 'object' && v !== null && !Array.isArray(v);
}
function is_array_of_objects(v) {
    return Array.isArray(v) && v.length > 0 && v.every(is_plain_object);
}
function is_array_of_scalars(v) {
    return Array.isArray(v) && v.length > 0 && v.every(el => el === null || ['string', 'number', 'boolean'].includes(typeof el));
}
function partition_entries(entries, field_index) {
    const scalars = [];
    const tables = [];
    const lists = [];
    for (const [k, v] of entries) {
        const hint = field_index.get(k);
        // Path 1: declared array_of object
        if (hint?.array_of && hint.array_of.type === 'object') {
            if (Array.isArray(v) && v.length === 0) {
                // Empty array → drop entirely
                continue;
            }
            if (is_array_of_objects(v)) {
                const columns = hint.array_of.shape.map(s => ({
                    key: s.key,
                    label: s.label ?? prettify_key(s.key),
                    type: s.type,
                }));
                tables.push({
                    key: k,
                    label: hint.label ?? prettify_key(k),
                    columns,
                    rows: v,
                });
                continue;
            }
            // Declared mismatch → strict fallback (push as scalar so existing JSON
            // formatter renders it visibly under the field's label).
            scalars.push([k, v]);
            continue;
        }
        // Path 2 + 3 merged: declared-scalar OR undeclared. If the value is
        // Array<object>, render as an inferred-column table regardless of whether
        // the field is declared as a plain scalar in expected_fields. (Strict
        // mismatch for declared `array_of: object` is already handled in Path 1
        // above.) This means doctype configs that haven't yet adopted `array_of`
        // still get table rendering when the LLM returns objects, and we never
        // silently downgrade structured data to a JSON-string fallback.
        if (is_array_of_objects(v)) {
            // Infer columns = union of keys across rows, in first-seen order
            const seen = new Set();
            const ordered_keys = [];
            for (const row of v) {
                for (const rk of Object.keys(row)) {
                    if (!seen.has(rk)) {
                        seen.add(rk);
                        ordered_keys.push(rk);
                    }
                }
            }
            const columns = ordered_keys.map(rk => ({
                key: rk,
                label: prettify_key(rk),
            }));
            tables.push({
                key: k,
                label: hint?.label ?? prettify_key(k),
                columns,
                rows: v,
            });
            continue;
        }
        if (is_array_of_scalars(v)) {
            lists.push({
                key: k,
                label: hint?.label ?? prettify_key(k),
                items: v,
            });
            continue;
        }
        // Anything else (scalar, empty array, mixed array) → scalar path
        scalars.push([k, v]);
    }
    return { scalars, tables, lists };
}
// ============================================================================
// Component
// ============================================================================
export function ExtractedFieldsInline(props) {
    const { item, classification_results, document_types, locale, currency_code, truncate_chars, role, on_request_reextraction } = props;
    const cr = resolve_classification(item, classification_results);
    if (!cr)
        return null;
    const entries = get_renderable_entries(cr.extracted_fields);
    const document_date = cr.document_date && cr.document_date.trim() ? cr.document_date.trim() : '';
    const confidence_clamped = typeof cr.confidence === 'number'
        ? Math.max(0, Math.min(1, cr.confidence))
        : 0;
    const has_confidence = typeof cr.confidence === 'number' && cr.confidence > 0;
    const matched_doctype = document_types?.find(dt => dt.type_id === cr.document_type);
    const field_index = new Map((matched_doctype?.expected_fields ?? []).map(f => [f.key, f]));
    const partitioned = partition_entries(entries, field_index);
    const date_display = document_date
        ? format_extracted_field(document_date, { key: 'document_date', type_hint: 'date', locale }).display
        : '';
    const can_reextract = role === 'agent' && !!on_request_reextraction;
    const [is_loading, set_is_loading] = React.useState(false);
    async function handle_reextract(scope) {
        if (is_loading || !on_request_reextraction)
            return;
        set_is_loading(true);
        try {
            await Promise.resolve(on_request_reextraction(item.content_id, scope));
        }
        finally {
            set_is_loading(false);
        }
    }
    const is_replaced = !!item.replaced_by_content_id;
    const wrapper_class = is_replaced
        ? 'mt-1 pl-7 text-[12px] leading-relaxed opacity-40'
        : 'mt-1 pl-7 text-[12px] leading-relaxed';
    const has_meta = !!document_date || has_confidence;
    // Confidence alone is not sufficient to render — require a date or at least one field.
    const has_content = !!document_date
        || can_reextract
        || partitioned.scalars.length > 0
        || partitioned.tables.length > 0
        || partitioned.lists.length > 0;
    if (!has_content)
        return null;
    function is_numeric(t) {
        return t === 'number' || t === 'currency';
    }
    const dim_class = is_loading ? 'opacity-50 pointer-events-none' : '';
    return (_jsxs("div", { className: wrapper_class, children: [(has_meta || can_reextract) && (_jsxs("div", { className: "text-[#94A3B8] mb-0.5 flex items-center", children: [_jsxs("div", { className: `flex-1 min-w-0 ${dim_class}`, children: [document_date && _jsxs("span", { children: [_jsx("span", { className: "font-semibold text-[#64748B]", children: "Document date: " }), _jsx("span", { className: "text-[#475569]", children: date_display })] }), document_date && has_confidence && _jsx("span", { className: "mx-1.5 text-[#CBD5E1]", children: "\u00B7" }), has_confidence && _jsxs("span", { children: [_jsx("span", { className: "font-semibold text-[#64748B]", children: "Confidence: " }), _jsx("span", { className: "text-[#475569]", children: `${Math.round(confidence_clamped * 100)}%` })] })] }), can_reextract && (_jsxs("div", { className: "ml-2 flex items-center gap-1", children: [_jsx("button", { type: "button", onClick: () => handle_reextract('classification'), disabled: is_loading, className: "text-[#94A3B8] hover:text-[#475569] disabled:opacity-50", title: "Re-extract fields", children: _jsx(LuRefreshCw, { className: `w-3 h-3 ${is_loading ? 'animate-spin' : ''}` }) }), _jsxs(PopoverPrimitive.Root, { modal: true, children: [_jsx(PopoverPrimitive.Trigger, { asChild: true, children: _jsx("button", { type: "button", disabled: is_loading, className: "text-[#94A3B8] hover:text-[#475569] disabled:opacity-50", title: "More re-extract options", children: _jsx(LuEllipsisVertical, { className: "w-3 h-3" }) }) }), _jsx(PopoverPrimitive.Portal, { children: _jsxs(PopoverPrimitive.Content, { align: "end", sideOffset: 4, collisionPadding: 16, className: "z-50 min-w-[180px] rounded-md border border-[#E2E8F0] bg-white py-1 shadow-md text-[12px]", style: { backgroundColor: 'hsl(var(--popover, 0 0% 100%))' }, children: [_jsx("button", { type: "button", onClick: () => handle_reextract('classification'), disabled: is_loading, className: "block w-full text-left px-3 py-1.5 text-[#334155] hover:bg-[#F1F5F9] disabled:opacity-50", children: "Re-extract fields" }), _jsx("button", { type: "button", onClick: () => handle_reextract('full'), disabled: is_loading, className: "block w-full text-left px-3 py-1.5 text-[#334155] hover:bg-[#F1F5F9] disabled:opacity-50", children: "Re-run full analysis" })] }) })] })] }))] })), _jsxs("div", { "data-content-region": true, className: dim_class, children: [partitioned.scalars.length > 0 && (_jsx("div", { className: "text-[#64748B]", children: partitioned.scalars.map(([k, v], i) => {
                            const hint = field_index.get(k);
                            const formatted = format_extracted_field(v, {
                                key: k,
                                type_hint: hint?.type,
                                locale,
                                currency_code,
                                truncate_chars,
                            });
                            const label = hint?.label ?? prettify_key(k);
                            return (_jsxs("span", { children: [i > 0 && _jsx("span", { className: "mx-1.5 text-[#CBD5E1]", children: "\u00B7" }), _jsxs("span", { className: "font-semibold text-[#64748B]", children: [label, ": "] }), _jsx("span", { className: "text-[#334155]", title: formatted.title, children: formatted.display })] }, k));
                        }) })), partitioned.tables.map(t => (_jsxs("div", { className: "mt-2", children: [_jsx("div", { className: "text-[#475569] font-medium mb-1", children: t.label }), _jsx("div", { className: "overflow-x-auto rounded-md border border-[#E2E8F0] bg-white", children: _jsxs("table", { className: "w-full text-[12px] border-collapse", children: [_jsx("caption", { className: "sr-only", children: t.label }), _jsx("thead", { children: _jsx("tr", { className: "bg-[#F8FAFC] text-[#64748B]", children: t.columns.map(c => (_jsx("th", { scope: "col", className: `px-2 py-1.5 font-medium border-b border-[#E2E8F0] ${is_numeric(c.type) ? 'text-right' : 'text-left'}`, children: c.label }, c.key))) }) }), _jsx("tbody", { children: t.rows.map((row, i) => (_jsx("tr", { className: "text-[#334155] even:bg-[#FAFBFC]", children: t.columns.map(c => {
                                                    const cell = format_extracted_field(row[c.key], {
                                                        key: c.key,
                                                        type_hint: c.type,
                                                        locale,
                                                        currency_code,
                                                        truncate_chars,
                                                    });
                                                    return (_jsx("td", { className: `px-2 py-1 align-top border-t border-[#F1F5F9] first:border-t-0 ${is_numeric(c.type) ? 'text-right tabular-nums' : ''}`, title: cell.title, children: cell.display }, c.key));
                                                }) }, i))) })] }) })] }, t.key))), partitioned.lists.map(l => (_jsxs("div", { className: "mt-1.5", children: [_jsx("div", { className: "text-[#94A3B8] mb-0.5", children: l.label }), _jsx("ul", { className: "list-disc list-inside text-[#334155] space-y-0.5", children: l.items.map((it, i) => {
                                    const cell = format_extracted_field(it, { key: l.key, locale, currency_code, truncate_chars });
                                    return (_jsx("li", { title: cell.title, children: cell.display }, i));
                                }) })] }, l.key)))] })] }));
}
//# sourceMappingURL=extracted_fields_inline.js.map