/**
 * Table Pagination and Search Component
 *
 * Provides client-side pagination, search, and filtering for data tables
 *
 * @version 1.0.0
 * @author WHP Development Team
 */

class TablePagination {
    /**
     * Initialize table pagination
     *
     * @param {Object} options Configuration options
     * @param {string} options.tableId - ID of the table element
     * @param {string} options.searchId - ID of the search input element
     * @param {string} options.paginationId - ID of the pagination container
     * @param {string} options.infoId - ID of the info text element
     * @param {number} options.itemsPerPage - Number of items per page (default: 25)
     * @param {string} options.filterSelectId - Optional: ID of filter select element
     * @param {string} options.filterAttribute - Optional: Data attribute to filter by
     */
    constructor(options) {
        this.table = document.getElementById(options.tableId);
        this.searchInput = document.getElementById(options.searchId);
        this.paginationContainer = document.getElementById(options.paginationId);
        this.infoElement = document.getElementById(options.infoId);
        this.filterSelect = options.filterSelectId ? document.getElementById(options.filterSelectId) : null;
        this.filterAttribute = options.filterAttribute || null;
        this.itemsPerPage = options.itemsPerPage || 25;
        this.currentPage = 1;
        this.allRows = [];
        this.filteredRows = [];

        if (!this.table) {
            console.error('Table not found:', options.tableId);
            return;
        }

        // Store original rows
        const tbody = this.table.querySelector('tbody');
        if (tbody) {
            this.allRows = Array.from(tbody.querySelectorAll('tr'));
            this.filteredRows = [...this.allRows];
        }

        this.init();
    }

    /**
     * Initialize event listeners and render
     */
    init() {
        // Search functionality
        if (this.searchInput) {
            this.searchInput.addEventListener('input', () => this.handleSearch());
        }

        // Filter functionality
        if (this.filterSelect && this.filterAttribute) {
            this.filterSelect.addEventListener('change', () => this.handleFilter());
        }

        // Initial render
        this.render();
    }

    /**
     * Handle search input
     */
    handleSearch() {
        const searchTerm = this.searchInput.value.toLowerCase().trim();

        if (searchTerm === '') {
            this.filteredRows = [...this.allRows];
        } else {
            this.filteredRows = this.allRows.filter(row => {
                const text = row.textContent.toLowerCase();
                return text.includes(searchTerm);
            });
        }

        // Apply filter if active
        if (this.filterSelect && this.filterAttribute) {
            this.applyFilter();
        }

        this.currentPage = 1;
        this.render();
    }

    /**
     * Handle filter select change
     */
    handleFilter() {
        // Reset to all rows
        this.filteredRows = [...this.allRows];

        // Apply search if active
        const searchTerm = this.searchInput ? this.searchInput.value.toLowerCase().trim() : '';
        if (searchTerm !== '') {
            this.filteredRows = this.filteredRows.filter(row => {
                const text = row.textContent.toLowerCase();
                return text.includes(searchTerm);
            });
        }

        // Apply filter
        this.applyFilter();

        this.currentPage = 1;
        this.render();
    }

    /**
     * Apply current filter value
     */
    applyFilter() {
        if (!this.filterSelect || !this.filterAttribute) return;

        const filterValue = this.filterSelect.value;

        if (filterValue === '' || filterValue === 'all') {
            // Show all (already set in filteredRows)
            return;
        }

        this.filteredRows = this.filteredRows.filter(row => {
            const value = row.dataset[this.filterAttribute];
            return value === filterValue;
        });
    }

    /**
     * Render current page
     */
    render() {
        const tbody = this.table.querySelector('tbody');
        if (!tbody) return;

        const totalItems = this.filteredRows.length;
        const totalPages = Math.ceil(totalItems / this.itemsPerPage);
        const startIndex = (this.currentPage - 1) * this.itemsPerPage;
        const endIndex = Math.min(startIndex + this.itemsPerPage, totalItems);

        // Hide all rows
        this.allRows.forEach(row => row.style.display = 'none');

        // Show current page rows
        const pageRows = this.filteredRows.slice(startIndex, endIndex);
        pageRows.forEach(row => row.style.display = '');

        // Update info text
        if (this.infoElement) {
            if (totalItems === 0) {
                this.infoElement.textContent = 'No items found';
            } else {
                this.infoElement.textContent = `Showing ${startIndex + 1} to ${endIndex} of ${totalItems} items`;
            }
        }

        // Render pagination controls
        this.renderPagination(totalPages);

        // Trigger custom event for post-render actions (like version loading)
        const event = new CustomEvent('tablePaginationRendered', {
            detail: {
                visibleRows: pageRows,
                currentPage: this.currentPage,
                totalPages: totalPages,
                totalItems: totalItems
            }
        });
        document.dispatchEvent(event);
    }

    /**
     * Render pagination controls
     *
     * @param {number} totalPages Total number of pages
     */
    renderPagination(totalPages) {
        if (!this.paginationContainer) return;

        this.paginationContainer.innerHTML = '';

        if (totalPages <= 1) {
            return;
        }

        const ul = document.createElement('ul');
        ul.className = 'pagination mb-0';

        // Previous button
        const prevLi = document.createElement('li');
        prevLi.className = `page-item ${this.currentPage === 1 ? 'disabled' : ''}`;
        prevLi.innerHTML = `<a class="page-link" href="#" data-page="${this.currentPage - 1}"><i class="fa fa-chevron-left"></i></a>`;
        ul.appendChild(prevLi);

        // Page numbers
        const maxButtons = 7;
        let startPage = Math.max(1, this.currentPage - Math.floor(maxButtons / 2));
        let endPage = Math.min(totalPages, startPage + maxButtons - 1);

        if (endPage - startPage < maxButtons - 1) {
            startPage = Math.max(1, endPage - maxButtons + 1);
        }

        // First page
        if (startPage > 1) {
            const firstLi = document.createElement('li');
            firstLi.className = 'page-item';
            firstLi.innerHTML = `<a class="page-link" href="#" data-page="1">1</a>`;
            ul.appendChild(firstLi);

            if (startPage > 2) {
                const ellipsisLi = document.createElement('li');
                ellipsisLi.className = 'page-item disabled';
                ellipsisLi.innerHTML = `<span class="page-link">...</span>`;
                ul.appendChild(ellipsisLi);
            }
        }

        // Page numbers
        for (let i = startPage; i <= endPage; i++) {
            const li = document.createElement('li');
            li.className = `page-item ${i === this.currentPage ? 'active' : ''}`;
            li.innerHTML = `<a class="page-link" href="#" data-page="${i}">${i}</a>`;
            ul.appendChild(li);
        }

        // Last page
        if (endPage < totalPages) {
            if (endPage < totalPages - 1) {
                const ellipsisLi = document.createElement('li');
                ellipsisLi.className = 'page-item disabled';
                ellipsisLi.innerHTML = `<span class="page-link">...</span>`;
                ul.appendChild(ellipsisLi);
            }

            const lastLi = document.createElement('li');
            lastLi.className = 'page-item';
            lastLi.innerHTML = `<a class="page-link" href="#" data-page="${totalPages}">${totalPages}</a>`;
            ul.appendChild(lastLi);
        }

        // Next button
        const nextLi = document.createElement('li');
        nextLi.className = `page-item ${this.currentPage === totalPages ? 'disabled' : ''}`;
        nextLi.innerHTML = `<a class="page-link" href="#" data-page="${this.currentPage + 1}"><i class="fa fa-chevron-right"></i></a>`;
        ul.appendChild(nextLi);

        this.paginationContainer.appendChild(ul);

        // Add click handlers
        ul.querySelectorAll('a.page-link').forEach(link => {
            link.addEventListener('click', (e) => {
                e.preventDefault();
                const page = parseInt(link.dataset.page);
                if (page >= 1 && page <= totalPages && page !== this.currentPage) {
                    this.goToPage(page);
                }
            });
        });
    }

    /**
     * Go to specific page
     *
     * @param {number} page Page number
     */
    goToPage(page) {
        this.currentPage = page;
        this.render();

        // Scroll to top of table
        this.table.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }

    /**
     * Refresh the table (useful when rows are dynamically added/removed)
     */
    refresh() {
        const tbody = this.table.querySelector('tbody');
        if (tbody) {
            this.allRows = Array.from(tbody.querySelectorAll('tr'));
            this.filteredRows = [...this.allRows];

            // Reapply search and filter
            if (this.searchInput && this.searchInput.value.trim() !== '') {
                this.handleSearch();
            } else if (this.filterSelect && this.filterSelect.value !== '' && this.filterSelect.value !== 'all') {
                this.handleFilter();
            } else {
                this.render();
            }
        }
    }
}
