"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useFormFields = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const fieldDefaults_1 = require("../utils/fieldDefaults.js");
const fieldNames_1 = require("../utils/fieldNames.js");
const fieldTree_1 = require("../utils/fieldTree.js");
const fieldTreeOps_1 = require("../utils/fieldTreeOps.js");
const useFormFields = ({ initialFields, onChange }) => {
    const [formFields, setFormFields] = React.useState(initialFields);
    const [selectedFieldId, setSelectedFieldId] = React.useState(null);
    const idCounter = React.useRef((0, fieldNames_1.maxIdNumericSuffix)(initialFields) + 1);
    const generateId = React.useCallback(() => {
        const id = `fb2_${idCounter.current}`;
        idCounter.current += 1;
        return id;
    }, []);
    const generateName = React.useCallback(() => `field_${idCounter.current}`, []);
    const commit = React.useCallback((next) => {
        setFormFields(next);
        onChange?.(next);
    }, [onChange]);
    const addField = React.useCallback((type) => {
        const id = generateId();
        const name = generateName();
        const newField = (0, fieldDefaults_1.createDefaultField)(type, name, id);
        commit([...formFields, newField]);
    }, [commit, formFields, generateId, generateName]);
    const addFieldToSection = React.useCallback((sectionId, type) => {
        const id = generateId();
        const baseName = generateName();
        const arrayMode = (0, fieldTreeOps_1.isArrayModeSection)(formFields, sectionId);
        const name = arrayMode ? (0, fieldNames_1.prefixNameForArrayMode)(baseName) : baseName;
        const newChild = (0, fieldDefaults_1.createDefaultField)(type, name, id);
        commit((0, fieldTreeOps_1.addChildToSectionDeep)(formFields, sectionId, newChild));
    }, [commit, formFields, generateId, generateName]);
    const insertFieldRelative = React.useCallback((targetId, type, offset) => {
        const makeField = (arrayMode) => {
            const id = generateId();
            const baseName = generateName();
            const name = arrayMode ? (0, fieldNames_1.prefixNameForArrayMode)(baseName) : baseName;
            return (0, fieldDefaults_1.createDefaultField)(type, name, id);
        };
        const result = (0, fieldTreeOps_1.insertAtTargetDeep)(formFields, targetId, offset, makeField);
        if (result === null) {
            const fallback = makeField(false);
            commit([...formFields, fallback]);
            return;
        }
        commit(result);
    }, [commit, formFields, generateId, generateName]);
    const insertFieldBefore = React.useCallback((targetId, type) => insertFieldRelative(targetId, type, 0), [insertFieldRelative]);
    const insertFieldAfter = React.useCallback((targetId, type) => insertFieldRelative(targetId, type, 1), [insertFieldRelative]);
    const removeField = React.useCallback((fieldId) => {
        commit((0, fieldTreeOps_1.removeFieldDeep)(formFields, fieldId));
    }, [commit, formFields]);
    const moveFieldToSection = React.useCallback((fieldId, targetSectionId) => {
        if (fieldId === targetSectionId)
            return;
        const sourceField = (0, fieldTree_1.findFieldById)(formFields, fieldId);
        if (!sourceField)
            return;
        const targetField = (0, fieldTree_1.findFieldById)(formFields, targetSectionId);
        if (!targetField || targetField.type !== 'section') {
            return;
        }
        if (sourceField.type === 'section' && (0, fieldTreeOps_1.containsId)(sourceField, targetSectionId)) {
            return;
        }
        const withoutField = (0, fieldTreeOps_1.removeFieldDeep)(formFields, fieldId);
        const targetIsArray = (0, fieldTreeOps_1.isArrayModeSection)(withoutField, targetSectionId);
        let movedField = sourceField;
        if (sourceField.type !== 'section' && sourceField.type !== 'text') {
            const currentHasIndex = sourceField.name.includes('{{index}}');
            if (targetIsArray && !currentHasIndex) {
                movedField = {
                    ...sourceField,
                    name: (0, fieldNames_1.prefixNameForArrayMode)(sourceField.name),
                };
            }
            else if (!targetIsArray && currentHasIndex) {
                movedField = {
                    ...sourceField,
                    name: (0, fieldNames_1.stripArrayModePrefix)(sourceField.name),
                };
            }
        }
        const result = (0, fieldTreeOps_1.addChildToSectionDeep)(withoutField, targetSectionId, movedField);
        commit(result);
    }, [commit, formFields]);
    const duplicateField = React.useCallback((fieldId) => {
        const existingNames = (0, fieldNames_1.collectNames)(formFields);
        const result = (0, fieldTreeOps_1.duplicateFieldDeep)(formFields, fieldId, generateId, existingNames);
        if (result !== null) {
            commit(result);
        }
    }, [commit, formFields, generateId]);
    const updateField = React.useCallback((fieldId, updates) => {
        commit((0, fieldTreeOps_1.updateFieldDeep)(formFields, fieldId, updates));
    }, [commit, formFields]);
    const moveFieldUp = React.useCallback((fieldId) => {
        const result = (0, fieldTreeOps_1.swapInListDeep)(formFields, fieldId, -1);
        if (result.handled) {
            commit(result.fields);
        }
    }, [commit, formFields]);
    const moveFieldDown = React.useCallback((fieldId) => {
        const result = (0, fieldTreeOps_1.swapInListDeep)(formFields, fieldId, 1);
        if (result.handled) {
            commit(result.fields);
        }
    }, [commit, formFields]);
    const setAllFields = React.useCallback((next) => {
        idCounter.current = Math.max(idCounter.current, (0, fieldNames_1.maxIdNumericSuffix)(next) + 1);
        commit(next);
    }, [commit]);
    const resetForm = React.useCallback(() => {
        commit([]);
        setSelectedFieldId(null);
    }, [commit]);
    const selectField = React.useCallback((fieldId) => {
        setSelectedFieldId(fieldId);
    }, []);
    return {
        formFields,
        selectedFieldId,
        addField,
        addFieldToSection,
        insertFieldBefore,
        insertFieldAfter,
        moveFieldToSection,
        removeField,
        duplicateField,
        updateField,
        moveFieldUp,
        moveFieldDown,
        setAllFields,
        resetForm,
        selectField,
    };
};
exports.useFormFields = useFormFields;
//# sourceMappingURL=useFormFields.js.map
