/**
 * Dynamic Array Widget JavaScript
 * Provides functionality for adding and removing array items dynamically
 */

const initDynamicArrayWidget = () => {
    const containers = document.querySelectorAll('.dynamic-array-widget')

    containers.forEach(container => {
        if (container.dataset.initialized === 'true') {
            return
        }

        const itemsContainer = container.querySelector('.array-items')
        const addButton = container.querySelector('.add-array-item')
        const hiddenInput = container.querySelector('input[type="hidden"]')
        const name = container.dataset.name

        addButton?.addEventListener('click', () => {
            addArrayItem(itemsContainer, name)
            updateHiddenInput(container)
        })
        addRemoveEventListeners(container)
        addInputEventListeners(container)
        updateRemoveButtonVisibility(container)

        // Ensure hidden input is synced with visible inputs on initialization
        updateHiddenInput(container)
        container.dataset.initialized = 'true'
    })
}

const addArrayItem = (itemsContainer, name) => {
    const itemCount = itemsContainer.querySelectorAll('.array-item').length
    const itemHtml = `
        <div class="array-item d-flex mb-2">
            <input type="text" class="form-control array-item-input" value="" data-index="${itemCount}" />
            <button type="button" class="btn btn-sm btn-outline-danger ms-2 remove-array-item" title="Remove item">×</button>
        </div>
    `
    itemsContainer.insertAdjacentHTML('beforeend', itemHtml)

    // Add event listeners to the new item
    const container = itemsContainer.closest('.dynamic-array-widget')
    addRemoveEventListeners(container)
    addInputEventListeners(container)
    updateRemoveButtonVisibility(container)

    // Focus on the new input
    const newItem = itemsContainer.lastElementChild
    const newInput = newItem.querySelector('.array-item-input')
    newInput?.focus()
}

const addRemoveEventListeners = (container) => {
    const removeButtons = container.querySelectorAll('.remove-array-item')
    removeButtons.forEach(button => {
        button.removeEventListener('click', handleRemoveItem)
        button.addEventListener('click', handleRemoveItem)
    })
}

const addInputEventListeners = (container) => {
    const inputs = container.querySelectorAll('.array-item-input')
    inputs.forEach(input => {
        // removal should not be necessary, but better safe than sorry
        input.removeEventListener('input', handleInputChange)
        input.removeEventListener('blur', handleInputChange)
        input.addEventListener('input', handleInputChange)
        input.addEventListener('blur', handleInputChange)
    })
}

const handleRemoveItem = (ev) => {
    const button = ev.target
    const arrayItem = button.closest('.array-item')
    const container = button.closest('.dynamic-array-widget')
    const itemsContainer = container.querySelector('.array-items')

    const itemCount = itemsContainer.querySelectorAll('.array-item').length
    if (itemCount <= 1) {
        const input = arrayItem.querySelector('.array-item-input')
        if (input) { input.value = '' }
    } else {
        arrayItem.remove()
    }

    updateHiddenInput(container)
    reindexItems(container)
    updateRemoveButtonVisibility(container)
}

const handleInputChange = (ev) => {
    const container = ev.target.closest('.dynamic-array-widget')
    updateHiddenInput(container)
}

const updateHiddenInput = (container) => {
    const inputs = container.querySelectorAll('.array-item-input')
    const hiddenInput = container.querySelector('input[type="hidden"]')

    if (!hiddenInput) return

    const values = Array.from(inputs)
        .map(input => input.value ? input.value.trim() : '')
        .filter(value => value !== '')

    hiddenInput.value = JSON.stringify(values)
}

const reindexItems = (container) => {
    const items = container.querySelectorAll('.array-item-input')
    items.forEach((input, index) => {
        input.dataset.index = index
    })
}

const updateRemoveButtonVisibility = (container) => {
    const items = container.querySelectorAll('.array-item')
    const removeButtons = container.querySelectorAll('.remove-array-item')

    // Show/hide remove buttons based on item count
    removeButtons.forEach(button => {
        if (items.length <= 1) {
            button.style.display = 'none'
        } else {
            button.style.display = 'inline-block'
        }
    })
}

window.updateHiddenInput = updateHiddenInput

document.addEventListener('DOMContentLoaded', initDynamicArrayWidget)
document.addEventListener('htmx:afterSwap', initDynamicArrayWidget)
document.addEventListener('htmx:afterSettle', initDynamicArrayWidget)
