<?= $this->extend('layout/management_layout') ?>
<?= $this->section('content') ?>

<?php
    helper('url');
    $assignRoleEndpoint = $assignRoleEndpoint ?? site_url('api/rolepermission/users');
    $rolesEndpoint      = $rolesEndpoint ?? site_url('api/rolepermission/roles');
?>

<div class="container-fluid"
     data-users-endpoint="<?= esc($assignRoleEndpoint) ?>"
     data-roles-endpoint="<?= esc($rolesEndpoint) ?>">
    <div class="wrapper">
        <div class="content"></div>
        <h2 class="text-center mt-4 mb-3">Assign Role to Users</h2>

        <?php if (session()->getFlashdata('success')): ?>
            <div class="alert alert-success"><?= esc(session()->getFlashdata('success')); ?></div>
        <?php elseif (session()->getFlashdata('error')): ?>
            <div class="alert alert-danger"><?= esc(session()->getFlashdata('error')); ?></div>
        <?php endif; ?>

        <div id="assignRoleAlert" class="alert alert-danger d-none" role="alert"></div>

        <div class="table-responsive">
            <table id="usersTable" class="display table table-bordered table-striped align-middle">
                <thead class="table-dark">
                    <tr>
                        <th>User ID</th>
                        <th>Account Number</th>
                        <th>Name</th>
                        <th>Email</th>
                        <th>Current Roles</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td colspan="6" class="text-center text-muted">Loading users…</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

<div class="modal fade" id="assignRoleModal" tabindex="-1" aria-labelledby="assignRoleModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <form method="post" action="<?= site_url('rolepermission/save_role'); ?>" id="assignRoleForm">
                <?= csrf_field(); ?>
                <div class="modal-header">
                    <h5 class="modal-title" id="assignRoleModalLabel">Assign Roles</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <input type="hidden" name="user_id" id="modal_user_id">
                    <div class="mb-3">
                        <label class="form-label">User</label>
                        <div id="modal_user_info" class="fw-semibold"></div>
                    </div>
                    <div class="form-group" id="modal_roles_container">
                        <label class="form-label">Select Roles</label>
                        <div id="modal_roles_list" class="d-flex flex-column gap-1"></div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                    <button type="submit" class="btn btn-primary">Save Roles</button>
                </div>
            </form>
        </div>
    </div>
</div>

<?= $this->endSection() ?>

<?= $this->section('scripts') ?>
<script>
    document.addEventListener('DOMContentLoaded', () => {
        // --- FixedHeader helpers ---
        function getFixedHeaderOffset() {
            let total = 0;
            const stack = [];
            const header = document.querySelector('header.navbar.sticky-top, header.navbar.fixed-top');
            if (header) stack.push(header);
            const mgmt = document.getElementById('navbarManagement');
            if (mgmt && (mgmt.classList.contains('sticky-top') || mgmt.classList.contains('fixed-top'))) stack.push(mgmt);
            document.querySelectorAll('.navbar.sticky-top, .navbar.fixed-top').forEach(el => { if (!stack.includes(el)) stack.push(el); });
            stack.forEach(el => { const h = el.offsetHeight || el.getBoundingClientRect().height || 0; total += Math.max(0, Math.round(h)); });
            return total;
        }

        function loadScript(src, id) {
            return new Promise((resolve, reject) => {
                if (id && document.getElementById(id)) return resolve();
                const s = document.createElement('script');
                if (id) s.id = id;
                s.src = src;
                s.onload = resolve;
                s.onerror = reject;
                document.head.appendChild(s);
            });
        }
        function loadCss(href, id) {
            return new Promise((resolve) => {
                if (id && document.getElementById(id)) return resolve();
                const l = document.createElement('link');
                if (id) l.id = id;
                l.rel = 'stylesheet';
                l.href = href;
                l.onload = resolve;
                document.head.appendChild(l);
            });
        }

        function ensureFixedHeaderAssets() {
            const hasFH = !!(window.jQuery && window.jQuery.fn && window.jQuery.fn.dataTable && window.jQuery.fn.dataTable.FixedHeader);
            if (hasFH) return Promise.resolve();
            return Promise.all([
                loadScript('https://cdn.jsdelivr.net/npm/datatables.net-fixedheader@3.4.0/js/dataTables.fixedHeader.min.js', 'dt-fixedheader'),
                loadCss('https://cdn.jsdelivr.net/npm/datatables.net-fixedheader-bs5@3.4.0/css/fixedHeader.bootstrap5.min.css', 'dt-fixedheader-css')
            ]).catch(() => {});
        }

        // Start loading FixedHeader assets early
        ensureFixedHeaderAssets();
        const container = document.querySelector('[data-users-endpoint]');
        if (!container) {
            return;
        }

        const usersEndpoint = container.dataset.usersEndpoint;
        const rolesEndpoint = container.dataset.rolesEndpoint;
        const alertBox = document.getElementById('assignRoleAlert');
        const tableBody = document.querySelector('#usersTable tbody');
        const modalElement = document.getElementById('assignRoleModal');
        const modalUserInfo = document.getElementById('modal_user_info');
        const modalUserId = document.getElementById('modal_user_id');
        const modalRolesList = document.getElementById('modal_roles_list');
        const modalInstance = modalElement ? new bootstrap.Modal(modalElement) : null;

        let users = [];
        let usersById = new Map();
        let roles = [];

        const hasDataTables = () =>
            !!(window.jQuery && window.jQuery.fn && window.jQuery.fn.DataTable);

        const destroyDataTable = () => {
            if (!hasDataTables()) return;
            if (window.jQuery.fn.DataTable.isDataTable('#usersTable')) {
                window.jQuery('#usersTable').DataTable().clear().destroy();
            }
        };

        const initDataTable = () => {
            if (!hasDataTables()) return;
            const opts = {
                pageLength: 100,
                lengthMenu: [5, 10, 25, 50, 100],
                columnDefs: [
                    { orderable: false, targets: [5] },
                ],
            };

            if (window.jQuery.fn.dataTable && window.jQuery.fn.dataTable.FixedHeader) {
                opts.fixedHeader = { header: true, headerOffset: getFixedHeaderOffset() };
            }

            const dt = window.jQuery('#usersTable').DataTable(opts);

            // If plugin finished loading slightly after init, attach FixedHeader instance
            if (!opts.fixedHeader) {
                ensureFixedHeaderAssets().then(() => {
                    if (window.jQuery.fn.dataTable && window.jQuery.fn.dataTable.FixedHeader) {
                        try { new window.jQuery.fn.dataTable.FixedHeader(dt, { header: true, headerOffset: getFixedHeaderOffset() }); } catch (_) {}
                    }
                });
            }
        };

        const showError = (message) => {
            if (!alertBox) return;
            alertBox.textContent = message;
            alertBox.classList.remove('d-none');
        };

        const clearError = () => {
            if (!alertBox) return;
            alertBox.textContent = '';
            alertBox.classList.add('d-none');
        };

        const buildRolesMarkup = (selectedIds = []) => {
            modalRolesList.innerHTML = '';
            const selectedSet = new Set(selectedIds.map((id) => Number(id)));

            if (!Array.isArray(roles) || roles.length === 0) {
                modalRolesList.innerHTML = '<div class="text-muted">No roles available.</div>';
                return;
            }

            roles.forEach((role) => {
                const checkboxId = `roleCheck_${role.id}`;
                const wrapper = document.createElement('div');
                wrapper.classList.add('form-check');

                const input = document.createElement('input');
                input.type = 'checkbox';
                input.className = 'form-check-input';
                input.name = 'role_ids[]';
                input.value = role.id;
                input.id = checkboxId;
                if (selectedSet.has(Number(role.id))) {
                    input.checked = true;
                }

                const label = document.createElement('label');
                label.className = 'form-check-label';
                label.htmlFor = checkboxId;
                label.textContent = role.name ?? '';

                wrapper.appendChild(input);
                wrapper.appendChild(label);
                modalRolesList.appendChild(wrapper);
            });
        };

        const openModalForUser = (userId) => {
            const user = usersById.get(userId);
            if (!user || !modalInstance) return;

            modalUserId.value = user.id ?? '';
            const fullName = `${user.firstname ?? ''} ${user.lastname ?? ''}`.trim();
            modalUserInfo.textContent = `${fullName} (${user.email ?? ''})`;

            buildRolesMarkup([]);
            const selectedRoleIds = [];
            if (Array.isArray(user.roles) && user.roles.length > 0) {
                const lookup = new Map(roles.map((role) => [role.name, role.id]));
                user.roles.forEach((roleName) => {
                    if (lookup.has(roleName)) {
                        selectedRoleIds.push(lookup.get(roleName));
                    }
                });
            }
            buildRolesMarkup(selectedRoleIds);
            modalInstance.show();
        };

        const renderNameCell = (user) => {
            const td = document.createElement('td');
            const fullName = `${user?.firstname ?? ''} ${user?.lastname ?? ''}`.trim();
            const label = fullName !== '' ? fullName : '—';
            const roleList = Array.isArray(user?.roles)
                ? user.roles.map((role) => (role || '').toString().toLowerCase())
                : [];
            const isParent = roleList.includes('parent');
            const uid = Number(user?.id || 0);

            if (isParent && uid > 0) {
                const link = document.createElement('a');
                link.href = '#';
                link.className = 'text-decoration-none';
                link.setAttribute('data-family-guardian-id', String(uid));
                link.textContent = label;
                td.appendChild(link);
                return td;
            }

            td.textContent = label;
            return td;
        };

        const renderTable = () => {
            if (!tableBody) return;

            destroyDataTable();
            tableBody.innerHTML = '';

            if (!Array.isArray(users) || users.length === 0) {
                const row = document.createElement('tr');
                const cell = document.createElement('td');
                cell.colSpan = 6;
                cell.classList.add('text-center', 'text-muted');
                cell.textContent = 'No users found.';
                row.appendChild(cell);
                tableBody.appendChild(row);
                return;
            }

            users.forEach((user) => {
                usersById.set(user.id, user);

                const row = document.createElement('tr');

                const userIdCell = document.createElement('td');
                userIdCell.textContent = user.id ?? '';
                row.appendChild(userIdCell);

                const accountCell = document.createElement('td');
                accountCell.textContent = user.account_id ?? '';
                row.appendChild(accountCell);

                row.appendChild(renderNameCell(user));

                const emailCell = document.createElement('td');
                emailCell.textContent = user.email ?? '';
                row.appendChild(emailCell);

                const rolesCell = document.createElement('td');
                if (Array.isArray(user.roles) && user.roles.length > 0) {
                    rolesCell.innerHTML = user.roles
                        .map((role) => `<span class="badge bg-primary me-1 mb-1">${role}</span>`)
                        .join('');
                } else {
                    rolesCell.innerHTML = '<span class="text-muted">No role assigned</span>';
                }
                row.appendChild(rolesCell);

                const actionsCell = document.createElement('td');
                const button = document.createElement('button');
                button.type = 'button';
                button.className = 'btn btn-primary btn-sm';
                button.textContent = 'Assign / Update Roles';
                button.addEventListener('click', () => openModalForUser(user.id));
                actionsCell.appendChild(button);
                row.appendChild(actionsCell);

                tableBody.appendChild(row);
            });

            initDataTable();
        };

        const fetchRoles = () => {
            if (!rolesEndpoint) return Promise.resolve();
            return fetch(rolesEndpoint, {
                headers: { 'Accept': 'application/json' },
                credentials: 'same-origin',
            })
                .then((response) => {
                    if (!response.ok) {
                        throw new Error(`Roles request failed with status ${response.status}`);
                    }
                    return response.json();
                })
                .then((payload) => {
                    roles = Array.isArray(payload?.roles) ? payload.roles : [];
                });
        };

        const fetchUsers = () => {
            if (!usersEndpoint) return;

            tableBody.innerHTML = `
                <tr>
                    <td colspan="6" class="text-center text-muted">Loading users…</td>
                </tr>
            `;

            return fetch(usersEndpoint, {
                headers: { 'Accept': 'application/json' },
                credentials: 'same-origin',
            })
                .then((response) => {
                    if (!response.ok) {
                        throw new Error(`Users request failed with status ${response.status}`);
                    }
                    return response.json();
                })
                .then((payload) => {
                    users = Array.isArray(payload?.users) ? payload.users : [];
                    clearError();
                    renderTable();
                })
                .catch((error) => {
                    console.error(error);
                    showError('Unable to load users.');
                    destroyDataTable();
                    tableBody.innerHTML = `
                        <tr>
                            <td colspan="6" class="text-center text-danger">Failed to load users.</td>
                        </tr>
                    `;
                });
        };

        fetchRoles()
            .then(fetchUsers)
            .catch((error) => {
                console.error(error);
                showError('Unable to load roles.');
            });
    });
</script>
<?= $this->endSection() ?>
