'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/**
 * Left sidebar listing validation rules grouped by document type.
 */
import React, { useState, useCallback, useRef, useEffect } from 'react';
import { cn } from '../../../utils/cn.js';
import { EditorInput } from '../../shared/editor_theme/index.js';
import { useValidationRuleEditor } from '../context.js';
import { slugify } from '../../../utils/slugify.js';
import { LuSearch, LuPlus, LuChevronDown, LuChevronRight, LuShieldCheck, LuShieldOff, LuFileText, LuDownload, LuUpload, } from 'react-icons/lu';
export function RuleList({ className }) {
    const { rules_data, selected_id, set_selected_id, type_filter, set_type_filter, search_query, set_search_query, active_tab, set_active_tab, filtered_rules, read_only, } = useValidationRuleEditor();
    const [collapsed_types, set_collapsed_types] = useState(new Set());
    const file_input_ref = useRef(null);
    const [importing, set_importing] = useState(false);
    const [import_status, set_import_status] = useState(null);
    // Auto-clear import status after 4 s
    useEffect(() => {
        if (!import_status)
            return;
        const t = setTimeout(() => set_import_status(null), 4000);
        return () => clearTimeout(t);
    }, [import_status]);
    const handle_export = useCallback(() => {
        const exportable = rules_data.rules.map(({ id: _id, created_at: _ca, changed_at: _ch, scope_id: _sc, ...rest }) => rest);
        const blob = new Blob([JSON.stringify(exportable, null, 2)], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `validation-rules-${new Date().toISOString().slice(0, 10)}.json`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    }, [rules_data.rules]);
    const handle_import_change = useCallback(async (e) => {
        const file = e.target.files?.[0];
        if (!file)
            return;
        if (file_input_ref.current)
            file_input_ref.current.value = '';
        set_importing(true);
        set_import_status(null);
        try {
            const text = await file.text();
            const data = JSON.parse(text);
            if (!Array.isArray(data))
                throw new Error('Expected a JSON array');
            let imported = 0;
            let skipped = 0;
            for (const item of data) {
                const rule = item;
                if (!rule.name || !rule.document_type) {
                    skipped++;
                    continue;
                }
                let rule_id = rule.rule_id ?? slugify(rule.name);
                if (!rules_data.is_rule_id_unique(rule_id)) {
                    rule_id = `${rule_id}_${Date.now()}`;
                }
                const result = await rules_data.create_rule({
                    rule_id,
                    name: rule.name,
                    document_type: rule.document_type,
                    prompt: rule.prompt ?? '',
                    clarification_type: rule.clarification_type ?? 'none',
                    enabled: rule.enabled ?? true,
                    description: rule.description,
                    priority: rule.priority,
                    check_type: rule.check_type,
                    validation_type: rule.validation_type,
                    coverage: rule.coverage,
                    custom_issue_description: rule.custom_issue_description,
                    custom_action_description: rule.custom_action_description,
                    custom_response_options: rule.custom_response_options,
                    response_set_id: rule.response_set_id,
                });
                if (result)
                    imported++;
                else
                    skipped++;
            }
            set_import_status(`Imported ${imported}${skipped ? `, skipped ${skipped}` : ''}`);
        }
        catch {
            set_import_status('Import failed — invalid file');
        }
        finally {
            set_importing(false);
        }
    }, [rules_data]);
    // Group rules by document type
    const grouped = React.useMemo(() => {
        const groups = {};
        for (const rule of filtered_rules) {
            if (!groups[rule.document_type]) {
                groups[rule.document_type] = [];
            }
            groups[rule.document_type].push(rule);
        }
        return groups;
    }, [filtered_rules]);
    const toggle_collapse = useCallback((type) => {
        set_collapsed_types(prev => {
            const next = new Set(prev);
            if (next.has(type)) {
                next.delete(type);
            }
            else {
                next.add(type);
            }
            return next;
        });
    }, []);
    const handle_add_rule = useCallback(() => {
        set_selected_id('__new_rule');
    }, [set_selected_id]);
    const tab_items = [
        { id: 'all', label: 'All' },
        { id: 'enabled', label: 'Active' },
        { id: 'disabled', label: 'Inactive' },
    ];
    return (_jsxs("div", { className: cn('flex flex-col h-full border-r', className), children: [_jsxs("div", { className: "p-3 border-b space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-1", children: [_jsx("h3", { className: "text-sm font-semibold flex-1 min-w-0 truncate", children: "Validation Rules" }), _jsxs("div", { className: "flex items-center gap-1 flex-shrink-0", children: [_jsx("button", { type: "button", onClick: handle_export, disabled: rules_data.rules.length === 0, title: "Export rules as JSON", className: "inline-flex items-center justify-center h-6 w-6 rounded text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors disabled:opacity-40 disabled:cursor-not-allowed", children: _jsx(LuDownload, { className: "h-3.5 w-3.5" }) }), !read_only && (_jsxs(_Fragment, { children: [_jsx("input", { ref: file_input_ref, type: "file", accept: ".json,application/json", className: "hidden", onChange: handle_import_change }), _jsx("button", { type: "button", onClick: () => file_input_ref.current?.click(), disabled: importing, title: "Import rules from JSON", className: "inline-flex items-center justify-center h-6 w-6 rounded text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors disabled:opacity-40 disabled:cursor-not-allowed", children: _jsx(LuUpload, { className: "h-3.5 w-3.5" }) }), _jsxs("button", { type: "button", onClick: handle_add_rule, className: "inline-flex items-center gap-1 px-2 py-1 text-xs rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors", children: [_jsx(LuPlus, { className: "h-3 w-3" }), "Add"] })] }))] })] }), _jsx("div", { className: "flex gap-1 p-0.5 bg-muted/30 rounded-md", children: tab_items.map(tab => (_jsx("button", { type: "button", onClick: () => set_active_tab(tab.id), className: cn('flex-1 px-2 py-1 text-xs font-medium rounded transition-all', active_tab === tab.id
                                ? 'bg-background text-foreground shadow-sm'
                                : 'text-muted-foreground hover:text-foreground'), children: tab.label }, tab.id))) }), _jsxs("div", { className: "relative", children: [_jsx(LuSearch, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" }), _jsx(EditorInput, { value: search_query, onChange: (e) => set_search_query(e.target.value), placeholder: "Search rules...", className: "pl-8 h-8 text-xs", field_width: "full" })] }), rules_data.document_types.length > 1 && (_jsxs("select", { value: type_filter ?? '', onChange: (e) => set_type_filter(e.target.value || null), className: "w-full px-2 py-1 border rounded-md text-xs bg-background", children: [_jsx("option", { value: "", children: "All document types" }), rules_data.document_types.map(t => (_jsx("option", { value: t, children: t }, t)))] }))] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: rules_data.loading ? (_jsx("div", { className: "flex items-center justify-center h-20 text-xs text-muted-foreground", children: "Loading..." })) : Object.keys(grouped).length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-32 text-xs text-muted-foreground gap-2 px-4 text-center", children: [_jsx(LuFileText, { className: "h-8 w-8 text-muted-foreground/50" }), search_query || type_filter
                            ? 'No rules match your filters.'
                            : 'No validation rules yet.'] })) : (Object.entries(grouped).map(([doc_type, type_rules]) => (_jsxs("div", { children: [_jsxs("button", { type: "button", onClick: () => toggle_collapse(doc_type), className: "w-full flex items-center gap-1.5 px-3 py-2 text-xs font-semibold text-muted-foreground uppercase tracking-wide bg-muted/20 hover:bg-muted/40 transition-colors", children: [collapsed_types.has(doc_type)
                                    ? _jsx(LuChevronRight, { className: "h-3.5 w-3.5" })
                                    : _jsx(LuChevronDown, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "truncate flex-1 text-left", children: doc_type }), _jsx("span", { className: "text-muted-foreground/60", children: type_rules.length })] }), !collapsed_types.has(doc_type) && type_rules.map(rule => (_jsxs("button", { type: "button", onClick: () => set_selected_id(rule.id), className: cn('w-full flex items-center gap-2 px-3 py-2 text-sm text-left transition-colors', selected_id === rule.id
                                ? 'bg-primary/10 text-primary border-l-2 border-l-primary'
                                : 'hover:bg-muted/30 border-l-2 border-l-transparent'), children: [rule.enabled
                                    ? _jsx(LuShieldCheck, { className: "h-3.5 w-3.5 text-emerald-600 flex-shrink-0" })
                                    : _jsx(LuShieldOff, { className: "h-3.5 w-3.5 text-muted-foreground flex-shrink-0" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-center gap-1.5 truncate", children: [_jsx("span", { className: "truncate", children: rule.name }), rule.origin === 'global' && (_jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide px-1.5 py-0.5 rounded bg-muted text-muted-foreground flex-shrink-0", children: "Default" })), rule.origin === 'override' && (_jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide px-1.5 py-0.5 rounded bg-accent/15 text-accent-foreground flex-shrink-0", children: "Customized" }))] }), rule.target_field_id && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: rule.target_label ?? rule.target_field_id }))] })] }, rule.id)))] }, doc_type)))) }), _jsxs("div", { className: "px-3 py-2 border-t text-xs text-muted-foreground space-y-0.5", children: [_jsxs("div", { children: [filtered_rules.length, " rule", filtered_rules.length !== 1 ? 's' : '', rules_data.rules.length !== filtered_rules.length && ` of ${rules_data.rules.length}`] }), importing && _jsx("div", { className: "text-primary", children: "Importing\u2026" }), import_status && !importing && (_jsx("div", { className: import_status.startsWith('Import failed') ? 'text-destructive' : 'text-emerald-600', children: import_status }))] })] }));
}
//# sourceMappingURL=rule_list.js.map