import { apiGet, apiPost } from '../api.js';
import { pageHeaderHTML, showToast } from '../app.js';
import { confirmAction } from '../confirm-modal.js';

const CLIENT_PAGE_SIZE = 50;

let coaches = [];
let clients = [];
let selectedCoachID = null;
let filterCoachSearch = '';
let clientsByCoach = {};
let clientPage = 0;
let selectedClientCodes = new Set();

export async function assignmentsPage() {
    selectedCoachID = null;
    filterCoachSearch = '';
    clientPage = 0;
    selectedClientCodes = new Set();
    const app = document.getElementById('app');

    app.innerHTML = `
        ${pageHeaderHTML('Assign Clients')}
        <div id="assignContent"><div class="spinner"></div></div>
    `;

    try {
        const data = await apiGet('assignments.php');
        coaches = data.coaches || [];
        clients = data.clients || [];
        rebuildClientsByCoach();
        renderAssignments();
    } catch (e) {
        showToast(e.message, 'error');
        document.getElementById('assignContent').innerHTML =
            `<p class="error-text" style="padding:16px">${esc(e.message)}</p>`;
    }
}

function rebuildClientsByCoach() {
    clientsByCoach = {};
    clients.forEach(c => {
        if (c.coachID) {
            (clientsByCoach[c.coachID] = clientsByCoach[c.coachID] || []).push(c);
        }
    });
}

function renderAssignments() {
    const container = document.getElementById('assignContent');

    if (!coaches.length) {
        container.innerHTML = `
            <div class="card empty-state">
                <h3>No counselors found</h3>
                <p>Create counselors first before assigning clients.</p>
            </div>`;
        return;
    }

    const unassignedCount = clients.filter(c => !c.coachID).length;

    container.innerHTML = `
        <div class="assign-page">
            <div class="assign-layout">

                <aside class="card assign-coaches" aria-label="Counselors">
                    <div class="assign-panel-header">
                        <h3>Counselors <span class="data-toolbar-hint">(${coaches.length})</span></h3>
                        <div class="filter-bar">
                            <input type="search" id="coachSearch" class="filter-search"
                                placeholder="Search counselor or supervisor…" value="${esc(filterCoachSearch)}">
                        </div>
                    </div>
                    <div class="assign-panel-body">
                        <ul class="coach-list" id="coachList" role="listbox" aria-label="Filter by counselor"></ul>
                    </div>
                </aside>

                <section class="card assign-clients-card" aria-label="Clients">
                        <div class="assign-clients-toolbar">
                            <div class="assign-clients-toolbar-top">
                                <h3>Clients <span class="data-toolbar-hint" id="clientListSummary"></span></h3>
                                <div class="assign-clients-actions">
                                    <button type="button" class="btn btn-sm" id="selectAllBtn">Select visible</button>
                                    <button type="button" class="btn btn-sm" id="clearSelBtn">Clear</button>
                                </div>
                            </div>
                            <div class="assign-clients-filters filter-bar">
                                <select id="filterByCoach" aria-label="Filter by counselor">
                                    <option value="">All counselors (${clients.length})</option>
                                    <option value="__unassigned__">Unassigned (${unassignedCount})</option>
                                    ${coaches.map(c => {
                                        const n = (clientsByCoach[c.coachID] || []).length;
                                        return `<option value="${c.coachID}">${esc(c.username)} (${n})</option>`;
                                    }).join('')}
                                </select>
                                <input type="search" id="clientSearch" class="filter-search"
                                    placeholder="Search client or counselor…">
                            </div>
                        </div>
                        <div class="assign-table-panel">
                            <div class="table-wrapper assign-table-scroll">
                                <table class="data-table">
                                    <thead>
                                        <tr>
                                            <th style="width:40px">
                                                <input type="checkbox" id="selectAllCb" title="Toggle all visible rows" aria-label="Select all visible">
                                            </th>
                                            <th>Client Code</th>
                                            <th>Current counselor</th>
                                        </tr>
                                    </thead>
                                    <tbody id="clientTableBody"></tbody>
                                </table>
                            </div>
                        </div>
                        <div class="assign-clients-footer">
                            <div class="pagination-bar" id="clientPagination"></div>
                            <div id="selectionInfo" class="selection-info" style="display:none"></div>
                        </div>
                </section>
            </div>

            <section class="card assign-action-card" id="assignActionCard" style="display:none" aria-label="Assign selection">
                <h4>Assign selected clients to</h4>
                <div class="assign-action-row">
                    <select id="targetCoachSelect" aria-label="Target counselor">
                        <option value="">— select counselor —</option>
                        ${coaches.map(c =>
                            `<option value="${c.coachID}">${esc(c.username)}${c.supervisorUsername ? ` (${esc(c.supervisorUsername)})` : ''}</option>`
                        ).join('')}
                    </select>
                    <button type="button" class="btn btn-primary" id="assignBtn">Assign</button>
                </div>
            </section>
        </div>
    `;

    document.getElementById('coachSearch').addEventListener('input', (e) => {
        filterCoachSearch = e.target.value;
        renderCoachList();
    });

    document.getElementById('coachList').addEventListener('click', (e) => {
        const item = e.target.closest('.coach-list-item');
        if (!item || item.dataset.action === 'clear-filter') return;
        document.querySelectorAll('.coach-list-item').forEach(x => x.classList.remove('active'));
        item.classList.add('active');
        selectedCoachID = item.dataset.id;
        document.getElementById('filterByCoach').value = selectedCoachID;
        clientPage = 0;
        renderClientRows();
    });

    document.getElementById('filterByCoach').addEventListener('change', (e) => {
        const value = e.target.value;
        clientPage = 0;
        if (value && value !== '__unassigned__') {
            selectedCoachID = value;
            highlightCoachInList(value);
        } else {
            selectedCoachID = null;
            document.querySelectorAll('.coach-list-item').forEach(x => x.classList.remove('active'));
        }
        renderClientRows();
    });

    document.getElementById('clientSearch').addEventListener('input', () => {
        clientPage = 0;
        renderClientRows();
    });

    document.getElementById('selectAllBtn').addEventListener('click', () => {
        document.querySelectorAll('#clientTableBody .client-cb').forEach(cb => {
            cb.checked = true;
            selectedClientCodes.add(cb.value);
        });
        updateSelectionInfo();
    });
    document.getElementById('clearSelBtn').addEventListener('click', () => {
        selectedClientCodes.clear();
        document.querySelectorAll('#clientTableBody .client-cb').forEach(cb => { cb.checked = false; });
        syncSelectAllCb();
        updateSelectionInfo();
    });
    document.getElementById('selectAllCb').addEventListener('change', (e) => {
        document.querySelectorAll('#clientTableBody .client-cb').forEach(cb => {
            cb.checked = e.target.checked;
            if (e.target.checked) selectedClientCodes.add(cb.value);
            else selectedClientCodes.delete(cb.value);
        });
        updateSelectionInfo();
    });

    document.getElementById('assignBtn').addEventListener('click', doAssign);

    renderCoachList();
    renderClientRows();
}

function getFilteredCoaches() {
    const q = filterCoachSearch.trim().toLowerCase();
    if (!q) return coaches;
    return coaches.filter(c => {
        const hay = `${c.username} ${c.supervisorUsername || ''}`.toLowerCase();
        return hay.includes(q);
    });
}

function renderCoachList() {
    const list = document.getElementById('coachList');
    if (!list) return;

    const filtered = getFilteredCoaches();
    const q = filterCoachSearch.trim();

    if (!filtered.length) {
        list.innerHTML = `<li class="coach-list-empty">${q ? 'No counselors match' : 'No counselors'}</li>`;
        return;
    }

    list.innerHTML = filtered.map(c => coachListItemHTML(c)).join('');

    if (selectedCoachID) {
        highlightCoachInList(selectedCoachID);
    }
}

function coachListItemHTML(c) {
    const count = (clientsByCoach[c.coachID] || []).length;
    const active = selectedCoachID === c.coachID ? ' active' : '';
    return `
        <li class="coach-list-item${active}" data-id="${c.coachID}" role="option" tabindex="0">
            <div class="coach-name">${esc(c.username)}</div>
            ${c.supervisorUsername
                ? `<div class="coach-supervisor">${esc(c.supervisorUsername)}</div>`
                : ''}
            <span class="coach-client-count">${count} client${count === 1 ? '' : 's'}</span>
        </li>`;
}

function highlightCoachInList(coachID) {
    document.querySelectorAll('.coach-list-item').forEach(li => {
        li.classList.toggle('active', li.dataset.id === coachID);
    });
    const active = document.querySelector(`.coach-list-item[data-id="${CSS.escape(coachID)}"]`);
    active?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}

function getVisibleClients() {
    const coachFilter = document.getElementById('filterByCoach')?.value ?? '';
    const search = document.getElementById('clientSearch')?.value.trim().toLowerCase() ?? '';
    let visible = clients;
    if (coachFilter === '__unassigned__') {
        visible = clients.filter(c => !c.coachID);
    } else if (coachFilter) {
        visible = clients.filter(c => c.coachID === coachFilter);
    }
    if (search) {
        visible = visible.filter(c => {
            const hay = `${c.clientCode} ${c.coachUsername || ''}`.toLowerCase();
            return hay.includes(search);
        });
    }
    return visible;
}

function updateClientSummary(filteredCount, pageSlice) {
    const el = document.getElementById('clientListSummary');
    if (!el) return;
    const search = document.getElementById('clientSearch')?.value.trim() ?? '';
    const coachFilter = document.getElementById('filterByCoach')?.value ?? '';
    const hasFilter = search || coachFilter;
    const parts = [];
    if (hasFilter && filteredCount !== clients.length) {
        parts.push(`${filteredCount} of ${clients.length} match`);
    } else {
        parts.push(String(clients.length));
    }
    if (pageSlice && filteredCount > CLIENT_PAGE_SIZE) {
        const from = clientPage * CLIENT_PAGE_SIZE + 1;
        const to = Math.min((clientPage + 1) * CLIENT_PAGE_SIZE, filteredCount);
        parts.push(`rows ${from}–${to}`);
    }
    el.textContent = `(${parts.join(', ')})`;
}

function renderPaginationBar(barId, totalRows, currentPage, pageSize, onPageChange) {
    const pag = document.getElementById(barId);
    if (!pag) return;

    if (!totalRows) {
        pag.innerHTML = '';
        return;
    }

    const totalPages = Math.max(1, Math.ceil(totalRows / pageSize));
    if (totalRows <= pageSize) {
        pag.innerHTML = `<span>${totalRows} row${totalRows === 1 ? '' : 's'}</span>`;
        return;
    }

    const from = currentPage * pageSize + 1;
    const to = Math.min((currentPage + 1) * pageSize, totalRows);
    const prevId = `${barId}Prev`;
    const nextId = `${barId}Next`;
    pag.innerHTML = `
        <button type="button" class="btn btn-sm" id="${prevId}" ${currentPage <= 0 ? 'disabled' : ''}>Prev</button>
        <span>Rows ${from}–${to} of ${totalRows} (page ${currentPage + 1}/${totalPages})</span>
        <button type="button" class="btn btn-sm" id="${nextId}" ${currentPage >= totalPages - 1 ? 'disabled' : ''}>Next</button>
    `;
    document.getElementById(prevId)?.addEventListener('click', () => onPageChange(currentPage - 1));
    document.getElementById(nextId)?.addEventListener('click', () => onPageChange(currentPage + 1));
}

function syncSelectAllCb(codesOnPage = []) {
    const allCb = document.getElementById('selectAllCb');
    if (!allCb) return;
    if (!codesOnPage.length) {
        allCb.checked = false;
        allCb.indeterminate = false;
        return;
    }
    const allSelected = codesOnPage.every(code => selectedClientCodes.has(code));
    const someSelected = codesOnPage.some(code => selectedClientCodes.has(code));
    allCb.checked = allSelected;
    allCb.indeterminate = !allSelected && someSelected;
}

function renderClientRows() {
    const body = document.getElementById('clientTableBody');
    if (!body) return;

    const visible = getVisibleClients();
    const totalPages = Math.max(1, Math.ceil(visible.length / CLIENT_PAGE_SIZE));
    if (clientPage >= totalPages) clientPage = totalPages - 1;

    if (!visible.length) {
        updateClientSummary(0, false);
        body.innerHTML = `
            <tr>
                <td colspan="3" style="text-align:center;color:var(--text-secondary);padding:28px 16px">
                    No clients match the current filters
                </td>
            </tr>`;
        renderPaginationBar('clientPagination', 0, clientPage, CLIENT_PAGE_SIZE, (p) => {
            clientPage = p;
            renderClientRows();
        });
        syncSelectAllCb();
        updateSelectionInfo();
        return;
    }

    const slice = visible.slice(clientPage * CLIENT_PAGE_SIZE, (clientPage + 1) * CLIENT_PAGE_SIZE);
    updateClientSummary(visible.length, visible.length > CLIENT_PAGE_SIZE);

    body.innerHTML = slice.map(c => {
        const checked = selectedClientCodes.has(c.clientCode) ? ' checked' : '';
        return `
        <tr>
            <td>
                <input type="checkbox" class="client-cb" data-code="${esc(c.clientCode)}" value="${esc(c.clientCode)}"${checked} aria-label="Select ${esc(c.clientCode)}">
            </td>
            <td><strong>${esc(c.clientCode)}</strong></td>
            <td>${c.coachUsername
                ? esc(c.coachUsername)
                : '<span style="color:var(--text-secondary);font-style:italic">Unassigned</span>'}</td>
        </tr>`;
    }).join('');

    body.querySelectorAll('.client-cb').forEach(cb => {
        cb.addEventListener('change', () => {
            if (cb.checked) selectedClientCodes.add(cb.value);
            else selectedClientCodes.delete(cb.value);
            syncSelectAllCb(slice.map(c => c.clientCode));
            updateSelectionInfo();
        });
    });

    renderPaginationBar('clientPagination', visible.length, clientPage, CLIENT_PAGE_SIZE, (p) => {
        clientPage = p;
        renderClientRows();
    });
    syncSelectAllCb(slice.map(c => c.clientCode));
    updateSelectionInfo();
}

function getSelectedCodes() {
    return [...selectedClientCodes];
}

function updateSelectionInfo() {
    const selected = getSelectedCodes();
    const info = document.getElementById('selectionInfo');
    const card = document.getElementById('assignActionCard');
    const onPage = document.querySelectorAll('#clientTableBody .client-cb:checked').length;

    if (!selected.length) {
        info.style.display = 'none';
        card.style.display = 'none';
        return;
    }
    info.style.display = '';
    const extra = selected.length > onPage
        ? ` <span class="data-toolbar-hint">(${onPage} on this page)</span>`
        : '';
    info.innerHTML = `<strong>${selected.length}</strong> client${selected.length === 1 ? '' : 's'} selected${extra}`;
    card.style.display = '';
    if (selectedCoachID) {
        const sel = document.getElementById('targetCoachSelect');
        if (sel) sel.value = selectedCoachID;
    }
}

async function doAssign() {
    const selected = getSelectedCodes();
    const coachID = document.getElementById('targetCoachSelect').value;

    if (!selected.length) { showToast('Select at least one client', 'error'); return; }
    if (!coachID) { showToast('Select a target counselor', 'error'); return; }

    const coachName = coaches.find(c => c.coachID === coachID)?.username || coachID;
    if (!(await confirmAction({
        title: 'Assign clients',
        message: `Assign ${selected.length} client(s) to ${coachName}?`,
        confirmLabel: 'Assign',
    }))) return;

    const btn = document.getElementById('assignBtn');
    btn.disabled = true;
    btn.textContent = 'Assigning...';

    try {
        const data = await apiPost('assignments.php', { clientCodes: selected, coachID });
        if (data.success) {
            selected.forEach(code => {
                const c = clients.find(x => x.clientCode === code);
                if (c) {
                    c.coachID = coachID;
                    c.coachUsername = coachName;
                }
            });
            selectedClientCodes.clear();
            rebuildClientsByCoach();
            showToast(`${data.assigned} client(s) assigned to ${coachName}`, 'success');
            renderAssignments();
        }
    } catch (e) {
        showToast(e.message, 'error');
        btn.disabled = false;
        btn.textContent = 'Assign';
    }
}

function esc(s) {
    const d = document.createElement('div');
    d.textContent = s ?? '';
    return d.innerHTML;
}
