import Sortable from '@stimulus-components/sortable';
import {getComponent} from '@symfony/ux-live-component';

export default class extends Sortable {

    static values = {
        mode: {type: String, default: 'default'},
        action: {type: String, default: 'sortable'}
    }
    static targets = ['item'];

    async initialize() {
        super.initialize();
        this.component = await getComponent(this.element.closest('[data-controller~="live"]'));
        console.log(this.component);
    }

    connect() {
        super.connect();
        this.applyModeOptions();
    }

    /* ============================================================
       🔥 1. Choix du mode d’options (default, grid, compact…)
       ============================================================ */
    applyModeOptions() {
        let options = this.getOptionsDefault();

        switch (this.modeValue) {
            case 'grid':
                options = this.getOptionsGrid();
                break;

            case 'default':
            default:
                options = this.getOptionsDefault();
        }

        // Merge avec les options existantes de Sortable
        this.sortable.options = {
            ...this.sortable.options,
            ...options
        };
    }

    /* ============================================
       🔥 2. Sets d’options
       ============================================ */
    getOptionsDefault() {
        return {
            animation: 150,
            handle: this.handleValue,
            onEnd: evt => this.onSortableEnd(evt),
        };
    }

    getOptionsGrid() {
        return {
            animation: 200,
            handle: this.handleValue,
            ghostClass: "opacity-50",
            direction: "vertical",
            onChange: (evt) => this.updateGridClasses(),
            onEnd: evt => {
                this.updateGridClasses();
                this.onSortableEnd(evt);
            }
        };
    }

    /* =======================================================
       🔥 3. onEnd global → reindex + notif au Live Component
       ======================================================= */
    async onSortableEnd(evt) {
        this.renumberCollection();
        console.log(12);
        console.log(evt.item);
        await this.component.action(this.actionValue, {
            currentPosition: evt.oldIndex,
            newPosition: evt.newIndex,
            ...this.extractContext(evt.target)
        });
    }

    /* ============================================
       🔥 4. Grid styling (mode optionnel)
       ============================================ */
    updateGridClasses() {
        if (this.element.classList.contains("grid")) {
            this.itemTargets.forEach((el, index) => {
                el.classList.remove("row-span-2", "col-span-2");
                if (index === 0) {
                    el.classList.add("row-span-2", "col-span-2");
                }
            });
        }
    }

    /* ================================
       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
                ])
        )
    }

    /* ============================================================
       🔥 5. Fonction générique de reindexation (restaurée)
       ============================================================ */
    renumberCollection() {
        console.log(this.itemTargets);
        this.itemTargets.forEach((item, newIndex) => {
            const oldIndex = item.dataset.index;

            item.dataset.index = newIndex;

            item.querySelectorAll("[name], [id], [for]").forEach(el => {
                this.updateAttribute(el, "name", oldIndex, newIndex);
                this.updateAttribute(el, "id", oldIndex, newIndex);
                this.updateAttribute(el, "for", oldIndex, newIndex);
            });
        });
    }

    updateAttribute(el, attr, oldIndex, newIndex) {
        if (!el.hasAttribute(attr)) return;

        const value = el.getAttribute(attr);

        const newValue = value
            .replace(new RegExp(`\\[${oldIndex}\\]`, "g"), `[${newIndex}]`)
            .replace(new RegExp(`_${oldIndex}_`, "g"), `_${newIndex}_`);

        el.setAttribute(attr, newValue);
    }
}
