/**
 * FieldAuditProvider — owns the in-session audit history.
 *
 * State lives in React state, so it dies with the component tree. Persistence
 * is intentionally out of scope for this release; consuming apps that need
 * durable audit logs can keep their own copy by subscribing to record_change
 * via the imperative API.
 */
'use client';
import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useCallback, useContext, useMemo, useRef, useState, } from 'react';
const FieldAuditContext = createContext(undefined);
/**
 * Hook for consumers that *must* run inside a provider. Throws otherwise.
 */
export function useFieldAudit() {
    const ctx = useContext(FieldAuditContext);
    if (!ctx) {
        throw new Error('useFieldAudit must be used inside <FieldAuditProvider>');
    }
    return ctx;
}
/**
 * Hook for components that may render with or without an audit provider.
 * `FieldAuditIcon` and `FieldAuditPanel` use this so they can be dropped
 * into a slot whether or not audit is enabled — when no provider is mounted
 * they silently render nothing.
 */
export function useFieldAuditOptional() {
    return useContext(FieldAuditContext);
}
function make_id(field_id) {
    return `${field_id}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
}
export function FieldAuditProvider({ children }) {
    const [entries, set_entries] = useState(() => new Map());
    const [expanded, set_expanded] = useState(() => new Set());
    // Mirror entries in a ref so the auto-watcher (FormDataAuditor) can read
    // the live state without re-binding to setState and creating stale closures.
    const entries_ref = useRef(entries);
    entries_ref.current = entries;
    const record_change = useCallback((input) => {
        set_entries((prev) => {
            const existing = prev.get(input.field_id) ?? [];
            const last = existing[0];
            const window_ms = input.dedup_window_ms ?? 500;
            // Dedup against a recent entry with the same new value.
            if (last &&
                Object.is(last.new_value, input.new_value) &&
                Date.now() - last.at < window_ms) {
                // The auto-watcher fires `manual` on every form_data change; an
                // explicit caller may classify the same change as `clarification`
                // before/around the watcher fires. Always promote the existing
                // entry to the more specific source.
                if (last.source === 'manual' && input.source !== 'manual') {
                    const promoted = {
                        ...last,
                        source: input.source,
                        user: input.user ?? last.user,
                    };
                    const next = new Map(prev);
                    next.set(input.field_id, [promoted, ...existing.slice(1)]);
                    return next;
                }
                // Otherwise treat as a duplicate and keep the existing entry.
                return prev;
            }
            const entry = {
                id: make_id(input.field_id),
                field_id: input.field_id,
                source: input.source,
                at: Date.now(),
                prev_value: input.prev_value !== undefined ? input.prev_value : last?.new_value,
                new_value: input.new_value,
                user: input.user,
            };
            const next = new Map(prev);
            next.set(input.field_id, [entry, ...existing]);
            return next;
        });
    }, []);
    const toggle_expanded = useCallback((field_id) => {
        set_expanded((prev) => {
            const next = new Set(prev);
            if (next.has(field_id))
                next.delete(field_id);
            else
                next.add(field_id);
            return next;
        });
    }, []);
    const clear_field = useCallback((field_id) => {
        set_entries((prev) => {
            if (!prev.has(field_id))
                return prev;
            const next = new Map(prev);
            next.delete(field_id);
            return next;
        });
        set_expanded((prev) => {
            if (!prev.has(field_id))
                return prev;
            const next = new Set(prev);
            next.delete(field_id);
            return next;
        });
    }, []);
    const clear_all = useCallback(() => {
        set_entries(new Map());
        set_expanded(new Set());
    }, []);
    const value = useMemo(() => ({
        entries,
        expanded,
        record_change,
        toggle_expanded,
        clear_field,
        clear_all,
    }), [entries, expanded, record_change, toggle_expanded, clear_field, clear_all]);
    return (_jsx(FieldAuditContext.Provider, { value: value, children: children }));
}
export { FieldAuditContext };
//# sourceMappingURL=context.js.map