'use client';
/**
 * Custom hook for managing validation rules via hazo_connect API.
 * Follows the same pattern as use_elements.ts in hazo_field_library.
 */
import { useState, useCallback, useMemo } from 'react';
import { API_ENDPOINTS } from '../../../config/api_endpoints.js';
const DEFAULT_TABLE_NAME = 'hazo_collab_form_validations';
const DEFAULT_API_ENDPOINT = API_ENDPOINTS.library_data;
/** Parse a ValidationRuleRecord into a ValidationRule */
function parse_rule_record(record) {
    try {
        const rule_data = JSON.parse(record.rule_data);
        return {
            id: record.id,
            rule_id: record.rule_id,
            scope_id: record.scope_id,
            document_type: record.document_type,
            name: record.name,
            created_at: record.created_at,
            changed_at: record.changed_at,
            ...rule_data,
        };
    }
    catch {
        // Return minimal rule on parse error
        return {
            id: record.id,
            rule_id: record.rule_id,
            scope_id: record.scope_id,
            document_type: record.document_type,
            name: record.name,
            prompt: '',
            clarification_type: 'none',
            enabled: false,
            created_at: record.created_at,
            changed_at: record.changed_at,
        };
    }
}
/** Serialize a ValidationRule into a ValidationRuleRecord. Omit id when creating (DB auto-generates). */
function serialize_rule(rule, omit_id = false) {
    const { id, rule_id, scope_id, document_type, name, created_at, changed_at, ...rule_data } = rule;
    const record = {
        rule_id,
        scope_id: scope_id ?? null,
        document_type,
        name,
        rule_data: JSON.stringify(rule_data),
        created_at,
        changed_at,
    };
    if (!omit_id) {
        record.id = id;
    }
    return record;
}
export function use_validation_rules(options = {}) {
    const { api_base_url = DEFAULT_API_ENDPOINT, table_name = DEFAULT_TABLE_NAME, scope_id, include_globals = false, on_clone_to_override, } = options;
    const [rules, set_rules] = useState([]);
    const [loading, set_loading] = useState(false);
    const [error, set_error] = useState(null);
    // Derive distinct document types from rules
    const document_types = useMemo(() => {
        const type_set = new Set(rules.map(r => r.document_type));
        return Array.from(type_set).sort();
    }, [rules]);
    const fetch_rules = useCallback(async (filter) => {
        set_loading(true);
        set_error(null);
        const build_url = (scope_clause) => {
            const params = new URLSearchParams({
                table: table_name,
                orderBy: 'document_type',
                orderDirection: 'asc',
            });
            if (filter?.document_type) {
                params.set('filter[document_type]', filter.document_type);
            }
            if (scope_clause !== null) {
                params.set('filter[scope_id]', scope_clause);
            }
            return `${api_base_url}?${params.toString()}`;
        };
        const fetch_one = async (url) => {
            const response = await fetch(url);
            if (!response.ok) {
                const error_data = await response.json().catch(() => ({}));
                throw new Error(error_data.error || `HTTP ${response.status}`);
            }
            const result = await response.json();
            return (result.data || []);
        };
        try {
            let merged;
            if (include_globals && scope_id) {
                // Two-tier: globals (scope_id IS NULL) + overrides (scope_id = scope_id)
                const [globals_records, overrides_records] = await Promise.all([
                    fetch_one(build_url('is.null')),
                    fetch_one(build_url(scope_id)),
                ]);
                const overrides_by_rule_id = new Map(overrides_records.map(rec => {
                    const r = parse_rule_record(rec);
                    const has_matching_global = globals_records.some(g => g.rule_id === r.rule_id);
                    return [r.rule_id, { ...r, origin: has_matching_global ? 'override' : 'scope_only' }];
                }));
                const globals_merged = globals_records
                    .filter(g => !overrides_by_rule_id.has(g.rule_id))
                    .map(rec => ({ ...parse_rule_record(rec), origin: 'global' }));
                merged = [...globals_merged, ...overrides_by_rule_id.values()];
            }
            else {
                // Single-tier (legacy): one fetch with optional scope filter
                const records = await fetch_one(build_url(scope_id ?? null));
                merged = records.map(parse_rule_record);
            }
            set_rules(merged);
        }
        catch (err) {
            const message = err instanceof Error ? err.message : 'Failed to fetch validation rules';
            set_error(message);
            console.error('Error fetching validation rules:', err);
        }
        finally {
            set_loading(false);
        }
    }, [api_base_url, table_name, scope_id, include_globals]);
    const create_rule = useCallback(async (rule_input) => {
        set_error(null);
        try {
            const now = new Date().toISOString();
            const partial_rule = {
                ...rule_input,
                id: '', // placeholder — DB auto-generates
                rule_id: rule_input.rule_id,
                scope_id: scope_id ?? rule_input.scope_id ?? null,
                created_at: now,
                changed_at: now,
            };
            // Omit id from POST body — let DB generate the UUID
            const record = serialize_rule(partial_rule, true);
            const response = await fetch(api_base_url, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    table: table_name,
                    data: record,
                }),
            });
            if (!response.ok) {
                const error_data = await response.json().catch(() => ({}));
                throw new Error(error_data.error || `HTTP ${response.status}`);
            }
            // Read back the created record to get the DB-generated id
            const result = await response.json().catch(() => ({}));
            const created_record = result.data;
            const full_rule = created_record
                ? parse_rule_record(created_record)
                : { ...partial_rule, id: partial_rule.rule_id }; // fallback: use rule_id as id
            set_rules(prev => [...prev, full_rule]);
            return full_rule;
        }
        catch (err) {
            const message = err instanceof Error ? err.message : 'Failed to create validation rule';
            set_error(message);
            console.error('Error creating validation rule:', err);
            return null;
        }
    }, [api_base_url, table_name, scope_id]);
    const update_rule = useCallback(async (id, updates) => {
        set_error(null);
        try {
            // Find existing rule to merge
            const existing = rules.find(r => r.id === id);
            if (!existing) {
                throw new Error(`Rule ${id} not found`);
            }
            const updated_rule = {
                ...existing,
                ...updates,
                id, // Ensure ID doesn't change
                changed_at: new Date().toISOString(),
            };
            const record = serialize_rule(updated_rule);
            const response = await fetch(api_base_url, {
                method: 'PATCH',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    table: table_name,
                    criteria: { id },
                    data: {
                        rule_id: record.rule_id,
                        document_type: record.document_type,
                        name: record.name,
                        rule_data: record.rule_data,
                        changed_at: record.changed_at,
                    },
                }),
            });
            if (!response.ok) {
                const error_data = await response.json().catch(() => ({}));
                throw new Error(error_data.error || `HTTP ${response.status}`);
            }
            set_rules(prev => prev.map(r => (r.id === id ? updated_rule : r)));
            return updated_rule;
        }
        catch (err) {
            const message = err instanceof Error ? err.message : 'Failed to update validation rule';
            set_error(message);
            console.error('Error updating validation rule:', err);
            return null;
        }
    }, [api_base_url, table_name, rules]);
    const delete_rule = useCallback(async (id) => {
        set_error(null);
        try {
            const response = await fetch(api_base_url, {
                method: 'DELETE',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    table: table_name,
                    criteria: { id },
                }),
            });
            if (!response.ok) {
                const error_data = await response.json().catch(() => ({}));
                throw new Error(error_data.error || `HTTP ${response.status}`);
            }
            set_rules(prev => prev.filter(r => r.id !== id));
            return true;
        }
        catch (err) {
            const message = err instanceof Error ? err.message : 'Failed to delete validation rule';
            set_error(message);
            console.error('Error deleting validation rule:', err);
            return false;
        }
    }, [api_base_url, table_name]);
    const is_rule_id_unique = useCallback((rule_id, exclude_uuid) => {
        return !rules.some(r => r.rule_id === rule_id && r.id !== exclude_uuid);
    }, [rules]);
    const clone_to_override = useCallback(async (global_rule) => {
        set_error(null);
        if (!on_clone_to_override) {
            const msg = 'on_clone_to_override callback was not provided';
            set_error(msg);
            console.error(msg);
            return null;
        }
        try {
            const new_rule = await on_clone_to_override(global_rule);
            if (!new_rule)
                return null;
            const tagged = { ...new_rule, origin: 'override' };
            set_rules(prev => {
                const without_global = prev.filter(r => r.rule_id !== tagged.rule_id);
                return [...without_global, tagged];
            });
            return tagged;
        }
        catch (err) {
            const message = err instanceof Error ? err.message : 'Failed to clone rule';
            set_error(message);
            console.error('Error cloning rule:', err);
            return null;
        }
    }, [on_clone_to_override]);
    const can_clone_to_override = !!on_clone_to_override;
    return {
        rules,
        loading,
        error,
        document_types,
        fetch_rules,
        create_rule,
        update_rule,
        delete_rule,
        is_rule_id_unique,
        clone_to_override,
        can_clone_to_override,
    };
}
//# sourceMappingURL=use_validation_rules.js.map