import { Module } from '../core/module.js';

/**
 * Admin Data Table Module
 *
 * Provides interactive functionality for admin data tables:
 * - AJAX loading and pagination
 * - Sorting by columns
 * - Search/filtering
 * - Auto-refresh
 */
export class AdminDataTable extends Module {
    constructor(element) {
        super(element);

        this.resource = element.dataset.resource;
        this.apiEndpoint = element.dataset.apiEndpoint;
        this.sortable = element.dataset.sortable === 'true';
        this.searchable = element.dataset.searchable === 'true';
        this.paginated = element.dataset.paginated === 'true';
        this.perPage = parseInt(element.dataset.perPage) || 25;

        this.currentPage = 1;
        this.currentSort = null;
        this.currentSearch = '';
    }

    async init() {
        if (!this.apiEndpoint) {
            console.warn('AdminDataTable: No API endpoint configured');
            return;
        }

        this.tbody = this.element.querySelector('tbody');
        this.thead = this.element.querySelector('thead');

        if (!this.tbody) {
            console.warn('AdminDataTable: No tbody found');
            return;
        }

        this.setupEventListeners();

        // Only load data if table is initially empty
        if (this.tbody.children.length === 0) {
            await this.loadData();
        }
    }

    setupEventListeners() {
        // Sortable columns
        if (this.sortable && this.thead) {
            this.thead.querySelectorAll('th').forEach((th, index) => {
                const columnKey = th.dataset.column || this.getColumnKeyFromIndex(index);

                if (columnKey) {
                    th.style.cursor = 'pointer';
                    th.classList.add('sortable');

                    th.addEventListener('click', () => {
                        this.sortByColumn(columnKey, th);
                    });
                }
            });
        }

        // Search input
        if (this.searchable) {
            const searchInput = this.getSearchInput();
            if (searchInput) {
                searchInput.addEventListener('input', this.debounce(() => {
                    this.currentSearch = searchInput.value;
                    this.currentPage = 1;
                    this.loadData();
                }, 300));
            }
        }

        // Pagination links (if exist)
        this.setupPaginationListeners();
    }

    setupPaginationListeners() {
        const paginationContainer = this.getPaginationContainer();
        if (!paginationContainer) return;

        paginationContainer.addEventListener('click', (e) => {
            const pageLink = e.target.closest('[data-page]');
            if (pageLink) {
                e.preventDefault();
                const page = parseInt(pageLink.dataset.page);
                if (page && page !== this.currentPage) {
                    this.currentPage = page;
                    this.loadData();
                }
            }
        });
    }

    async sortByColumn(columnKey, th) {
        // Toggle sort direction
        const currentDir = th.dataset.sortDir;
        const newDir = currentDir === 'asc' ? 'desc' : 'asc';

        // Update sort state
        this.currentSort = { column: columnKey, direction: newDir };

        // Update UI
        this.thead.querySelectorAll('th').forEach(header => {
            header.removeAttribute('data-sort-dir');
            header.classList.remove('sort-asc', 'sort-desc');
        });

        th.dataset.sortDir = newDir;
        th.classList.add(`sort-${newDir}`);

        // Reload data
        await this.loadData();
    }

    async loadData() {
        const params = new URLSearchParams({
            page: this.currentPage.toString(),
            per_page: this.perPage.toString(),
        });

        if (this.currentSearch) {
            params.set('search', this.currentSearch);
        }

        if (this.currentSort) {
            params.set('sort_by', this.currentSort.column);
            params.set('sort_dir', this.currentSort.direction);
        }

        const url = `${this.apiEndpoint}?${params}`;

        try {
            this.setLoadingState(true);

            const response = await fetch(url);
            const result = await response.json();

            if (result.success) {
                this.renderRows(result.data);

                if (this.paginated && result.pagination) {
                    this.renderPagination(result.pagination);
                }
            } else {
                this.showError(result.error || 'Failed to load data');
            }
        } catch (error) {
            console.error('AdminDataTable: Failed to load data', error);
            this.showError('Failed to load data');
        } finally {
            this.setLoadingState(false);
        }
    }

    renderRows(data) {
        if (!data || data.length === 0) {
            this.tbody.innerHTML = this.getEmptyRow();
            return;
        }

        // Get column keys from header
        const columnKeys = this.getColumnKeys();

        this.tbody.innerHTML = data.map(item => {
            const cells = columnKeys.map(key => {
                const value = item[key] !== undefined ? item[key] : '';
                return `<td>${this.escapeHtml(value)}</td>`;
            }).join('');

            return `<tr data-id="${item.id || ''}">${cells}</tr>`;
        }).join('');
    }

    renderPagination(pagination) {
        const container = this.getPaginationContainer();
        if (!container) return;

        const { page, pages, total } = pagination;

        if (pages <= 1) {
            container.innerHTML = '';
            return;
        }

        const links = [];

        // Previous
        if (page > 1) {
            links.push(`<a href="#" data-page="${page - 1}" class="page-link">Previous</a>`);
        }

        // Page numbers
        for (let i = 1; i <= pages; i++) {
            if (i === page) {
                links.push(`<span class="page-link active">${i}</span>`);
            } else {
                links.push(`<a href="#" data-page="${i}" class="page-link">${i}</a>`);
            }
        }

        // Next
        if (page < pages) {
            links.push(`<a href="#" data-page="${page + 1}" class="page-link">Next</a>`);
        }

        container.innerHTML = `
            <div class="pagination">
                ${links.join('')}
                <span class="pagination-info">Total: ${total}</span>
            </div>
        `;
    }

    setLoadingState(loading) {
        if (loading) {
            this.element.classList.add('loading');
            this.tbody.style.opacity = '0.5';
        } else {
            this.element.classList.remove('loading');
            this.tbody.style.opacity = '1';
        }
    }

    showError(message) {
        const columnCount = this.getColumnKeys().length;
        this.tbody.innerHTML = `
            <tr>
                <td colspan="${columnCount}" class="error-message">
                    ${this.escapeHtml(message)}
                </td>
            </tr>
        `;
    }

    getEmptyRow() {
        const columnCount = this.getColumnKeys().length;
        return `
            <tr>
                <td colspan="${columnCount}" class="empty-message">
                    No data available
                </td>
            </tr>
        `;
    }

    getColumnKeys() {
        if (!this.thead) return [];

        const headers = this.thead.querySelectorAll('th');
        return Array.from(headers).map((th, index) =>
            th.dataset.column || this.getColumnKeyFromIndex(index)
        ).filter(Boolean);
    }

    getColumnKeyFromIndex(index) {
        // Fallback: use column index as key
        return `col_${index}`;
    }

    getSearchInput() {
        return document.querySelector(`[data-table-search="${this.resource}"]`);
    }

    getPaginationContainer() {
        return document.querySelector(`[data-table-pagination="${this.resource}"]`) ||
               this.element.parentElement.querySelector('.pagination-container');
    }

    escapeHtml(str) {
        const div = document.createElement('div');
        div.textContent = String(str);
        return div.innerHTML;
    }

    debounce(func, wait) {
        let timeout;
        return (...args) => {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    }
}

// Auto-initialize all admin data tables
document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('[data-resource][data-api-endpoint]').forEach(table => {
        new AdminDataTable(table).init();
    });
});
