window.tmKanban = {
    instances: new Map(),

    _ensureSortable() {
        if (typeof window.Sortable !== 'function') {
            console.error('[tmKanban] SortableJS not loaded');
            return false;
        }
        return true;
    },

    init(containerSelector, dotNetRef) {
        if (!this._ensureSortable()) return;
        this.dispose(containerSelector);
        const container = document.querySelector(containerSelector);
        if (!container) { console.warn('[tmKanban] container not found:', containerSelector); return; }
        const columns = container.querySelectorAll('[data-kanban-column]');
        if (!columns.length) { console.warn('[tmKanban] no columns in', containerSelector); return; }
        const instances = [];
        columns.forEach(col => {
            instances.push(window.Sortable.create(col, {
                group: 'tm-cards',
                animation: 180,
                ghostClass: 'tm-card-ghost',
                chosenClass: 'tm-card-chosen',
                dragClass: 'tm-card-drag',
                onEnd: (evt) => {
                    const cardId = parseInt(evt.item.getAttribute('data-card-id'), 10);
                    const toColumnId = parseInt(evt.to.getAttribute('data-column-id'), 10);
                    const newPosition = evt.newIndex;
                    if (!isNaN(cardId) && !isNaN(toColumnId)) {
                        dotNetRef.invokeMethodAsync('OnCardMoved', cardId, toColumnId, newPosition)
                            .catch(err => console.error('[tmKanban] OnCardMoved failed:', err));
                    }
                }
            }));
        });
        this.instances.set(containerSelector, instances);
        console.log('[tmKanban] board initialized', columns.length, 'columns');
    },

    initDashboard(containerSelector, dotNetRef) {
        if (!this._ensureSortable()) return;
        this.dispose(containerSelector);
        const container = document.querySelector(containerSelector);
        if (!container) { console.warn('[tmKanban] dashboard container not found:', containerSelector); return; }
        const buckets = container.querySelectorAll('[data-dashboard-column]');
        if (!buckets.length) { console.warn('[tmKanban] no buckets in', containerSelector); return; }
        const instances = [];
        buckets.forEach(bucket => {
            instances.push(window.Sortable.create(bucket, {
                group: 'tm-dashboard-cards',
                animation: 180,
                ghostClass: 'tm-card-ghost',
                chosenClass: 'tm-card-chosen',
                dragClass: 'tm-card-drag',
                onEnd: (evt) => {
                    const cardId = parseInt(evt.item.getAttribute('data-card-id'), 10);
                    const toBucket = parseInt(evt.to.getAttribute('data-bucket-position'), 10);
                    if (!isNaN(cardId) && !isNaN(toBucket)) {
                        dotNetRef.invokeMethodAsync('OnDashboardCardMoved', cardId, toBucket)
                            .catch(err => console.error('[tmKanban] OnDashboardCardMoved failed:', err));
                    }
                }
            }));
        });
        this.instances.set(containerSelector, instances);
        console.log('[tmKanban] dashboard initialized', buckets.length, 'buckets');
    },

    dispose(containerSelector) {
        const existing = this.instances.get(containerSelector);
        if (existing) {
            existing.forEach(s => { try { s.destroy(); } catch { } });
            this.instances.delete(containerSelector);
        }
    }
};
