'use client';
import { jsx as _jsx } from "react/jsx-runtime";
/**
 * Template Generator Context
 * Provides state management and actions for the template generator
 *
 * Multi-section support: state now uses sections: Section[] instead of template: Section
 */
import { createContext, useContext, useReducer, useEffect, useMemo } from 'react';
import { DEFAULT_SECTION, DEFAULT_GROUP, get_default_icons_behaviour } from './types.js';
import { deep_clone, get_fields, get_field_by_path, get_section_by_index, update_field_at_path, update_section_at_index, add_field_at_path, add_section, delete_field_at_path, delete_section_at_index, duplicate_field_at_path, move_field, move_section, build_tree_nodes, get_all_field_ids, generate_field_id, normalize_to_form_set_data, is_section_path, parse_path, build_path, } from './utils/template_utils.js';
import { validate_template } from './utils/validation.js';
import { new_field_definition_to_config } from '../../utils/field_definition_to_config.js';
const MAX_HISTORY = 50;
// Initial state with one empty section
const initial_state = {
    sections: [{ ...DEFAULT_SECTION, section_name: 'Section 1' }],
    icons_behaviour: undefined,
    selected_path: null,
    selected_item: null,
    history: [],
    history_index: -1,
    can_undo: false,
    can_redo: false,
    validation_errors: [],
    is_preview_open: false,
    is_dirty: false,
};
// Helper to get selected item from path
function get_selected_item(sections, path) {
    if (!path)
        return null;
    // Check if it's a section path
    if (is_section_path(path)) {
        const { section_index } = parse_path(path);
        const section = get_section_by_index(sections, section_index);
        if (!section)
            return null;
        const nodes = build_tree_nodes(sections);
        const node = nodes[section_index];
        if (!node)
            return null;
        return {
            path,
            type: 'section',
            node,
        };
    }
    const field = get_field_by_path(sections, path);
    if (!field)
        return null;
    const nodes = build_tree_nodes(sections);
    const find_node = (nodes, target_path) => {
        for (const node of nodes) {
            if (node.path === target_path)
                return node;
            if (node.children) {
                const found = find_node(node.children, target_path);
                if (found)
                    return found;
            }
        }
        return null;
    };
    const node = find_node(nodes, path);
    if (!node)
        return null;
    return {
        path,
        type: node.type,
        node,
    };
}
// Reducer
function reducer(state, action) {
    switch (action.type) {
        case 'SET_TEMPLATE': {
            const { sections, icons_behaviour } = action.payload;
            return {
                ...state,
                sections,
                icons_behaviour,
                selected_path: null,
                selected_item: null,
                is_dirty: true,
                validation_errors: validate_template(sections, icons_behaviour),
            };
        }
        case 'ADD_SECTION': {
            const new_sections = add_section(state.sections, action.payload);
            return {
                ...state,
                sections: new_sections,
                // Select the new section
                selected_path: `s${new_sections.length - 1}`,
                selected_item: get_selected_item(new_sections, `s${new_sections.length - 1}`),
                is_dirty: true,
                validation_errors: validate_template(new_sections, state.icons_behaviour),
            };
        }
        case 'UPDATE_SECTION': {
            const { section_index, updates } = action.payload;
            const new_sections = update_section_at_index(state.sections, section_index, updates);
            return {
                ...state,
                sections: new_sections,
                selected_item: get_selected_item(new_sections, state.selected_path),
                is_dirty: true,
                validation_errors: validate_template(new_sections, state.icons_behaviour),
            };
        }
        case 'DELETE_SECTION': {
            const section_index = action.payload;
            // Don't allow deleting the last section
            if (state.sections.length <= 1)
                return state;
            const new_sections = delete_section_at_index(state.sections, section_index);
            // Adjust selected path if needed
            let new_selected_path = state.selected_path;
            if (state.selected_path) {
                const { section_index: selected_section } = parse_path(state.selected_path);
                if (selected_section === section_index) {
                    // Selected item was in deleted section
                    new_selected_path = null;
                }
                else if (selected_section > section_index) {
                    // Selected item was after deleted section - adjust index
                    const { field_indices } = parse_path(state.selected_path);
                    new_selected_path = build_path(selected_section - 1, field_indices);
                }
            }
            return {
                ...state,
                sections: new_sections,
                selected_path: new_selected_path,
                selected_item: get_selected_item(new_sections, new_selected_path),
                is_dirty: true,
                validation_errors: validate_template(new_sections, state.icons_behaviour),
            };
        }
        case 'MOVE_SECTION': {
            const { from_index, to_index } = action.payload;
            const new_sections = move_section(state.sections, from_index, to_index);
            // Adjust selected path if needed
            let new_selected_path = state.selected_path;
            if (state.selected_path) {
                const { section_index, field_indices } = parse_path(state.selected_path);
                if (section_index === from_index) {
                    new_selected_path = build_path(to_index, field_indices);
                }
                else if (from_index < section_index && section_index <= to_index) {
                    new_selected_path = build_path(section_index - 1, field_indices);
                }
                else if (to_index <= section_index && section_index < from_index) {
                    new_selected_path = build_path(section_index + 1, field_indices);
                }
            }
            return {
                ...state,
                sections: new_sections,
                selected_path: new_selected_path,
                selected_item: get_selected_item(new_sections, new_selected_path),
                is_dirty: true,
                validation_errors: validate_template(new_sections, state.icons_behaviour),
            };
        }
        case 'UPDATE_FIELD': {
            const { path, updates } = action.payload;
            const new_sections = update_field_at_path(state.sections, path, updates);
            return {
                ...state,
                sections: new_sections,
                selected_item: get_selected_item(new_sections, state.selected_path),
                is_dirty: true,
                validation_errors: validate_template(new_sections, state.icons_behaviour),
            };
        }
        case 'ADD_FIELD': {
            const { parent_path, field } = action.payload;
            // If no parent_path, default to first section
            const effective_parent = parent_path ?? 's0';
            const new_sections = add_field_at_path(state.sections, effective_parent, field);
            // Calculate new path for the added field
            const { section_index, field_indices } = parse_path(effective_parent);
            let new_path;
            if (field_indices.length === 0) {
                // Added to section root
                const section = new_sections[section_index];
                const groups = get_fields(section);
                new_path = build_path(section_index, [groups.length - 1]);
            }
            else {
                // Added to a group
                const parent = get_field_by_path(new_sections, effective_parent);
                const new_index = (parent?.fields?.length ?? 1) - 1;
                new_path = build_path(section_index, [...field_indices, new_index]);
            }
            return {
                ...state,
                sections: new_sections,
                selected_path: new_path,
                selected_item: get_selected_item(new_sections, new_path),
                is_dirty: true,
                validation_errors: validate_template(new_sections, state.icons_behaviour),
            };
        }
        case 'ADD_GROUP_WITH_FIELDS': {
            const { parent_path, group } = action.payload;
            // Groups are always added at section level (parent_path should be a section path)
            const effective_parent = parent_path ?? 's0';
            const new_sections = add_field_at_path(state.sections, effective_parent, group);
            // Calculate new path for the added group
            const { section_index } = parse_path(effective_parent);
            const section = new_sections[section_index];
            const groups = get_fields(section);
            const new_path = build_path(section_index, [groups.length - 1]);
            return {
                ...state,
                sections: new_sections,
                selected_path: new_path,
                selected_item: get_selected_item(new_sections, new_path),
                is_dirty: true,
                validation_errors: validate_template(new_sections, state.icons_behaviour),
            };
        }
        case 'DELETE_FIELD': {
            const path = action.payload;
            // Check if deleting a section
            if (is_section_path(path)) {
                const { section_index } = parse_path(path);
                // Don't allow deleting the last section
                if (state.sections.length <= 1)
                    return state;
                const new_sections = delete_section_at_index(state.sections, section_index);
                return {
                    ...state,
                    sections: new_sections,
                    selected_path: null,
                    selected_item: null,
                    is_dirty: true,
                    validation_errors: validate_template(new_sections, state.icons_behaviour),
                };
            }
            const new_sections = delete_field_at_path(state.sections, path);
            return {
                ...state,
                sections: new_sections,
                selected_path: null,
                selected_item: null,
                is_dirty: true,
                validation_errors: validate_template(new_sections, state.icons_behaviour),
            };
        }
        case 'DUPLICATE_FIELD': {
            const path = action.payload;
            const timestamp = Date.now().toString(36).slice(-4);
            const new_sections = duplicate_field_at_path(state.sections, path, `_${timestamp}`);
            return {
                ...state,
                sections: new_sections,
                is_dirty: true,
                validation_errors: validate_template(new_sections, state.icons_behaviour),
            };
        }
        case 'MOVE_FIELD': {
            const { from, to, position } = action.payload;
            console.log('[MOVE_FIELD] Before move, sections count:', state.sections.length);
            const new_sections = move_field(state.sections, from, to, position);
            console.log('[MOVE_FIELD] After move, sections count:', new_sections.length);
            return {
                ...state,
                sections: new_sections,
                is_dirty: true,
                validation_errors: validate_template(new_sections, state.icons_behaviour),
            };
        }
        case 'SELECT_ITEM': {
            const path = action.payload;
            return {
                ...state,
                selected_path: path,
                selected_item: get_selected_item(state.sections, path),
            };
        }
        case 'PUSH_HISTORY': {
            const new_history_entry = {
                sections: deep_clone(state.sections),
                icons_behaviour: state.icons_behaviour ? deep_clone(state.icons_behaviour) : undefined,
                selected_path: state.selected_path,
                timestamp: Date.now(),
                action_description: action.payload,
            };
            // If we're not at the end of history, discard future states
            const history = state.history.slice(0, state.history_index + 1);
            history.push(new_history_entry);
            // Limit history size
            if (history.length > MAX_HISTORY) {
                history.shift();
            }
            return {
                ...state,
                history,
                history_index: history.length - 1,
                can_undo: true,
                can_redo: false,
            };
        }
        case 'UNDO': {
            if (state.history_index <= 0)
                return state;
            const new_index = state.history_index - 1;
            const history_state = state.history[new_index];
            return {
                ...state,
                sections: deep_clone(history_state.sections),
                icons_behaviour: history_state.icons_behaviour ? deep_clone(history_state.icons_behaviour) : undefined,
                selected_path: history_state.selected_path,
                selected_item: get_selected_item(history_state.sections, history_state.selected_path),
                history_index: new_index,
                can_undo: new_index > 0,
                can_redo: true,
                is_dirty: true,
                validation_errors: validate_template(history_state.sections, history_state.icons_behaviour),
            };
        }
        case 'REDO': {
            if (state.history_index >= state.history.length - 1)
                return state;
            const new_index = state.history_index + 1;
            const history_state = state.history[new_index];
            return {
                ...state,
                sections: deep_clone(history_state.sections),
                icons_behaviour: history_state.icons_behaviour ? deep_clone(history_state.icons_behaviour) : undefined,
                selected_path: history_state.selected_path,
                selected_item: get_selected_item(history_state.sections, history_state.selected_path),
                history_index: new_index,
                can_undo: true,
                can_redo: new_index < state.history.length - 1,
                is_dirty: true,
                validation_errors: validate_template(history_state.sections, history_state.icons_behaviour),
            };
        }
        case 'SET_PREVIEW_OPEN': {
            return {
                ...state,
                is_preview_open: action.payload,
            };
        }
        case 'VALIDATE': {
            return {
                ...state,
                validation_errors: validate_template(state.sections, state.icons_behaviour),
            };
        }
        // Icons behaviour cases (now at form-set level)
        case 'UPDATE_ICONS_BEHAVIOUR': {
            const current_behaviour = state.icons_behaviour ?? get_default_icons_behaviour();
            const new_icons_behaviour = {
                ...current_behaviour,
                ...action.payload,
            };
            return {
                ...state,
                icons_behaviour: new_icons_behaviour,
                is_dirty: true,
                validation_errors: validate_template(state.sections, new_icons_behaviour),
            };
        }
        case 'ADD_ROLE': {
            const current_behaviour = state.icons_behaviour ?? get_default_icons_behaviour();
            const current_roles = current_behaviour.roles ?? [];
            const new_icons_behaviour = {
                ...current_behaviour,
                roles: [...current_roles, action.payload],
            };
            return {
                ...state,
                icons_behaviour: new_icons_behaviour,
                is_dirty: true,
                validation_errors: validate_template(state.sections, new_icons_behaviour),
            };
        }
        case 'UPDATE_ROLE': {
            const { role_id, updates } = action.payload;
            const current_behaviour = state.icons_behaviour ?? get_default_icons_behaviour();
            const current_roles = current_behaviour.roles ?? [];
            const new_roles = current_roles.map(role => role.role_id === role_id ? { ...role, ...updates } : role);
            const new_icons_behaviour = {
                ...current_behaviour,
                roles: new_roles,
            };
            return {
                ...state,
                icons_behaviour: new_icons_behaviour,
                is_dirty: true,
                validation_errors: validate_template(state.sections, new_icons_behaviour),
            };
        }
        case 'DELETE_ROLE': {
            const current_behaviour = state.icons_behaviour ?? get_default_icons_behaviour();
            const current_roles = current_behaviour.roles ?? [];
            const new_roles = current_roles.filter(role => role.role_id !== action.payload);
            const new_icons_behaviour = {
                ...current_behaviour,
                roles: new_roles,
            };
            return {
                ...state,
                icons_behaviour: new_icons_behaviour,
                is_dirty: true,
                validation_errors: validate_template(state.sections, new_icons_behaviour),
            };
        }
        default:
            return state;
    }
}
const TemplateGeneratorContext = createContext(null);
// Provider component
export function TemplateGeneratorProvider({ children, initial_template, on_template_change, }) {
    // Normalize initial template to FormSetData
    const initial_data = initial_template
        ? normalize_to_form_set_data(initial_template)
        : { sections: [{ ...DEFAULT_SECTION, section_name: 'Section 1' }], icons_behaviour: undefined };
    const [state, dispatch] = useReducer(reducer, {
        ...initial_state,
        sections: initial_data.sections,
        icons_behaviour: initial_data.icons_behaviour,
        validation_errors: validate_template(initial_data.sections, initial_data.icons_behaviour),
    });
    // Initialize history with initial state
    useEffect(() => {
        dispatch({ type: 'PUSH_HISTORY', payload: 'Initial state' });
    }, []);
    // Notify parent of changes
    useEffect(() => {
        if (on_template_change && state.is_dirty) {
            on_template_change({
                sections: state.sections,
                icons_behaviour: state.icons_behaviour,
            });
        }
    }, [state.sections, state.icons_behaviour, state.is_dirty, on_template_change]);
    // Keyboard shortcuts for undo/redo
    useEffect(() => {
        const handler = (e) => {
            if ((e.metaKey || e.ctrlKey) && e.key === 'z') {
                e.preventDefault();
                if (e.shiftKey) {
                    dispatch({ type: 'REDO' });
                }
                else {
                    dispatch({ type: 'UNDO' });
                }
            }
            if ((e.metaKey || e.ctrlKey) && e.key === 'y') {
                e.preventDefault();
                dispatch({ type: 'REDO' });
            }
        };
        window.addEventListener('keydown', handler);
        return () => window.removeEventListener('keydown', handler);
    }, []);
    // Actions
    const actions = useMemo(() => ({
        set_template: (data) => {
            dispatch({ type: 'PUSH_HISTORY', payload: 'Set template' });
            const form_set_data = normalize_to_form_set_data(data);
            dispatch({ type: 'SET_TEMPLATE', payload: form_set_data });
        },
        add_section: (section_name) => {
            const name = section_name || `Section ${state.sections.length + 1}`;
            const section = {
                ...DEFAULT_SECTION,
                section_name: name,
            };
            dispatch({ type: 'PUSH_HISTORY', payload: `Add section: ${name}` });
            dispatch({ type: 'ADD_SECTION', payload: section });
        },
        update_section: (section_index, updates) => {
            dispatch({ type: 'UPDATE_SECTION', payload: { section_index, updates } });
        },
        delete_section: (section_index) => {
            const section = state.sections[section_index];
            dispatch({ type: 'PUSH_HISTORY', payload: `Delete section: ${section?.section_name ?? section_index}` });
            dispatch({ type: 'DELETE_SECTION', payload: section_index });
        },
        move_section: (from_index, to_index) => {
            dispatch({ type: 'PUSH_HISTORY', payload: 'Move section' });
            dispatch({ type: 'MOVE_SECTION', payload: { from_index, to_index } });
        },
        add_field: (parent_path, field) => {
            dispatch({ type: 'PUSH_HISTORY', payload: `Add field: ${field.label}` });
            dispatch({ type: 'ADD_FIELD', payload: { parent_path, field } });
        },
        update_field: (path, updates) => {
            dispatch({ type: 'UPDATE_FIELD', payload: { path, updates } });
        },
        delete_field: (path) => {
            if (is_section_path(path)) {
                const { section_index } = parse_path(path);
                const section = state.sections[section_index];
                dispatch({ type: 'PUSH_HISTORY', payload: `Delete section: ${section?.section_name ?? path}` });
            }
            else {
                const field = get_field_by_path(state.sections, path);
                dispatch({ type: 'PUSH_HISTORY', payload: `Delete field: ${field?.label ?? path}` });
            }
            dispatch({ type: 'DELETE_FIELD', payload: path });
        },
        duplicate_field: (path) => {
            const field = get_field_by_path(state.sections, path);
            dispatch({ type: 'PUSH_HISTORY', payload: `Duplicate field: ${field?.label ?? path}` });
            dispatch({ type: 'DUPLICATE_FIELD', payload: path });
        },
        move_field: (from_path, to_path, position) => {
            dispatch({ type: 'PUSH_HISTORY', payload: 'Move field' });
            dispatch({ type: 'MOVE_FIELD', payload: { from: from_path, to: to_path, position } });
        },
        add_group: (parent_path, label) => {
            const id = generate_field_id(state.sections, label.toLowerCase().replace(/\s+/g, '_') || 'group');
            const group = {
                ...DEFAULT_GROUP,
                id,
                label,
                fields: [],
            };
            dispatch({ type: 'PUSH_HISTORY', payload: `Add group: ${label}` });
            dispatch({ type: 'ADD_FIELD', payload: { parent_path, field: group } });
        },
        add_group_with_fields: (parent_path, label, fields) => {
            const group_id = generate_field_id(state.sections, label.toLowerCase().replace(/\s+/g, '_') || 'group');
            // Convert NewFieldDefinition[] to FieldConfig[]
            const child_fields = fields.map(field_def => {
                const config = new_field_definition_to_config(field_def);
                // Generate a unique ID within the context
                config.id = generate_field_id(state.sections, config.id || 'field');
                return config;
            });
            const group = {
                ...DEFAULT_GROUP,
                id: group_id,
                label,
                fields: child_fields,
            };
            dispatch({ type: 'PUSH_HISTORY', payload: `Add group: ${label}` });
            dispatch({ type: 'ADD_GROUP_WITH_FIELDS', payload: { parent_path, group } });
        },
        select_item: (path) => {
            dispatch({ type: 'SELECT_ITEM', payload: path });
        },
        undo: () => {
            dispatch({ type: 'UNDO' });
        },
        redo: () => {
            dispatch({ type: 'REDO' });
        },
        push_history: (action_description) => {
            dispatch({ type: 'PUSH_HISTORY', payload: action_description });
        },
        validate_template: () => {
            const errors = validate_template(state.sections, state.icons_behaviour);
            dispatch({ type: 'VALIDATE' });
            return errors;
        },
        open_preview: () => {
            dispatch({ type: 'SET_PREVIEW_OPEN', payload: true });
        },
        close_preview: () => {
            dispatch({ type: 'SET_PREVIEW_OPEN', payload: false });
        },
        get_field_by_path: (path) => {
            return get_field_by_path(state.sections, path);
        },
        get_section_by_index: (index) => {
            return get_section_by_index(state.sections, index);
        },
        get_all_field_ids: () => {
            return get_all_field_ids(state.sections);
        },
        // Icons behaviour operations
        update_icons_behaviour: (updates) => {
            dispatch({ type: 'PUSH_HISTORY', payload: 'Update icons behaviour' });
            dispatch({ type: 'UPDATE_ICONS_BEHAVIOUR', payload: updates });
        },
        add_role: (role) => {
            dispatch({ type: 'PUSH_HISTORY', payload: `Add role: ${role.role_name}` });
            dispatch({ type: 'ADD_ROLE', payload: role });
        },
        update_role: (role_id, updates) => {
            dispatch({ type: 'UPDATE_ROLE', payload: { role_id, updates } });
        },
        delete_role: (role_id) => {
            dispatch({ type: 'PUSH_HISTORY', payload: 'Delete role' });
            dispatch({ type: 'DELETE_ROLE', payload: role_id });
        },
    }), [state.sections, state.icons_behaviour]);
    const value = useMemo(() => ({ state, actions }), [state, actions]);
    return (_jsx(TemplateGeneratorContext.Provider, { value: value, children: children }));
}
// Hook to use context
export function useTemplateGenerator() {
    const context = useContext(TemplateGeneratorContext);
    if (!context) {
        throw new Error('useTemplateGenerator must be used within a TemplateGeneratorProvider');
    }
    return context;
}
// Convenience hooks
export function useTemplateState() {
    return useTemplateGenerator().state;
}
export function useTemplateActions() {
    return useTemplateGenerator().actions;
}
//# sourceMappingURL=context.js.map