/**
 * Utility to convert NewFieldDefinition to FieldConfig
 * Used when consuming apps need a ready-to-use field configuration
 */
/**
 * Generate a unique field ID
 * Uses a combination of timestamp and random characters
 */
function generate_field_id(prefix = 'field') {
    const timestamp = Date.now().toString(36);
    const random = Math.random().toString(36).substring(2, 8);
    return `${prefix}_${timestamp}_${random}`;
}
/**
 * Get default value for a field type
 */
function get_default_value(field_type) {
    switch (field_type) {
        case 'HazoCollabFormCheckbox':
            return false;
        default:
            return '';
    }
}
/**
 * Convert FieldOption[] to InputOption[]
 * (They have the same structure but are different types)
 */
function convert_options(options) {
    return options.map(opt => ({
        label: opt.label,
        value: opt.value,
    }));
}
/**
 * Convert a NewFieldDefinition to a partial FieldConfig
 *
 * This utility creates a FieldConfig object from a NewFieldDefinition,
 * generating a unique ID and mapping field-type-specific options.
 *
 * @param definition - The new field definition from the add field dialog
 * @returns A partial FieldConfig that can be merged into the form sections
 *
 * @example
 * ```typescript
 * const handle_add_field_config = (after_field_id: string, field_config: FieldConfig) => {
 *   // Insert field_config into sections after the specified field
 *   set_sections(prev => insert_field_after(prev, after_field_id, field_config));
 * };
 * ```
 */
export function new_field_definition_to_config(definition) {
    // Determine if this is a group or field
    const is_group = definition.field_type === 'Group';
    // Base configuration
    const base_config = {
        id: generate_field_id(is_group ? 'group' : 'field'),
        label: definition.label,
        field_type: is_group ? 'group' : 'field',
        value: is_group ? '' : get_default_value(definition.field_type),
        required: definition.required,
        // Icons show automatically based on role config - no show_icons needed
    };
    // Add component_type for non-group fields
    if (!is_group) {
        base_config.component_type = definition.field_type;
    }
    // Add description if provided
    if (definition.description) {
        base_config.description = definition.description;
    }
    // Add field-type-specific configuration
    // Options for Radio, Combo
    if (definition.options && definition.options.length > 0) {
        base_config.input_options = convert_options(definition.options);
    }
    // Placeholder for text fields
    if (definition.placeholder) {
        base_config.input_format = {
            format_guide: definition.placeholder,
        };
    }
    // Date configuration
    if (definition.date_config) {
        // Note: The date_mode would need to be handled by the consuming app
        // or we could add a custom property. For now, we store it in a way
        // that the date component can understand.
        if (definition.date_config.date_mode === 'range') {
            // Date range is typically handled differently - the consuming app
            // may need to set this up based on their specific implementation
            // For now, we just mark it as a date component and let the app handle it
        }
    }
    // Checkbox configuration
    // Note: checkbox_config (checked_label, unchecked_label) would be used
    // for display purposes in the summary view. The consuming app can
    // store these in field metadata or a custom property.
    // For groups, initialize empty fields array
    if (is_group) {
        base_config.fields = [];
    }
    // If sourced from the library, spread the full source config into the base
    // This preserves input_type, input_format, validation, tooltip, etc.
    if (definition.source_config) {
        const { id: _id, field_type: _ft, value: _v, ...source_rest } = definition.source_config;
        Object.assign(base_config, source_rest);
        // Ensure the generated id is used (not the library's original id)
        base_config.id = generate_field_id(is_group ? 'group' : 'field');
        // Ensure the label from the definition takes precedence
        base_config.label = definition.label;
    }
    return base_config;
}
/**
 * Insert a field or group into sections after a specific field/group
 *
 * This is a helper function that consuming apps can use to insert
 * a new field or group configuration into their sections array.
 *
 * For groups (field_type === 'group'), inserts into section.groups.
 * For fields, inserts into the appropriate group's fields array.
 *
 * @param sections - The current sections array
 * @param after_field_id - The field/group ID after which to insert
 * @param new_field - The new field/group configuration to insert
 * @returns A new sections array with the field/group inserted
 */
export function insert_field_after_in_sections(sections, after_field_id, new_field) {
    // Check if we're inserting a group (at section level)
    const is_group = new_field.field_type === 'group';
    return sections.map(section => {
        if (!section.groups)
            return section;
        // If inserting a group, handle at section level
        if (is_group) {
            // Check for "before_<first_group_id>" - insert at beginning of section
            if (after_field_id.startsWith('before_')) {
                const target_group_id = after_field_id.replace('before_', '');
                const target_index = section.groups.findIndex(g => g.id === target_group_id);
                if (target_index !== -1) {
                    const new_groups = [...section.groups];
                    new_groups.splice(target_index, 0, new_field);
                    return {
                        ...section,
                        groups: new_groups,
                    };
                }
                // If target not found but starts with 'before_', insert at beginning
                return {
                    ...section,
                    groups: [new_field, ...section.groups],
                };
            }
            // Check if after_field_id matches a group - insert after that group
            const group_index = section.groups.findIndex(g => g.id === after_field_id);
            if (group_index !== -1) {
                const new_groups = [...section.groups];
                new_groups.splice(group_index + 1, 0, new_field);
                return {
                    ...section,
                    groups: new_groups,
                };
            }
            return section;
        }
        // For regular fields, insert into groups
        const new_groups = section.groups.map(group => {
            // Check if after_field_id is "before_<group_id>" (insert at beginning of group)
            // This handles the "+" button that appears before a group
            if (after_field_id === `before_${group.id}`) {
                return {
                    ...group,
                    fields: [new_field, ...(group.fields || [])],
                };
            }
            // Check if after_field_id is the group itself
            if (group.id === after_field_id) {
                // Insert as first field in the group
                return {
                    ...group,
                    fields: [new_field, ...(group.fields || [])],
                };
            }
            if (!group.fields)
                return group;
            // Find the field index
            const field_index = group.fields.findIndex(f => f.id === after_field_id);
            if (field_index === -1)
                return group;
            // Insert after the found field
            const new_fields = [...group.fields];
            new_fields.splice(field_index + 1, 0, new_field);
            return {
                ...group,
                fields: new_fields,
            };
        });
        return {
            ...section,
            groups: new_groups,
        };
    });
}
/**
 * Remove a field from sections by its ID
 *
 * This is a helper function that consuming apps can use to remove
 * a field from their sections array (soft delete or hard delete).
 *
 * @param sections - The current sections array
 * @param field_id - The ID of the field to remove
 * @returns A new sections array with the field removed
 *
 * @example
 * ```typescript
 * const handle_delete_field = (field_id: string) => {
 *   set_sections(prev => remove_field_from_sections(prev, field_id));
 * };
 * ```
 */
export function remove_field_from_sections(sections, field_id) {
    return sections.map(section => {
        if (!section.groups)
            return section;
        const new_groups = section.groups
            // Filter out groups that match the field_id (if deleting a group)
            .filter(group => group.id !== field_id)
            // For remaining groups, filter their fields
            .map(group => {
            if (!group.fields)
                return group;
            const new_fields = group.fields.filter(f => f.id !== field_id);
            // Only update if fields actually changed
            if (new_fields.length === group.fields.length)
                return group;
            return {
                ...group,
                fields: new_fields,
            };
        });
        return {
            ...section,
            groups: new_groups,
        };
    });
}
/**
 * Update a field's properties in sections by its ID
 *
 * This is a helper function that consuming apps can use to update
 * a field's properties (label, type, options, etc.) in their sections array.
 *
 * @param sections - The current sections array
 * @param field_id - The ID of the field to update
 * @param updates - Partial field properties to merge
 * @returns A new sections array with the field updated
 *
 * @example
 * ```typescript
 * const handle_edit_field = (field_id: string, updates: Partial<FieldConfig>) => {
 *   set_sections(prev => update_field_in_sections(prev, field_id, updates));
 * };
 * ```
 */
export function update_field_in_sections(sections, field_id, updates) {
    return sections.map(section => {
        if (!section.groups)
            return section;
        // Check if field_id is a group ID
        const group_index = section.groups.findIndex(g => g.id === field_id);
        if (group_index !== -1) {
            // Update the group itself
            const new_groups = [...section.groups];
            new_groups[group_index] = {
                ...new_groups[group_index],
                ...updates,
            };
            return {
                ...section,
                groups: new_groups,
            };
        }
        // Otherwise, look for the field in groups
        const new_groups = section.groups.map(group => {
            if (!group.fields)
                return group;
            const field_index = group.fields.findIndex(f => f.id === field_id);
            if (field_index === -1)
                return group;
            // Found the field - update it
            const new_fields = [...group.fields];
            new_fields[field_index] = {
                ...new_fields[field_index],
                ...updates,
            };
            return {
                ...group,
                fields: new_fields,
            };
        });
        return {
            ...section,
            groups: new_groups,
        };
    });
}
//# sourceMappingURL=field_definition_to_config.js.map