'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
 * Import/Export dialog for the Field Library
 * Supports: file upload, paste JSON, clipboard copy, file download
 */
import { useState, useCallback, useRef } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from '../../shared/dialog/index.js';
import { useFieldLibrary } from '../context.js';
import { export_to_json, validate_import, download_json, } from '../utils/import_export.js';
import { stringify_element } from '../utils/element_utils.js';
import { cn } from '../../../utils/cn.js';
import { HiDownload, HiUpload, HiClipboardCopy, HiCheck, HiExclamation, HiX, } from 'react-icons/hi';
export function ImportExportDialog({ open, on_close, initial_mode = 'import', export_all = false, }) {
    const { elements: { elements, create_element, update_element, fetch_elements }, filtered_elements, } = useFieldLibrary();
    const [mode, set_mode] = useState(initial_mode);
    const [import_source, set_import_source] = useState('file');
    const [paste_text, set_paste_text] = useState('');
    const [validation, set_validation] = useState(null);
    const [importing, set_importing] = useState(false);
    const [import_result, set_import_result] = useState(null);
    const [copied, set_copied] = useState(false);
    const [overwrite_duplicates, set_overwrite_duplicates] = useState(false);
    const file_input_ref = useRef(null);
    // Reset state when dialog opens/closes or mode changes
    const reset = useCallback(() => {
        set_paste_text('');
        set_validation(null);
        set_import_result(null);
        set_copied(false);
        set_overwrite_duplicates(false);
    }, []);
    const handle_mode_change = useCallback((new_mode) => {
        set_mode(new_mode);
        reset();
    }, [reset]);
    // === EXPORT ===
    const export_source = export_all
        ? elements
        : (filtered_elements.length > 0 ? filtered_elements : elements);
    const export_json = export_to_json(mode === 'export' ? export_source : []);
    const handle_copy = useCallback(async () => {
        const source = export_all ? elements : (filtered_elements.length > 0 ? filtered_elements : elements);
        const json = export_to_json(source);
        try {
            await navigator.clipboard.writeText(json);
            set_copied(true);
            setTimeout(() => set_copied(false), 2000);
        }
        catch {
            // Fallback: select textarea content
        }
    }, [elements, filtered_elements, export_all]);
    const handle_download = useCallback(() => {
        const source = export_all ? elements : (filtered_elements.length > 0 ? filtered_elements : elements);
        const json = export_to_json(source);
        const count = source.length;
        download_json(json, `field_library_${count}_elements.json`);
    }, [elements, filtered_elements, export_all]);
    // === IMPORT ===
    const handle_validate = useCallback((raw_text) => {
        try {
            const parsed = JSON.parse(raw_text);
            const result = validate_import(parsed, elements);
            set_validation(result);
        }
        catch (err) {
            const msg = err instanceof Error ? err.message : 'parse error';
            // Extract position from error message (e.g. "at position 8" or "line 1 column 9")
            let snippet_parts;
            const pos_match = msg.match(/position\s+(\d+)/);
            if (pos_match) {
                const pos = parseInt(pos_match[1], 10);
                const start = Math.max(0, pos - 20);
                const end = Math.min(raw_text.length, pos + 20);
                snippet_parts = {
                    before: (start > 0 ? '...' : '') + raw_text.slice(start, pos),
                    char: raw_text[pos] ?? '\u2423', // open box for EOF
                    after: raw_text.slice(pos + 1, end) + (end < raw_text.length ? '...' : ''),
                };
            }
            set_validation({
                valid: false,
                elements: [],
                errors: [{
                        index: -1,
                        field: 'json',
                        message: `Invalid JSON: ${msg}`,
                        snippet_parts,
                    }],
                warnings: [],
                duplicates: [],
            });
        }
    }, [elements]);
    const handle_file_select = useCallback(async (e) => {
        const file = e.target.files?.[0];
        if (!file)
            return;
        try {
            const text = await file.text();
            set_paste_text(text);
            handle_validate(text);
        }
        catch {
            set_validation({
                valid: false,
                elements: [],
                errors: [{ index: -1, field: 'file', message: 'Failed to read file' }],
                warnings: [],
                duplicates: [],
            });
        }
        // Reset file input so same file can be selected again
        if (file_input_ref.current) {
            file_input_ref.current.value = '';
        }
    }, [handle_validate]);
    const handle_paste_validate = useCallback(() => {
        if (!paste_text.trim()) {
            set_validation(null);
            return;
        }
        handle_validate(paste_text);
    }, [paste_text, handle_validate]);
    const handle_import = useCallback(async () => {
        if (!validation || !validation.valid || validation.elements.length === 0)
            return;
        set_importing(true);
        let success = 0;
        let failed = 0;
        const items_to_import = overwrite_duplicates
            ? validation.elements
            : validation.elements.filter(e => !validation.duplicates.includes(`${e.area}.${e.key}`));
        for (const item of items_to_import) {
            const element_json = typeof item.element === 'string'
                ? item.element
                : stringify_element(item.element);
            const full_key = `${item.area}.${item.key}`;
            const is_duplicate = validation.duplicates.includes(full_key);
            let result;
            if (is_duplicate && overwrite_duplicates) {
                // Find existing element's DB id and update it
                const existing = elements.find(e => e.area === item.area && e.key === item.key);
                if (existing) {
                    result = await update_element(existing.id, { element: element_json });
                }
            }
            else {
                result = await create_element(item.area, item.key, element_json);
            }
            if (result) {
                success++;
            }
            else {
                failed++;
            }
        }
        set_import_result({ success, failed });
        set_importing(false);
        // Refresh the elements list
        if (success > 0) {
            await fetch_elements();
        }
    }, [validation, overwrite_duplicates, elements, create_element, update_element, fetch_elements]);
    const export_count = export_all
        ? elements.length
        : (filtered_elements.length > 0 ? filtered_elements.length : elements.length);
    const importable_count = validation
        ? (overwrite_duplicates
            ? validation.elements.length
            : validation.elements.length - validation.duplicates.length)
        : 0;
    return (_jsx(Dialog, { open: open, onOpenChange: (o) => { if (!o) {
            on_close();
            reset();
        } }, children: _jsxs(DialogContent, { className: "max-w-2xl max-h-[80vh] flex flex-col", prevent_close_on_outside_click: true, children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Import / Export Elements" }), _jsx(DialogDescription, { children: "Transfer field library elements via JSON" })] }), _jsxs("div", { className: "flex border rounded-md overflow-hidden w-fit", children: [_jsxs("button", { onClick: () => handle_mode_change('import'), className: cn('flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium transition-colors', mode === 'import'
                                ? 'bg-primary text-primary-foreground'
                                : 'hover:bg-muted text-muted-foreground'), children: [_jsx(HiUpload, { className: "h-4 w-4" }), "Import"] }), _jsxs("button", { onClick: () => handle_mode_change('export'), className: cn('flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium transition-colors', mode === 'export'
                                ? 'bg-primary text-primary-foreground'
                                : 'hover:bg-muted text-muted-foreground'), children: [_jsx(HiDownload, { className: "h-4 w-4" }), "Export"] })] }), mode === 'export' && (_jsxs("div", { className: "flex flex-col gap-3 min-h-0 flex-1", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: export_all
                                ? `Exporting all ${elements.length} element${elements.length !== 1 ? 's' : ''} (fields + groups)`
                                : filtered_elements.length > 0
                                    ? `Exporting ${filtered_elements.length} filtered element${filtered_elements.length !== 1 ? 's' : ''}`
                                    : `Exporting all ${elements.length} element${elements.length !== 1 ? 's' : ''}` }), _jsx("pre", { className: "flex-1 min-h-0 overflow-auto p-3 text-xs font-mono bg-muted/40 border rounded-md whitespace-pre-wrap break-words max-h-64", children: export_json }), _jsxs("div", { className: "flex items-center gap-2 justify-end", children: [_jsxs("button", { onClick: handle_copy, className: "flex items-center gap-1.5 px-3 py-1.5 text-sm border rounded-md hover:bg-muted transition-colors", children: [copied ? _jsx(HiCheck, { className: "h-4 w-4 text-green-600" }) : _jsx(HiClipboardCopy, { className: "h-4 w-4" }), copied ? 'Copied' : 'Copy to Clipboard'] }), _jsxs("button", { onClick: handle_download, disabled: export_count === 0, className: cn('flex items-center gap-1.5 px-3 py-1.5 text-sm text-primary-foreground bg-primary rounded-md hover:bg-primary/90 transition-colors', export_count === 0 && 'opacity-50 cursor-not-allowed'), children: [_jsx(HiDownload, { className: "h-4 w-4" }), "Download JSON"] })] })] })), mode === 'import' && (_jsxs("div", { className: "flex flex-col gap-3 min-h-0 flex-1", children: [_jsxs("div", { className: "flex gap-2", children: [_jsx("button", { onClick: () => { set_import_source('file'); set_validation(null); set_import_result(null); }, className: cn('px-3 py-1 text-sm rounded-md border transition-colors', import_source === 'file'
                                        ? 'border-primary bg-primary/5 text-primary'
                                        : 'hover:bg-muted text-muted-foreground'), children: "From File" }), _jsx("button", { onClick: () => { set_import_source('paste'); set_validation(null); set_import_result(null); }, className: cn('px-3 py-1 text-sm rounded-md border transition-colors', import_source === 'paste'
                                        ? 'border-primary bg-primary/5 text-primary'
                                        : 'hover:bg-muted text-muted-foreground'), children: "Paste JSON" })] }), import_source === 'file' && (_jsx("div", { children: _jsx("input", { ref: file_input_ref, type: "file", accept: ".json", onChange: handle_file_select, className: "block w-full text-sm border rounded-md file:mr-3 file:px-3 file:py-1.5 file:border-0 file:text-sm file:font-medium file:bg-primary file:text-primary-foreground hover:file:bg-primary/90 file:rounded-l-md file:cursor-pointer cursor-pointer" }) })), import_source === 'paste' && (_jsxs("div", { className: "space-y-2", children: [_jsx("textarea", { value: paste_text, onChange: (e) => { set_paste_text(e.target.value); set_validation(null); set_import_result(null); }, rows: 8, className: "w-full px-3 py-2 text-xs font-mono border rounded-md resize-y focus:outline-none focus:ring-2 focus:ring-primary/50", placeholder: '[\n  {\n    "area": "personal",\n    "key": "full_name",\n    "element": {\n      "id": "full_name",\n      "label": "Full Name",\n      "field_type": "field",\n      "component_type": "HazoCollabFormInputbox",\n      "value": ""\n    }\n  }\n]' }), _jsx("button", { onClick: handle_paste_validate, disabled: !paste_text.trim(), className: cn('flex items-center gap-1.5 px-3 py-1.5 text-sm border rounded-md hover:bg-muted transition-colors', !paste_text.trim() && 'opacity-50 cursor-not-allowed'), children: "Validate" })] })), validation && (_jsxs("div", { className: "space-y-2 overflow-auto max-h-48", children: [validation.errors.length > 0 && (_jsxs("div", { className: "p-3 border border-destructive/30 rounded-md bg-destructive/5 space-y-1", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-sm font-medium text-destructive", children: [_jsx(HiX, { className: "h-4 w-4 flex-shrink-0" }), validation.errors.length, " error", validation.errors.length !== 1 ? 's' : ''] }), validation.errors.map((err, i) => (_jsxs("div", { className: "text-xs text-destructive/80 ml-5", children: [err.index >= 0 ? `[${err.index}] ` : '', err.field, ": ", err.message, err.snippet_parts && (_jsxs("pre", { className: "mt-1 p-1.5 bg-destructive/10 rounded text-[11px] font-mono whitespace-pre-wrap break-all leading-relaxed", children: [err.snippet_parts.before, _jsx("span", { className: "bg-red-500 text-white rounded-sm px-0.5", children: err.snippet_parts.char }), err.snippet_parts.after] }))] }, i)))] })), validation.warnings.length > 0 && (_jsxs("div", { className: "p-3 border border-amber-500/30 rounded-md bg-amber-50 dark:bg-amber-900/10 space-y-1", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-sm font-medium text-amber-700 dark:text-amber-400", children: [_jsx(HiExclamation, { className: "h-4 w-4 flex-shrink-0" }), validation.warnings.length, " warning", validation.warnings.length !== 1 ? 's' : ''] }), validation.warnings.map((w, i) => (_jsx("div", { className: "text-xs text-amber-600 dark:text-amber-500 ml-5", children: w }, i)))] })), validation.duplicates.length > 0 && (_jsxs("div", { className: "p-3 border border-blue-500/30 rounded-md bg-blue-50 dark:bg-blue-900/10 space-y-2", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-sm font-medium text-blue-700 dark:text-blue-400", children: [_jsx(HiExclamation, { className: "h-4 w-4 flex-shrink-0" }), validation.duplicates.length, " element", validation.duplicates.length !== 1 ? 's' : '', " already exist"] }), _jsx("div", { className: "text-xs text-blue-600 dark:text-blue-500 ml-5 space-y-0.5", children: validation.duplicates.map((key, i) => (_jsx("div", { className: "font-mono", children: key }, i))) }), _jsxs("label", { className: "flex items-center gap-2 text-xs text-blue-700 dark:text-blue-400 ml-5 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: overwrite_duplicates, onChange: (e) => set_overwrite_duplicates(e.target.checked), className: "rounded" }), "Overwrite existing elements"] })] })), validation.valid && validation.elements.length > 0 && (_jsx("div", { className: "p-3 border border-green-500/30 rounded-md bg-green-50 dark:bg-green-900/10", children: _jsxs("div", { className: "flex items-center gap-1.5 text-sm font-medium text-green-700 dark:text-green-400", children: [_jsx(HiCheck, { className: "h-4 w-4 flex-shrink-0" }), validation.elements.length, " element", validation.elements.length !== 1 ? 's' : '', " ready to import", validation.duplicates.length > 0 && !overwrite_duplicates && (_jsxs("span", { className: "text-xs font-normal text-muted-foreground", children: ["(", importable_count, " new, ", validation.duplicates.length, " skipped)"] }))] }) }))] })), import_result && (_jsx("div", { className: cn('p-3 border rounded-md', import_result.failed > 0
                                ? 'border-amber-500/30 bg-amber-50 dark:bg-amber-900/10'
                                : 'border-green-500/30 bg-green-50 dark:bg-green-900/10'), children: _jsxs("div", { className: cn('flex items-center gap-1.5 text-sm font-medium', import_result.failed > 0
                                    ? 'text-amber-700 dark:text-amber-400'
                                    : 'text-green-700 dark:text-green-400'), children: [_jsx(HiCheck, { className: "h-4 w-4 flex-shrink-0" }), "Imported ", import_result.success, " element", import_result.success !== 1 ? 's' : '', import_result.failed > 0 && `, ${import_result.failed} failed`] }) })), validation && !import_result && (_jsx("div", { className: "flex justify-end", children: _jsxs("button", { onClick: handle_import, disabled: importing || importable_count === 0, className: cn('flex items-center gap-1.5 px-4 py-1.5 text-sm text-primary-foreground bg-primary rounded-md hover:bg-primary/90 transition-colors', (importing || importable_count === 0) && 'opacity-50 cursor-not-allowed'), children: [_jsx(HiUpload, { className: "h-4 w-4" }), importing ? 'Importing...' : `Import ${importable_count} Element${importable_count !== 1 ? 's' : ''}`] }) })), import_result && (_jsx("div", { className: "flex justify-end", children: _jsx("button", { onClick: () => { on_close(); reset(); }, className: "flex items-center gap-1.5 px-4 py-1.5 text-sm text-primary-foreground bg-primary rounded-md hover:bg-primary/90 transition-colors", children: "Done" }) }))] }))] }) }));
}
//# sourceMappingURL=import_export_dialog.js.map