import { Controller } from '@hotwired/stimulus'
import Sortable from 'sortablejs'
import { getComponent } from '@symfony/ux-live-component'

export default class extends Controller {
    static targets = ['sortable']

    async connect() {
        this.component = await getComponent(
            this.element.closest('[data-controller~="live"]')
        )
    }

    /* ================================
       Gestion dynamique des listes
       ================================ */
    sortableTargetConnected(target) {
        if (Sortable.active) return

        Sortable.create(target, {
            animation: 150,
            handle: target.dataset.sortableHandle,
            onEnd: evt => this.onEnd(evt, target),
        })
    }

    sortableTargetDisconnected(target) {
        if (Sortable.active) return

        const instance = Sortable.get(target)
        if (instance) instance.destroy()
    }

    /* ================================
       Sort terminé (GÉNÉRIQUE)
       ================================ */
    async onEnd(evt, target) {
        const action = target.dataset.sortableAction
        if (!action) return

        const payload = {
            currentPosition: evt.oldIndex,
            newPosition: evt.newIndex,
            ...this.extractContext(target)
        }

        this.renumber(target)
        await this.component.action(action, payload)
    }

    /* ================================
       Context dynamique (parent, enfant…)
       ================================ */
    extractContext(target) {
        return Object.fromEntries(
            Object.entries(target.dataset)
                .filter(([key]) => key.startsWith('sortableContext'))
                .map(([key, value]) => [
                    key.replace('sortableContext', '').toLowerCase(),
                    value
                ])
        )
    }

    /* ================================
       Reindexation locale
       ================================ */
    renumber(target) {
        const items = target.querySelectorAll('[data-sortable-item]')
        items.forEach((item, newIndex) => {
            const oldIndex = item.dataset.index
            item.dataset.index = newIndex

            item.querySelectorAll('[name],[id],[for],[data-model]').forEach(el => {
                this.replaceIndex(el, oldIndex, newIndex)
            })
        })
    }

    replaceIndex(el, oldIndex, newIndex) {
        for (const attr of ['name', 'id', 'for', 'data-model']) {
            if (!el.hasAttribute(attr)) continue
            el.setAttribute(
                attr,
                el.getAttribute(attr)
                    .replace(new RegExp(`\\[${oldIndex}\\]`, 'g'), `[${newIndex}]`)
                    .replace(new RegExp(`_${oldIndex}_`, 'g'), `_${newIndex}_`)
            )
        }
    }
}
