export class AjaxTable {
    constructor(options = {}) {
        this.formId = options.formId || 'filterForm';
        this.tableContainerSelector = options.tableContainerSelector || '#userTableContainer';
        this.spinnerId = options.spinnerId || 'loadingSpinner';
        this.searchInputId = options.searchInputId || 'searchInput';
        this.btnClearSearchId = options.btnClearSearchId || 'btnClearSearch';
        this.btnClearFiltersId = options.btnClearFiltersId || 'btnClearFilters';
        this.statusFilterId = options.statusFilterId || 'statusFilter';
        this.monthFilterId = options.monthFilterId || 'monthFilter';
        this.skeletonColumns = options.skeletonColumns || 7;
        
        this.isLoading = false;
        this.searchDebounceTimer = null;

        this.init();
    }

    init() {
        this.form = document.getElementById(this.formId);
        this.spinner = document.getElementById(this.spinnerId);
        this.searchInput = document.getElementById(this.searchInputId);
        this.btnClearSearch = document.getElementById(this.btnClearSearchId);
        this.btnClearFilters = document.getElementById(this.btnClearFiltersId);
        this.statusFilter = document.getElementById(this.statusFilterId);
        this.monthFilter = document.getElementById(this.monthFilterId);

        if (this.form) {
            this.form.addEventListener('submit', (e) => {
                e.preventDefault();
                this.submitForm();
            });
        }

        if (this.searchInput) {
            this.searchInput.addEventListener('input', () => {
                this.toggleClearSearchBtn();
            });
        }

        if (this.btnClearSearch) {
            this.btnClearSearch.addEventListener('click', () => {
                if (this.searchInput) {
                    this.searchInput.value = '';
                    this.toggleClearSearchBtn();
                    this.submitForm();
                }
            });
        }

        if (this.form) {
            this.form.querySelectorAll('select').forEach(select => {
                select.addEventListener('change', () => {
                    this.submitForm();
                });
            });
        }

        if (this.btnClearFilters) {
            this.btnClearFilters.addEventListener('click', () => {
                if (this.searchInput) this.searchInput.value = '';
                if (this.statusFilter) this.statusFilter.value = '1';
                
                const roleFilter = document.getElementById('roleFilter');
                if (roleFilter) roleFilter.value = '';
                const departmentFilter = document.getElementById('departmentFilter');
                if (departmentFilter) departmentFilter.value = '';
                const flagSendFilter = document.getElementById('flagSendFilter');
                if (flagSendFilter) flagSendFilter.value = '';

                if (this.monthFilter) {
                    this.monthFilter.value = new Date().toISOString().slice(0, 7);
                }
                this.toggleClearSearchBtn();
                this.submitForm();
            });
        }

        // Intercept pagination links
        document.addEventListener('click', (e) => {
            if (this.isLoading) {
                e.preventDefault();
                return;
            }
            const link = e.target.closest(`${this.tableContainerSelector} nav a`);
            if (link) {
                e.preventDefault();
                this.loadUrl(link.href);
            }
        });

        // Browser history handling
        window.addEventListener('popstate', () => {
            this.loadUrl(window.location.href, false);
        });

        this.toggleClearSearchBtn();
    }

    toggleClearSearchBtn() {
        if (this.searchInput && this.btnClearSearch) {
            if (this.searchInput.value.trim() !== '') {
                this.btnClearSearch.classList.remove('hidden');
            } else {
                this.btnClearSearch.classList.add('hidden');
            }
        }
    }

    submitForm() {
        if (!this.form) return;
        const url = this.form.action + '?' + new URLSearchParams(new FormData(this.form)).toString();
        this.loadUrl(url);
    }

    getSkeletonHtml() {
        let html = '';
        for (let i = 0; i < 10; i++) {
            html += `
            <tr class="animate-pulse h-[69px]">
                <td class="px-6 py-4"><div class="h-4 bg-gray-200 rounded w-16"></div></td>
                <td class="px-6 py-4"><div class="h-4 bg-gray-200 rounded w-48"></div></td>
                <td class="px-6 py-4"><div class="h-4 bg-gray-200 rounded w-12"></div></td>
                <td class="px-6 py-4"><div class="h-4 bg-gray-200 rounded w-12"></div></td>
                <td class="px-6 py-4"><div class="h-4 bg-gray-200 rounded w-16"></div></td>
                <td class="px-6 py-4"><div class="h-6 bg-gray-200 rounded-full w-20"></div></td>
                <td class="px-6 py-4"><div class="h-6 bg-gray-200 rounded-full w-20"></div></td>
                <td class="px-6 py-4"><div class="h-8 bg-gray-200 rounded w-20 ml-auto"></div></td>
            </tr>`;
        }
        return html;
    }

    async loadUrl(url, updateHistory = true) {
        if (this.isLoading) return;
        this.isLoading = true;

        if (this.spinner) {
            this.spinner.classList.remove('hidden');
        }

        let formElements = [];
        if (this.form) {
            formElements = this.form.querySelectorAll('input, select, button');
            formElements.forEach(el => el.disabled = true);
        }

        const tableContainer = document.querySelector(this.tableContainerSelector);
        const tableBody = tableContainer ? tableContainer.querySelector('tbody') : null;
        if (tableBody) {
            tableBody.innerHTML = this.getSkeletonHtml();
        }

        try {
            const [res] = await Promise.all([
                fetch(url, { headers: { 'X-Requested-With': 'XMLHttpRequest' } }),
                new Promise(resolve => setTimeout(resolve, 200)) // smooth transition
            ]);

            if (!res.ok) throw new Error('Network response was not ok');
            
            const contentType = res.headers.get('content-type');
            const updateDOM = async () => {
                if (contentType && contentType.includes('application/json')) {
                    const data = await res.json();
                    
                    const titleEl = document.getElementById('pageTitle');
                    if (titleEl && data.title !== undefined) {
                        titleEl.innerHTML = data.title;
                    }
                    
                    const statsEl = document.getElementById('statsGrid');
                    if (statsEl && data.stats !== undefined) {
                        statsEl.innerHTML = data.stats;
                    }
                    
                    if (tableContainer && data.table !== undefined) {
                        tableContainer.innerHTML = data.table;
                    }
                } else {
                    const html = await res.text();
                    const parser = new DOMParser();
                    const doc = parser.parseFromString(html, 'text/html');

                    const currentTitle = document.getElementById('pageTitle');
                    const newTitle = doc.getElementById('pageTitle');
                    if (currentTitle && newTitle) currentTitle.innerHTML = newTitle.innerHTML;

                    const currentGrid = document.getElementById('statsGrid');
                    const newGrid = doc.getElementById('statsGrid');
                    if (currentGrid && newGrid) currentGrid.innerHTML = newGrid.innerHTML;

                    const newTable = doc.querySelector(this.tableContainerSelector);
                    if (tableContainer && newTable) tableContainer.innerHTML = newTable.innerHTML;
                }
            };

            if (document.startViewTransition) {
                document.startViewTransition(updateDOM);
            } else {
                await updateDOM();
            }

            if (updateHistory) {
                window.history.pushState({}, '', url);
            }

            const newTableContainer = document.querySelector(this.tableContainerSelector);
            if (newTableContainer) {
                newTableContainer.scrollIntoView({
                    behavior: 'smooth',
                    block: 'start'
                });
            }

        } catch (err) {
            console.error('Error fetching data:', err);
            window.location.reload();
        } finally {
            this.isLoading = false;
            if (this.spinner) {
                this.spinner.classList.add('hidden');
            }
            if (this.form) {
                formElements.forEach(el => el.disabled = false);
            }
            this.toggleClearSearchBtn();
        }
    }
}
