// ============================================================
// Easy ERP - HR & Payroll Module (hr.js)
// Version: 3.0 - Full Rewrite
// ============================================================

window.HRApp = (function () {
    'use strict';

    // --- State ---
    let currentUser = null;
    let employees = [];
    let advances = [];
    let payrolls = [];
    let accounts = [];
    let projects = [];
    let transactions = [];
    let users = [];

    let advancesAccountId = null;
    let salariesExpenseAccountId = null;
    let accruedSalariesAccountId = null;

    window.hrPayrollGrid = [];

    // Pagination state
    window.hrEmployeesPage = 1;
    window.hrArchivePage = 1;
    
    function renderPaginationControls(totalItems, currentPage, containerId, onPageChangeCallbackName) {
        const totalPages = Math.ceil(totalItems / 100);
        const container = document.getElementById(containerId);
        if (!container) return;
        if (totalPages <= 1) {
            container.innerHTML = '';
            return;
        }
        
        let html = `<div style="display:flex; justify-content:center; gap:5px; margin-top:10px; flex-wrap:wrap;">`;
        for (let i = 1; i <= totalPages; i++) {
            html += `<button class="action-btn" style="padding:5px 10px; background:${i === currentPage ? 'var(--hr-primary)' : '#eee'}; color:${i === currentPage ? '#fff' : '#333'}; min-width:30px;" onclick="window.${onPageChangeCallbackName}(${i})">${i}</button>`;
        }
        html += `</div>`;
        container.innerHTML = html;
    }
    
    // Global filter/pagination methods
    window.changeEmployeesPage = function(page) { window.hrEmployeesPage = page; renderEmployees(); };
    window.changeAdvancesPage  = function(page) { window.advancesCurrentPage = page; renderAdvances(); };
    window.changeArchivePage   = function(page) { window.hrArchivePage = page; renderArchive(); };
    
    // ======================
    // INIT & AUTH
    // ======================

    async function waitForDB() {
        let tries = 0;
        while ((!window.DB || typeof window.DB.getAll !== 'function') && tries < 40) {
            await new Promise(r => setTimeout(r, 250));
            tries++;
        }
        return !!(window.DB && typeof window.DB.getAll === 'function');
    }

    async function openApp() {
        const loader = document.getElementById('loading-overlay');
        if (loader) loader.style.display = 'flex';

        try {
            document.getElementById('current-username').innerText =
                currentUser.name || currentUser.username || 'مستخدم';
            document.getElementById('view-login').style.display = 'none';
            document.getElementById('app-layout').style.display = 'flex';
            const ok = await waitForDB();
            if (!ok) { alert('لم نتمكن من الوصول لقاعدة البيانات. يرجى التحديث.'); return; }
            await loadData();
            setupNavigation();
            showView('hr-dashboard');
        } finally {
            if (loader) loader.style.display = 'none';
        }
    }

    async function init() {
        try {
            const raw = sessionStorage.getItem('currentUser');
            if (raw) {
                currentUser = JSON.parse(raw);
                await openApp();
            }
            // else: remain on login screen
        } catch (e) {
            console.error('HR init error:', e);
        }
    }

    async function loginFromForm() {
        const errEl = document.getElementById('login-error');
        errEl.style.display = 'none';
        
        // Remove .trim() to strictly match the main app's behavior (which allows spaces)
        const username = document.getElementById('login-username').value || '';
        const password = document.getElementById('login-password').value || '';
        
        if (!username || !password) {
            errEl.innerText = 'يرجى إدخال اسم المستخدم وكلمة المرور';
            errEl.style.display = 'block';
            return;
        }
        
        const ok = await waitForDB();
        if (!ok) {
            errEl.innerText = 'خطأ في الاتصال بقاعدة البيانات';
            errEl.style.display = 'block';
            return;
        }
        
        try {
            // Use the standard window.DB.login to perfectly match main app's fallback/sync logic
            const found = await window.DB.login(username, password);
            if (found) {
                currentUser = found;
                sessionStorage.setItem('currentUser', JSON.stringify(found));
                await openApp();
            } else {
                errEl.innerText = 'اسم المستخدم أو كلمة المرور غير صحيحة';
                errEl.style.display = 'block';
            }
        } catch (e) {
            errEl.innerText = 'حدث خطأ، يرجى المحاولة مجدداً';
            errEl.style.display = 'block';
            console.error(e);
        }
    }

    function logout() {
        sessionStorage.removeItem('currentUser');
        window.location.href = 'index.html';
    }

    // ======================
    // DATA LOADING
    // ======================

    // Safely convert any DB result to a real JS array
    function toArray(val) {
        if (!val) return [];
        if (Array.isArray(val)) return val;
        if (typeof val === 'object') return Object.values(val);
        return [];
    }

    async function loadData() {
        const loader = document.getElementById('loading-overlay');
        if (loader) loader.style.display = 'flex';
        try {
             accounts     = toArray(await window.DB.getAll('accounts'));
            projects     = toArray(await window.DB.getAll('projects'));
            users        = toArray(await window.DB.getAll('users'));
            transactions = toArray(await window.DB.getAll('journal_entries'));
            employees    = toArray(await window.DB.getAll('employees'));
            advances     = toArray(await window.DB.getAll('advances'));
            payrolls     = toArray(await window.DB.getAll('payrolls'));
            await ensureSystemAccounts();
            await oneTimeDataFix_20260801();
            selfHealAdvances();
            await healOrphanedJournals(); // Automatically link orphaned journals to their payrolls
        } finally {
            if (loader) loader.style.display = 'none';
        }
    }
    
    async function oneTimeDataFix_20260801() {
        const fixKey = 'hr_fix_20260801_v2';
        if (localStorage.getItem(fixKey)) return;
        
        let changed = false;
        
        // Fix 1: حسام عشرى advance id=14 - installments should be 5, start_month should be 2026-04
        const adv14 = advances.find(a => String(a.id) === '14' && String(a.employee_id) === '30');
        if (adv14 && parseInt(adv14.installments) === 1 && parseFloat(adv14.amount) === 5000) {
//             console.log('[DATA FIX] Fixing advance id=14 for حسام: installments 1→5, start_month→2026-04');
            adv14.installments = 5;
            adv14.start_month = '2026-04';
            adv14.paid_amount = 0; // Let selfHealAdvances recalculate
            adv14.status = 'active';
            delete adv14._last_updated;
            await window.DB.update('advances', adv14);
            changed = true;
        }
        
        // Fix 2: Find and fix journal entry reference for payroll #18 (أبوقرقاص) 
        const p18 = payrolls.find(p => String(p.id) === '18' && p.status !== 'draft');
        if (p18 && !transactions.some(t => t.reference === 'PR-18')) {
            const grid = JSON.parse(p18.grid || '[]');
            const totalAdvances = grid.reduce((sum, row) => sum + (parseFloat(row.advanceDeduction) || 0), 0);
            const totalNet = parseFloat(p18.net_total) || 0;
            const expectedTotal = totalNet + totalAdvances;
            
//             console.log('[DATA FIX] Searching for existing journal entry for payroll #18, expectedTotal=' + expectedTotal + ', month=' + p18.month);
            
            // Log all journal entries to help find the right one
            transactions.forEach(t => {
                if (t.desc && t.desc.includes(p18.month)) {
//                     console.log(`[DATA FIX]   Candidate journal: id=${t.id}, ref=${t.reference}, total=${t.total}, desc=${t.desc}`);
                }
            });
            
            // Search broadly: any journal that mentions the same month and has a close total
            const existingJournal = transactions.find(t => {
                if (t.reference === 'PR-18') return false; // Already correct
                if (!t.desc) return false;
                if (!t.desc.includes(p18.month)) return false;
                // Check if total matches approximately
                if (Math.abs((parseFloat(t.total) || 0) - expectedTotal) < 1) return true;
                // Also try matching by project name in description
                const projName = p18.project_id && p18.project_id !== 'all' 
                    ? (projects.find(pr => String(pr.id) === String(p18.project_id)) || {}).name || '' 
                    : '';
                if (projName && t.desc.includes(projName) && t.desc.includes('رواتب')) return true;
                return false;
            });
            
            if (existingJournal) {
//                 console.log(`[DATA FIX] >>> Found journal for payroll #18: id=${existingJournal.id}, old ref=${existingJournal.reference}. Fixing to PR-18`);
                existingJournal.reference = 'PR-18';
                delete existingJournal._last_updated;
                await window.DB.update('journal_entries', existingJournal);
                changed = true;
            } else {
                // Journal was deleted - recreate it
//                 console.log('[DATA FIX] Journal for payroll #18 was deleted. Recreating...');
                const projName = p18.project_id && p18.project_id !== 'all' 
                    ? (projects.find(pr => String(pr.id) === String(p18.project_id)) || {}).name || '' 
                    : 'جميع المشاريع';
                
                const transRows = [];
                if (expectedTotal > 0) {
                    const parsedProjId = (p18.project_id === 'all' || !p18.project_id) ? null : parseInt(p18.project_id);
                    transRows.push({ account_id: salariesExpenseAccountId, debit: expectedTotal, credit: 0, project_id: parsedProjId });
                    transRows.push({ account_id: accruedSalariesAccountId, debit: 0, credit: totalNet, project_id: parsedProjId });
                }
                if (totalAdvances > 0) {
                    transRows.push({ account_id: advancesAccountId, debit: 0, credit: totalAdvances, project_id: null });
                }
                
                const journalEntry = {
                    id: Date.now() + 100,
                    date: p18.date || new Date().toISOString().split('T')[0],
                    desc: `استحقاق رواتب ${p18.month} - ${projName}`,
                    reference: 'PR-18',
                    status: 'posted',
                    created_by: 'إصلاح تلقائي',
                    total: expectedTotal,
                    rows: transRows
                };
                
                await window.DB.add('journal_entries', journalEntry);
                transactions.push(journalEntry);
                
                // Update account balances
                if (expectedTotal > 0) await updateAccountBalance(salariesExpenseAccountId, expectedTotal, 0);
                if (totalNet > 0) await updateAccountBalance(accruedSalariesAccountId, 0, totalNet);
                if (totalAdvances > 0) await updateAccountBalance(advancesAccountId, 0, totalAdvances);
                
//                 console.log('[DATA FIX] >>> Journal for payroll #18 recreated successfully!');
                changed = true;
            }
        }
        
        if (changed) {
//             console.log('[DATA FIX] Data fix applied successfully!');
        }
        localStorage.setItem(fixKey, 'done');
    }
    
    async function healOrphanedJournals() {
        let patched = false;
        const missing = payrolls.filter(p => p.status !== 'draft' && !transactions.some(t => t.reference === 'PR-' + p.id));
        
//         console.log(`[DEBUG HEAL-JOURNALS] Found ${missing.length} payrolls without journal entries`);
        
        for (const p of missing) {
            const grid = JSON.parse(p.grid || '[]');
            const totalAdvances = grid.reduce((sum, row) => sum + (parseFloat(row.advanceDeduction) || 0), 0);
            const expectedTotal = (parseFloat(p.net_total) || 0) + totalAdvances;
            
//             console.log(`[DEBUG HEAL-JOURNALS] Payroll id=${p.id} month=${p.month} expectedTotal=${expectedTotal}`);
            
            // Search for any orphaned journal that:
            // 1. Has a PR- reference that doesn't match any existing payroll, OR has no reference, OR has PR-undefined
            // 2. Mentions this payroll's month in description
            // 3. Has a matching total
            const orphan = transactions.find(t => {
                if (!t.desc || !t.desc.includes(p.month)) return false;
                if (Math.abs((parseFloat(t.total) || 0) - expectedTotal) >= 1) return false;
                
                // Check if this journal's reference is orphaned (doesn't point to a valid payroll)
                if (!t.reference) return true;
                if (t.reference === 'PR-undefined') return true;
                if (t.reference.startsWith('PR-')) {
                    const refId = t.reference.replace('PR-', '');
                    // If this PR- reference doesn't match any existing payroll, it's orphaned
                    const referencedPayroll = payrolls.find(px => String(px.id) === refId);
                    if (!referencedPayroll) return true;
                    // If it references a different payroll that already has its own journal, it's available
                    if (String(referencedPayroll.id) !== String(p.id)) {
                        const alreadyHasJournal = transactions.some(tx => tx !== t && tx.reference === t.reference);
                        if (alreadyHasJournal) return true;
                    }
                }
                return false;
            });
            
            if (orphan) {
//                 console.log(`[DEBUG HEAL-JOURNALS] >>> Found orphan journal id=${orphan.id} ref=${orphan.reference} for payroll id=${p.id}. Fixing...`);
                orphan.reference = 'PR-' + p.id;
                delete orphan._last_updated;
                await window.DB.update('journal_entries', orphan);
                patched = true;
            } else {
//                 console.log(`[DEBUG HEAL-JOURNALS] No orphan found for payroll id=${p.id}. Will remain as محذوف من الحسابات.`);
            }
        }
        
        if (patched) {
            transactions = toArray(await window.DB.getAll('journal_entries'));
        }
    }

    async function ensureSystemAccounts() {
        const ensure = async (name, type, offset, defaultCode) => {
            let acc = accounts.find(a => a.name === name);
            if (!acc) {
                // If it wasn't found, check if it exists in DB directly to avoid race conditions
                const all = await window.DB.getAll('accounts');
                acc = all.find(a => a.name === name);
                if (!acc) {
                    const id = Date.now() + offset;
                    acc = { id, name, type, balance: 0, parent_id: '', code: defaultCode };
                    try { 
                        const resId = await window.DB.add('accounts', acc);
                        if (resId) acc.id = resId; // DB.add returns the integer ID directly
                    } catch (e) {}
                }
                accounts.push(acc);
            }
            
            // Fix existing account if it lacks a code
            if (!acc.code) {
                acc.code = defaultCode;
                try { await window.DB.update('accounts', acc); } catch(e){}
            }

            return acc.id;
        };
        advancesAccountId        = await ensure('سلف العاملين', 'أصول متداولة', 0, '1201');
        salariesExpenseAccountId = await ensure('مصروفات الرواتب والأجور', 'مصروفات', 1, '5101');
        accruedSalariesAccountId = await ensure('رواتب وأجور مستحقة', 'أرصدة دائنة', 2, '2201');
    }

    // ======================
    // NAVIGATION
    // ======================

    function setupNavigation() {
        document.querySelectorAll('.hr-nav-link').forEach(link => {
            link.addEventListener('click', e => {
                if (link.getAttribute('href') === 'index.html' || link.getAttribute('href') === 'ready_mix.html') return;
                e.preventDefault();
                document.querySelectorAll('.hr-nav-link').forEach(l => l.classList.remove('active'));
                link.classList.add('active');
                const v = link.dataset.view;
                if (v) {
                    localStorage.setItem('currentHrView', v);
                    showView(v);
                }
            });
        });

        // Restore view on load
        const savedView = localStorage.getItem('currentHrView');
        if (savedView) {
            const link = document.querySelector(`.hr-nav-link[data-view="${savedView}"]`);
            if (link) {
                document.querySelectorAll('.hr-nav-link').forEach(l => l.classList.remove('active'));
                link.classList.add('active');
                showView(savedView);
            }
        }
        
        const urlParams = new URLSearchParams(window.location.search);
        const viewPayrollId = urlParams.get('viewPayroll');
        if (viewPayrollId) {
            setTimeout(() => {
                showView('hr-archive');
                viewArchivedPayroll(viewPayrollId);
                // Clean url
                window.history.replaceState({}, document.title, window.location.pathname);
            }, 500);
        }
    }

    function showView(viewId) {
        document.querySelectorAll('.content-area .view').forEach(v => v.style.display = 'none');
        const el = document.getElementById('view-' + viewId);
        if (el) el.style.display = 'block';
        if (viewId === 'hr-employees') renderEmployees();
        else if (viewId === 'hr-advances') renderAdvances();
        else if (viewId === 'hr-payroll') preparePayrollView();
        else if (viewId === 'hr-ledger') prepareLedgerView();
        else if (viewId === 'hr-archive') renderArchive();
        else if (viewId === 'hr-attendance') prepareAttendanceView();
        else updateDashboardStats();
    }

    // ======================
    // DASHBOARD
    // ======================

    function updateDashboardStats() {
        const activeEmps = employees.filter(e => e.status === 'active').length;
        const validAdvances = advances.filter(a => transactions.some(t => t.reference === 'ADV-' + a.id));
        const activeAdv = validAdvances.filter(a => a.status === 'active').length;
        
        const totalPaid = payrolls.filter(p => p.status !== 'draft').reduce((s, p) => s + (parseFloat(p.net_total) || 0), 0);
        
        const totalAdvAmt = validAdvances.reduce((s, a) => {
            const remain = (parseFloat(a.amount) || 0) - (parseFloat(a.paid_amount) || 0);
            return s + (remain > 0 ? remain : 0);
        }, 0);

        setText('stat-emp-count',    employees.length);
        setText('stat-emp-active',   activeEmps);
        setText('stat-adv-active',   activeAdv);
        setText('stat-adv-remaining', totalAdvAmt.toFixed(2));
        setText('stat-payroll-total', totalPaid.toFixed(2));
        setText('stat-payroll-count', payrolls.filter(p => p.status !== 'draft').length);
    }

    function setText(id, val) {
        const el = document.getElementById(id);
        if (el) el.innerText = val;
    }

    // ======================
    // ROLE HELPERS
    // ======================

    function getVisibleProjects() {
        if (!currentUser) return [];
        if (currentUser.allowed_projects && currentUser.allowed_projects.length > 0) {
            const allowed = currentUser.allowed_projects.map(x => String(x));
            return projects.filter(p => allowed.includes(String(p.id)));
        }
        if (currentUser.role === 'مدير عام') return projects;
        if (currentUser.project_id) {
            return projects.filter(p => String(p.id) === String(currentUser.project_id));
        }
        return [];
    }

    function getVisibleEmployees() {
        if (!currentUser) return [];
        if (currentUser.role === 'مدير عام') return employees;
        const vpIds = getVisibleProjects().map(p => String(p.id));
        return employees.filter(e => e.project_id && vpIds.includes(String(e.project_id)));
    }

    // ======================
    // EMPLOYEES
    // ======================

    function renderEmployees() {
        const tbody = document.getElementById('hr-employees-tbody');
        if (!tbody) return;
        
        let allVisible = getVisibleEmployees();

        // Populate projects dynamically
        const pFilter = document.getElementById('hr-filter-project');
        if (pFilter && pFilter.options.length <= 1) {
            const currentVal = pFilter.value;
            pFilter.innerHTML = '<option value="">كل المشاريع</option>' + 
                getVisibleProjects().map(p => `<option value="${p.id}">${p.name}</option>`).join('');
            pFilter.value = currentVal;
        }

        // Populate job titles dynamically
        const jFilter = document.getElementById('hr-filter-job');
        if (jFilter && jFilter.options.length <= 1) {
            const currentVal = jFilter.value;
            const uniqueJobs = [...new Set(allVisible.map(e => (e.job_title || '').trim()).filter(j => j))];
            jFilter.innerHTML = '<option value="">كل المسميات</option>' + 
                uniqueJobs.map(job => `<option value="${job}">${job}</option>`).join('');
            jFilter.value = currentVal;
        }

        let list = [...allVisible];
        
        const jobFilter = document.getElementById('hr-filter-job')?.value.trim().toLowerCase();
        const projectFilter = document.getElementById('hr-filter-project')?.value;
        const statusFilter = document.getElementById('hr-filter-status')?.value;

        if (jobFilter) {
            list = list.filter(e => (e.job_title || '').toLowerCase() === jobFilter);
        }
        if (projectFilter) {
            list = list.filter(e => String(e.project_id) === String(projectFilter));
        }
        if (statusFilter) {
            list = list.filter(e => e.status === statusFilter);
        }

        if (list.length === 0) {
            tbody.innerHTML = '<tr><td colspan="11" style="text-align:center; padding:30px; color:var(--text-muted);">لا يوجد موظفون.</td></tr>';
            document.getElementById('hr-employees-pagination').innerHTML = '';
            return;
        }
        
        // Pagination
        const limit = 100;
        const totalPages = Math.ceil(list.length / limit);
        if (window.hrEmployeesPage > totalPages) window.hrEmployeesPage = totalPages;
        if (window.hrEmployeesPage < 1) window.hrEmployeesPage = 1;
        const start = (window.hrEmployeesPage - 1) * limit;
        const paginatedList = list.slice(start, start + limit);
        
        let totalBasic = 0, totalHousing = 0, totalTransport = 0, grandTotal = 0;
        
        const rowsHtml = paginatedList.map(emp => {
            const proj = projects.find(p => String(p.id) === String(emp.project_id));
            const basic    = parseFloat(emp.basic_salary)       || 0;
            const housing  = parseFloat(emp.housing_allowance)  || 0;
            const transport= parseFloat(emp.transport_allowance)|| 0;
            const total    = basic + housing + transport;
            
            totalBasic += basic;
            totalHousing += housing;
            totalTransport += transport;
            grandTotal += total;

            const statusBadge = emp.status === 'active'
                ? '<span class="badge badge-success">نشط</span>'
                : '<span class="badge badge-danger">غير نشط</span>';
            return `<tr>
                <td>${emp.name || ''}</td>
                <td>${emp.job_title || '-'}</td>
                <td>${proj ? proj.name : '-'}</td>
                <td>${statusBadge}</td>
                <td>${emp.notes || '-'}</td>
                <td>${basic.toLocaleString('en-US', {minimumFractionDigits: 2})}</td>
                <td>${housing.toLocaleString('en-US', {minimumFractionDigits: 2})}</td>
                <td>${transport.toLocaleString('en-US', {minimumFractionDigits: 2})}</td>
                <td><strong>${total.toLocaleString('en-US', {minimumFractionDigits: 2})}</strong></td>
                <td>${parseFloat(emp.leave_balance) || 0} يوم</td>
                <td>
                    <button class="action-btn" style="background:#f39c12; color:#fff;" onclick="HRApp.viewEmployeeStatement(${emp.id}, '${(emp.name || '').replace(/'/g, "\\'")}')">كشف الدوام</button>
                    <button class="action-btn btn-edit" onclick="HRApp.openEmployeeModal(${emp.id})">تعديل</button>
                    <button class="action-btn btn-delete" onclick="HRApp.deleteEmployee(${emp.id})">حذف</button>
                </td>
            </tr>`;
        }).join('');

        const totalsRowHtml = `<tr style="font-weight:bold; background:rgba(46, 204, 113, 0.1); border-bottom:2px solid var(--border);">
            <td colspan="5" style="text-align:left; color:var(--text-muted); padding:12px;">الإجمالي الكلي:</td>
            <td style="color:#2ecc71;">${totalBasic.toLocaleString('en-US', {minimumFractionDigits: 2})}</td>
            <td style="color:#2ecc71;">${totalHousing.toLocaleString('en-US', {minimumFractionDigits: 2})}</td>
            <td style="color:#2ecc71;">${totalTransport.toLocaleString('en-US', {minimumFractionDigits: 2})}</td>
            <td style="color:#2ecc71; font-size:15px;">${grandTotal.toLocaleString('en-US', {minimumFractionDigits: 2})}</td>
            <td colspan="2"></td>
        </tr>`;

        tbody.innerHTML = totalsRowHtml + rowsHtml;
        
        renderPaginationControls(list.length, window.hrEmployeesPage, 'hr-employees-pagination', 'changeEmployeesPage');
    }

    function openEmployeeModal(id = null) {
        const pSelect = document.getElementById('hr-emp-project');
        pSelect.innerHTML = '<option value="">-- بدون مشروع --</option>' +
            getVisibleProjects().map(p => `<option value="${p.id}">${p.name}</option>`).join('');

        if (id) {
            const emp = employees.find(e => String(e.id) === String(id));
            if (emp) {
                document.getElementById('hr-emp-id').value          = emp.id;
                document.getElementById('hr-emp-name').value        = emp.name || '';
                document.getElementById('hr-emp-job').value         = emp.job_title || '';
                document.getElementById('hr-emp-project').value     = emp.project_id || '';
                document.getElementById('hr-emp-phone').value       = emp.phone || '';
                document.getElementById('hr-emp-national-id').value = emp.national_id || '';
                document.getElementById('hr-emp-basic').value       = emp.basic_salary || 0;
                document.getElementById('hr-emp-housing').value     = emp.housing_allowance || 0;
                document.getElementById('hr-emp-transport').value   = emp.transport_allowance || 0;
                document.getElementById('hr-emp-leaves').value      = emp.leave_balance || 0;
                document.getElementById('hr-emp-notes').value       = emp.notes || '';
                document.getElementById('hr-emp-status').value      = emp.status || 'active';
                document.getElementById('hr-emp-hire-date').value   = emp.hire_date || '';
                document.getElementById('hr-employee-modal-title').innerText = 'تعديل بيانات الموظف';
            }
        } else {
            ['hr-emp-id','hr-emp-name','hr-emp-job','hr-emp-phone','hr-emp-national-id','hr-emp-hire-date','hr-emp-notes'].forEach(id => {
                const el = document.getElementById(id);
                if (el) el.value = '';
            });
            document.getElementById('hr-emp-basic').value     = 0;
            document.getElementById('hr-emp-housing').value   = 0;
            document.getElementById('hr-emp-transport').value = 0;
            document.getElementById('hr-emp-leaves').value    = 0;
            document.getElementById('hr-emp-project').value   = '';
            document.getElementById('hr-emp-status').value    = 'active';
            document.getElementById('hr-employee-modal-title').innerText = 'إضافة موظف جديد';
        }
        showModal('hr-employee-modal');
    }

    function closeEmployeeModal() { hideModal('hr-employee-modal'); }

    let isSaving = false;
    async function saveEmployee(btn) {
        if (isSaving) return;
        isSaving = true;
        
        if(btn) btn.disabled = true;
        const originalBtnText = btn ? btn.innerHTML : '';
        if(btn) btn.innerHTML = 'جارٍ الحفظ...';

        const id      = document.getElementById('hr-emp-id').value;
        const nameVal = document.getElementById('hr-emp-name').value.trim();
        if (!nameVal) { 
            alert('يرجى إدخال اسم الموظف'); 
            isSaving = false;
            if(btn) { btn.disabled = false; btn.innerHTML = originalBtnText; }
            return; 
        }

        const data = {
            name:               nameVal,
            job_title:          document.getElementById('hr-emp-job').value.trim(),
            project_id:         document.getElementById('hr-emp-project').value,
            phone:              document.getElementById('hr-emp-phone').value.trim(),
            national_id:        document.getElementById('hr-emp-national-id').value.trim(),
            hire_date:          document.getElementById('hr-emp-hire-date').value,
            basic_salary:       parseFloat(document.getElementById('hr-emp-basic').value)     || 0,
            housing_allowance:  parseFloat(document.getElementById('hr-emp-housing').value)   || 0,
            transport_allowance:parseFloat(document.getElementById('hr-emp-transport').value) || 0,
            leave_balance:      parseFloat(document.getElementById('hr-emp-leaves').value)    || 0,
            notes:              document.getElementById('hr-emp-notes').value.trim(),
            status:             document.getElementById('hr-emp-status').value
        };

        try {
            if (id) {
                data.id = parseInt(id);
                await window.DB.update('employees', data);
                // Update local array directly
                const idx = employees.findIndex(e => String(e.id) === String(data.id));
                if (idx >= 0) employees[idx] = data;
                else employees.push(data);
            } else {
                data.id = Date.now();
                await window.DB.add('employees', data);
                // Add directly to local array immediately
                employees.push(data);
                // Delayed sync: wait 2s then verify server has the record
                const savedId = String(data.id);
                setTimeout(() => {
                    window.DB.getAll('employees').then(res => {
                        const fresh = toArray(res);
                        // Only overwrite if server has our record
                        if (fresh.some(e => String(e.id) === savedId)) {
                            employees = fresh;
                            renderEmployees();
                            updateDashboardStats();
                        }
                    }).catch(() => {});
                }, 2000);
            }
            closeEmployeeModal();
            renderEmployees();
            updateDashboardStats();
            showToast('تم حفظ الموظف بنجاح');
        } catch(e) {
            console.error('Save error:', e);
            alert('حدث خطأ أثناء الحفظ');
        } finally {
            isSaving = false;
            if(btn) { btn.disabled = false; btn.innerHTML = originalBtnText; }
        }
    }

    async function deleteEmployee(id) {
        if (!confirm('هل أنت متأكد من حذف هذا الموظف؟')) return;

        // Remove from local array IMMEDIATELY (optimistic UI)
        employees = employees.filter(e => String(e.id) !== String(id));
        renderEmployees();
        updateDashboardStats();
        showToast('تم حذف الموظف');

        // Then delete from server in background
        try {
            await window.DB.remove('employees', id);
        } catch(e) {
            console.error('Delete error:', e);
        }
    }

    // ======================
    // ADVANCES
    // ======================

    async function selfHealAdvances() {
//         console.log(`[DEBUG HEAL] selfHealAdvances called. advances count=${advances.length}, payrolls count=${payrolls.length}, transactions count=${transactions.length}`);
        let changed = false;
        for (let adv of advances) {
            if (!adv.start_month) continue;
            // Skip if advance has no journal entry (deleted)
            const hasAdvJournal = transactions.some(t => t.reference === 'ADV-' + adv.id);
            if (!hasAdvJournal) {
//                 console.log(`[DEBUG HEAL] Advance id=${adv.id} SKIPPED - no ADV- journal entry found`);
                continue;
            }
            
            let expectedPaid = 0;
            let startIdx = 0;
            if (adv.start_month) {
                const sParts = adv.start_month.split('-');
                if (sParts.length >= 2) {
                    startIdx = parseInt(sParts[0]) * 12 + parseInt(sParts[1]);
                }
            }
            const inst = (parseFloat(adv.amount) || 0) / (parseInt(adv.installments) || 1);
            
            const sortedPayrolls = [...payrolls].sort((a,b) => {
               if(!a.month || !b.month) return 0;
               return a.month.localeCompare(b.month);
            });
            
//             console.log(`[DEBUG HEAL] Advance id=${adv.id}, emp=${adv.employee_id}, amount=${adv.amount}, installments=${adv.installments}, current status=${adv.status}, current paid=${adv.paid_amount}, start_month=${adv.start_month}`);
            
            for (let p of sortedPayrolls) {
                if (p.status === 'draft') continue;
                
                // Skip payrolls that are 'محذوف من الحسابات' (no journal entry)
                const hasPRJournal = transactions.some(t => t.reference === 'PR-' + p.id);
                if (!hasPRJournal) {
//                     console.log(`[DEBUG HEAL]   Payroll id=${p.id} month=${p.month} SKIPPED - no PR- journal (محذوف من الحسابات)`);
                    continue;
                }
                
                const cYear = parseInt(p.month.split('-')[0]);
                const cMonth = parseInt(p.month.split('-')[1]);
                const currentIdx = cYear * 12 + cMonth;
                
                if (startIdx > 0 && currentIdx < startIdx) continue;
                
                let grid = [];
                try {
                    grid = typeof p.grid === 'string' ? JSON.parse(p.grid) : (p.grid || []);
                } catch(e) {}

                const hasEmp = grid.some(row => row.employee && String(row.employee.id) === String(adv.employee_id) && row.advanceDeduction > 0);
                if (hasEmp) {
                    const amount = parseFloat(adv.amount) || 0;
                    if (expectedPaid < amount) {
                        let add = inst;
                        if (expectedPaid + add > amount) add = amount - expectedPaid;
                        expectedPaid += add;
                    }
//                     console.log(`[DEBUG HEAL]   Payroll id=${p.id} month=${p.month} HAS deduction for emp. expectedPaid now=${expectedPaid}`);
                }
            }
            
            const newStatus = expectedPaid >= (parseFloat(adv.amount) || 0) - 0.01 ? 'completed' : 'active';
//             console.log(`[DEBUG HEAL] Advance id=${adv.id}: expectedPaid=${expectedPaid}, newStatus=${newStatus}, oldStatus=${adv.status}, oldPaid=${adv.paid_amount}`);
            if (Math.abs((parseFloat(adv.paid_amount) || 0) - expectedPaid) > 0.01 || adv.status !== newStatus) {
                adv.paid_amount = expectedPaid;
                adv.status = newStatus;
                delete adv._last_updated; // fix sync issue if any
                await window.DB.update('advances', adv);
                changed = true;
//                 console.log(`[DEBUG HEAL] >>> UPDATED advance id=${adv.id} to status=${newStatus}, paid_amount=${expectedPaid}`);
            }
        }
        if (changed) {
            renderAdvances();
            updateDashboardStats();
        }
    }

    function renderAdvances() {
        selfHealAdvances(); // Run in background to fix data silently
        const tbody = document.getElementById('hr-advances-tbody');
        if (!tbody) return;
        
        const filterSelect = document.getElementById('advances-emp-filter');
        if (filterSelect && filterSelect.options.length <= 1) {
            // Keep the default option
            filterSelect.innerHTML = '<option value="">-- عرض كل الموظفين --</option>';
            getVisibleEmployees().filter(e => e.status === 'active').forEach(e => {
                const opt = document.createElement('option');
                opt.value = e.id;
                opt.textContent = e.name;
                filterSelect.appendChild(opt);
            });
        }
        const selectedEmp = filterSelect ? filterSelect.value : "";
        
        const empIds = getVisibleEmployees().map(e => String(e.id));
        let list = advances.filter(a => empIds.includes(String(a.employee_id)));
        
        if (selectedEmp) {
            list = list.filter(a => String(a.employee_id) === String(selectedEmp));
        }

        // Sort descending (newest first)
        list.sort((a, b) => (b.id || 0) - (a.id || 0));

        if (list.length === 0) {
            tbody.innerHTML = '<tr><td colspan="10" style="text-align:center; padding:30px; color:var(--text-muted);">لا يوجد سلف مسجلة.</td></tr>';
            return;
        }

        // Pagination
        window.advancesCurrentPage = window.advancesCurrentPage || 1;
        const limit = 100;
        const totalPages = Math.ceil(list.length / limit);
        if (window.advancesCurrentPage > totalPages) window.advancesCurrentPage = totalPages;
        if (window.advancesCurrentPage < 1) window.advancesCurrentPage = 1;
        
        const start = (window.advancesCurrentPage - 1) * limit;
        const paginatedList = list.slice(start, start + limit);

        let html = paginatedList.map(adv => {
            const emp    = employees.find(e => String(e.id) === String(adv.employee_id)) || {};
            const amount = parseFloat(adv.amount)       || 0;
            const paid   = parseFloat(adv.paid_amount)  || 0;
            const remain = amount - paid;
            const inst   = amount / (parseInt(adv.installments) || 1);
            const badge  = adv.status === 'completed'
                ? '<span class="badge badge-success">مسدد</span>'
                : '<span class="badge badge-warning">ساري</span>';
                
            const createdBy = adv.created_by || '-';
            
            let paidFrom = '-';
            if (adv.treasury_id) {
                const treasury = accounts.find(a => String(a.id) === String(adv.treasury_id));
                if (treasury) paidFrom = treasury.name;
            }
            
            return `<tr>
                <td>${adv.date || ''}</td>
                <td style="font-weight:bold; color:var(--primary);">${adv.start_month || '-'}</td>
                <td>${emp.name || 'مجهول'}</td>
                <td>${amount.toFixed(2)}</td>
                <td>${inst.toFixed(2)}</td>
                <td style="color:var(--success)">${paid.toFixed(2)}</td>
                <td style="color:var(--danger)">${remain.toFixed(2)}</td>
                <td><span style="font-size:0.9em; color:#555;">${createdBy}</span></td>
                <td><span style="font-size:0.9em; color:#555; font-weight:bold;">${paidFrom}</span></td>
                <td><button class="action-btn btn-delete" onclick="HRApp.deleteAdvance(${adv.id})">🗑️ حذف</button></td>
            </tr>`;
        }).join('');
        
        tbody.innerHTML = html;
        

        renderPaginationControls(list.length, window.advancesCurrentPage, 'hr-advances-pagination', 'changeAdvancesPage');
    }

    function openAdvanceModal() {
        const eSelect = document.getElementById('hr-adv-employee');
        eSelect.innerHTML = '<option value="">اختر الموظف...</option>' +
            getVisibleEmployees()
                .filter(e => e.status === 'active')
                .map(e => `<option value="${e.id}">${e.name}</option>`)
                .join('');

        const tSelect = document.getElementById('hr-adv-treasury');
        const treasuries = accounts.filter(a =>
            a.name.includes('خزينة') || a.name.includes('صندوق') || a.name.includes('بنك') || a.name.includes('مصرف') || a.name.includes('خزنة') || a.name.includes('عهد'));
        tSelect.innerHTML = '<option value="">اختر الخزينة / البنك...</option>' +
            treasuries.map(a => `<option value="${a.id}">${a.name}</option>`).join('');

        document.getElementById('hr-adv-amount').value     = '';
        document.getElementById('hr-adv-date').value       = new Date().toISOString().split('T')[0];
        document.getElementById('hr-adv-month').value      = new Date().toISOString().slice(0,7);
        document.getElementById('hr-adv-installments').value = 1;
        showModal('hr-advance-modal');
    }

    function closeAdvanceModal() { hideModal('hr-advance-modal'); }

    async function saveAdvance() {
        const empId      = document.getElementById('hr-adv-employee').value;
        const amount     = parseFloat(document.getElementById('hr-adv-amount').value);
        const treasuryId = document.getElementById('hr-adv-treasury').value;
        const date       = document.getElementById('hr-adv-date').value;
        const startMonth = document.getElementById('hr-adv-month').value;
        const installs   = parseInt(document.getElementById('hr-adv-installments').value) || 1;

        if (!empId)      { alert('يرجى اختيار الموظف');         return; }
        if (!amount || amount <= 0) { alert('يرجى إدخال مبلغ صحيح'); return; }
        if (!treasuryId) { alert('يرجى اختيار الخزينة / البنك'); return; }
        if (!date)       { alert('يرجى تحديد تاريخ صرف السلفة'); return; }

        const emp = employees.find(e => String(e.id) === String(empId));
        if (!emp) { alert('الموظف غير موجود'); return; }

        const advId   = Date.now();
        const transId = Date.now() + 1;

        const advData = {
            id:           advId,
            employee_id:  empId,
            amount:       amount,
            date:         date,
            start_month:  startMonth,
            installments: installs,
            paid_amount:  0,
            status:       'active',
            treasury_id:  parseInt(treasuryId),
            created_by:   window.currentUser ? window.currentUser.username : 'Admin'
        };

        const transRows = [
            { account_id: advancesAccountId, debit: amount, credit: 0, project_id: null },
            { account_id: parseInt(treasuryId), debit: 0, credit: amount, project_id: null }
        ];

        const transData = {
            id:           transId,
            date:         date,
            desc:         `سلفة موظف - ${emp.name} - ${amount.toFixed(2)} ج.م`,
            reference:    `ADV-${advId}`,
            status:       'posted',
            created_by:   'نظام الموارد البشرية',
            total:        amount,
            rows:         transRows
        };
        
        const voucherData = {
            id: Date.now() + 2,
            date: date,
            type: 'payment',
            contact_id: null,
            amount: amount,
            account_id: parseInt(treasuryId),
            category: 'سلف موظفين',
            desc: `سلفة نقدية - ${emp.name}`,
            created_by: 'نظام الموارد البشرية'
        };

        try {
            const realAdvId = await window.DB.add('advances', advData);
            const actualAdvId = realAdvId || advId;
            transData.reference = `ADV-${actualAdvId}`;
            
            await window.DB.add('journal_entries', transData);
            await window.DB.add('transactions', voucherData);
            await updateAccountBalance(advancesAccountId, amount, 0);
            await updateAccountBalance(parseInt(treasuryId), 0, amount);

            // Update local arrays directly
            advances.push(advData);
            transactions.push(transData);

            hideModal('hr-advance-modal');
            renderAdvances();
            updateDashboardStats();
            showToast(`تم صرف سلفة ${emp.name} بمبلغ ${amount.toFixed(2)} ج وإنشاء القيد المحاسبي ✅`);

            // Delayed sync after server writes
            const savedAdvId = String(advId);
            setTimeout(() => {
                window.DB.getAll('advances').then(res => {
                    const fresh = toArray(res);
                    if (fresh.some(a => String(a.id) === savedAdvId)) {
                        advances = fresh;
                        renderAdvances();
                        updateDashboardStats();
                    }
                }).catch(() => {});
            }, 2000);
        } catch (e) {
            alert('خطأ في الحفظ: ' + e.message);
            console.error(e);
        }
    }

    async function deleteAdvance(id) {
        if (!confirm('سيتم حذف السلفة والقيد المحاسبي وسند الصرف المرتبطين بها. هل أنت متأكد؟')) return;

        // Find journal entry (now stored in transactions variable which holds journal_entries)
        const journal = transactions.find(t => t.reference === 'ADV-' + id);
        
        // Remove from local array IMMEDIATELY
        advances = advances.filter(a => String(a.id) !== String(id));
        if (journal) transactions = transactions.filter(t => String(t.id) !== String(journal.id));

        renderAdvances();
        updateDashboardStats();
        showToast('تم حذف السلفة بنجاح');

        // Then delete from server in background
        try {
            if (journal) {
                const rows = journal.rows || [];
                for (const d of rows) {
                    await updateAccountBalance(d.account_id, d.credit, d.debit); // reverse (credit instead of debit)
                }
                await window.DB.remove('journal_entries', journal.id);
            }
            await window.DB.remove('advances', id);
            
            // Also attempt to find and delete the payment voucher (we don't have it loaded in memory in hr.js, so we fetch it)
            const allTransRaw = await window.DB.getAll('transactions');
            const allTrans = Array.isArray(allTransRaw) ? allTransRaw : Object.values(allTransRaw || {});
            const voucher = allTrans.find(t => t.type === 'payment' && t.category === 'سلف موظفين' && (t.desc || '').includes('سلفة') && Math.abs(new Date(t.date) - new Date(journal?.date || 0)) < 86400000);
            if (voucher) {
                await window.DB.remove('transactions', voucher.id);
            }
            
        } catch(e) {
            console.error('Delete advance error:', e);
        }
    }

    // ======================
    // PAYROLL
    // ======================

    function preparePayrollView() {
        const pSelect = document.getElementById('payroll-project-filter');
        pSelect.innerHTML = '<option value="all">جميع المشاريع</option>' +
            getVisibleProjects().map(p => `<option value="${p.id}">${p.name}</option>`).join('');
        const now = new Date();
        document.getElementById('payroll-month').value = `${now.getFullYear()}-${String(now.getMonth()+1).padStart(2,'0')}`;
        document.getElementById('hr-payroll-tbody').innerHTML =
            '<tr><td colspan="9" style="text-align:center; padding:30px; color:var(--text-muted);">اختر الشهر والمشروع ثم اضغط "توليد المسير"</td></tr>';
        window.hrPayrollGrid = [];
    }

    async function generatePayroll() {
        const month   = document.getElementById('payroll-month').value;
        const projFilter = document.getElementById('payroll-project-filter').value;
        if (!month) { alert('يرجى اختيار الشهر'); return; }
        
        await selfHealAdvances();

        let targetEmps = getVisibleEmployees().filter(e => e.status === 'active');
        if (projFilter !== 'all') {
            targetEmps = targetEmps.filter(e => String(e.project_id) === String(projFilter));
        }

        if (targetEmps.length === 0) {
            document.getElementById('hr-payroll-tbody').innerHTML =
                '<tr><td colspan="9" style="text-align:center; padding:30px; color:var(--danger);">لا توجد موظفين نشطين لعرضهم.</td></tr>';
            return;
        }

        document.getElementById('loading-overlay').style.display = 'flex';
        let absencesMap = {};
        try {
            const res = await fetch('api.php?store=get_monthly_absences&month=' + month);
            absencesMap = await res.json();
        } catch (e) {
            console.error('Error fetching absences:', e);
        }
        document.getElementById('loading-overlay').style.display = 'none';

        const tbody = document.getElementById('hr-payroll-tbody');
        tbody.innerHTML = '';
        window.hrPayrollGrid = [];

        targetEmps.forEach(emp => {
            const basic    = parseFloat(emp.basic_salary)        || 0;
            const housing  = parseFloat(emp.housing_allowance)   || 0;
            const transport= parseFloat(emp.transport_allowance) || 0;
            const totalFixed = basic + housing + transport;
            const dailyRate  = totalFixed / 30;

            // Advance installment
            let advanceDeduction = 0;
            const empAdvances = advances.filter(a => String(a.employee_id) === String(emp.id));
//             console.log(`[DEBUG PAYROLL] Employee: ${emp.name} (id=${emp.id}), Total advances found: ${empAdvances.length}`);
            empAdvances.forEach(a => {
//                 console.log(`[DEBUG PAYROLL]   Advance id=${a.id}, amount=${a.amount}, installments=${a.installments}, status=${a.status}, paid_amount=${a.paid_amount}, start_month=${a.start_month}`);
            });
            
            advances.filter(a => {
                if (String(a.employee_id) !== String(emp.id)) return false;
                if (a.status === 'completed') {
//                     console.log(`[DEBUG PAYROLL]   SKIPPED advance id=${a.id} - status is completed`);
                    return false;
                }
                
                if (!a.start_month) return true;
                
                const sYear = parseInt(a.start_month.split('-')[0]);
                const sMonth = parseInt(a.start_month.split('-')[1]);
                const cYear = parseInt(month.split('-')[0]);
                const cMonth = parseInt(month.split('-')[1]);
                
                if (isNaN(sYear) || isNaN(sMonth) || isNaN(cYear) || isNaN(cMonth)) return true;
                
                const startIdx = sYear * 12 + sMonth;
                const currentIdx = cYear * 12 + cMonth;
                
                if (currentIdx < startIdx) {
//                     console.log(`[DEBUG PAYROLL]   SKIPPED advance id=${a.id} - month ${month} is before start_month ${a.start_month}`);
                    return false;
                }
                
//                 console.log(`[DEBUG PAYROLL]   INCLUDED advance id=${a.id} for deduction`);
                return true;
            }).forEach(adv => {
                let inst = (parseFloat(adv.amount) || 0) / (parseInt(adv.installments) || 1);
                const remain = (parseFloat(adv.amount) || 0) - (parseFloat(adv.paid_amount) || 0);
                
//                 console.log(`[DEBUG PAYROLL]   Calculating: inst=${inst}, remain=${remain}`);
                
                if (remain <= 0) {
//                     console.log(`[DEBUG PAYROLL]   SKIPPED - remain <= 0`);
                    return;
                }
                if (inst > remain) inst = remain;
                
                advanceDeduction += inst;
//                 console.log(`[DEBUG PAYROLL]   advanceDeduction now = ${advanceDeduction}`);
            });

            const rowId = 'pr_' + emp.id;
            const proj  = projects.find(p => String(p.id) === String(emp.project_id));
            
            // Populate absences from attendance module
            const absenceDays = absencesMap[emp.id] || 0;

            const tr = document.createElement('tr');
            tr.innerHTML = `
                <td>
                    <strong>${emp.name}</strong><br>
                    <small style="color:var(--text-muted)">${proj ? proj.name : 'غير محدد'}</small>
                </td>
                <td>${totalFixed.toFixed(2)}</td>
                <td><input type="number" id="${rowId}_bonus"     value="0" min="0"
                    oninput="HRApp.recalcPayrollRow(${emp.id})" style="width:80px; padding:4px; border-radius:4px; color:var(--text-color, inherit); background:var(--input-bg, transparent); border:1px solid var(--border-color, #ccc);"></td>
                <td><input type="number" id="${rowId}_deduction" value="0" min="0"
                    oninput="HRApp.recalcPayrollRow(${emp.id})" style="width:80px; padding:4px; border-radius:4px; color:var(--text-color, inherit); background:var(--input-bg, transparent); border:1px solid var(--border-color, #ccc);"></td>
                <td><input type="number" id="${rowId}_leaves"    value="0" min="0"
                    oninput="HRApp.recalcPayrollRow(${emp.id})"
                    style="width:80px; padding:4px; border-radius:4px; color:var(--text-color, inherit); background:var(--input-bg, transparent); border:1px solid var(--border-color, #ccc);"></td>
                <td><input type="number" id="${rowId}_absence"   value="${absenceDays}" min="0"
                    oninput="HRApp.recalcPayrollRow(${emp.id})" style="width:80px; padding:4px; border-radius:4px; color:var(--text-color, inherit); background:var(--input-bg, transparent); border:1px solid var(--border-color, #ccc);"></td>
                <td style="color:var(--danger)">${advanceDeduction.toFixed(2)}</td>
                <td id="${rowId}_net" style="font-weight:bold; color:var(--success);">${(totalFixed - advanceDeduction).toFixed(2)}</td>
            `;
            tbody.appendChild(tr);

            window.hrPayrollGrid.push({
                employee:         emp,
                basic_salary:     basic,
                allowances:       housing + transport,
                totalFixed:       totalFixed,
                dailyRate:        dailyRate,
                advanceDeduction: advanceDeduction,
                bonus:            0,
                deduction:        0,
                overtime:         0,
                deductions:       0,
                absences:         absenceDays,
                absenceDeduction: absenceDays * dailyRate,
                leavesUsed:       0,
                absenceDays:      absenceDays,
                net:              totalFixed - advanceDeduction - (absenceDays * dailyRate)
            });
            
            // Fix net display immediately if there are absence days
            if (absenceDays > 0) {
                setTimeout(() => HRApp.recalcPayrollRow(emp.id), 0);
            }
        });
        recalcPayrollTotal();
    }

    function renderPayrollGrid() {
        const tbody = document.getElementById('hr-payroll-tbody');
        tbody.innerHTML = '';
        if (!window.hrPayrollGrid || window.hrPayrollGrid.length === 0) {
            tbody.innerHTML = '<tr><td colspan="9" style="text-align:center; padding:30px; color:var(--danger);">لا توجد بيانات مسير لعرضها.</td></tr>';
            return;
        }

        window.hrPayrollGrid.forEach(entry => {
            const emp = entry.employee;
            const rowId = 'pr_' + emp.id;
            const proj  = projects.find(p => String(p.id) === String(emp.project_id));
            const tr = document.createElement('tr');
            
            // Highlight row if leave_balance is dangerously low
            const remainLeaves = parseFloat(emp.leave_balance) || 0;
            
            tr.innerHTML = `
                <td>
                    <strong>${emp.name}</strong><br>
                    <small style="color:var(--text-muted)">${proj ? proj.name : 'غير محدد'}</small>
                </td>
                <td>${(entry.totalFixed || 0).toFixed(2)}</td>
                <td><input type="number" id="${rowId}_bonus"     value="${entry.bonus || 0}" min="0"
                    oninput="HRApp.recalcPayrollRow(${emp.id})" style="width:80px; padding:4px; border-radius:4px; color:var(--text-color, inherit); background:var(--input-bg, transparent); border:1px solid var(--border-color, #ccc);"></td>
                <td><input type="number" id="${rowId}_deduction" value="${entry.deduction || 0}" min="0"
                    oninput="HRApp.recalcPayrollRow(${emp.id})" style="width:80px; padding:4px; border-radius:4px; color:var(--text-color, inherit); background:var(--input-bg, transparent); border:1px solid var(--border-color, #ccc);"></td>
                <td>
                    <input type="number" id="${rowId}_leaves"    value="${entry.leavesUsed || 0}" min="0"
                        oninput="HRApp.recalcPayrollRow(${emp.id})"
                        style="width:80px; padding:4px; border-radius:4px; color:var(--text-color, inherit); background:var(--input-bg, transparent); border:1px solid var(--border-color, #ccc);">
                    <br><small style="color:gray; font-size:10px;">رصيده: ${remainLeaves}</small>
                </td>
                <td><input type="number" id="${rowId}_absence"   value="${entry.absenceDays || 0}" min="0"
                    oninput="HRApp.recalcPayrollRow(${emp.id})" style="width:80px; padding:4px; border-radius:4px; color:var(--text-color, inherit); background:var(--input-bg, transparent); border:1px solid var(--border-color, #ccc);"></td>
                <td style="color:var(--danger)">${(entry.advanceDeduction || 0).toFixed(2)}</td>
                <td id="${rowId}_net" style="font-weight:bold; color:var(--success);">${(entry.net || 0).toFixed(2)}</td>
            `;
            tbody.appendChild(tr);
        });
        recalcPayrollTotal();
    }

    function parseNum(val) {
        if (!val) return 0;
        const str = String(val).replace(/[٠-٩]/g, d => '٠١٢٣٤٥٦٧٨٩'.indexOf(d));
        return parseFloat(str) || 0;
    }

    function recalcPayrollRow(empId) {
        const rowId = 'pr_' + empId;
        const entry = window.hrPayrollGrid.find(g => String(g.employee.id) === String(empId));
        if (!entry) return;

        entry.bonus       = parseNum(document.getElementById(rowId + '_bonus').value);
        entry.deduction   = parseNum(document.getElementById(rowId + '_deduction').value);
        entry.leavesUsed  = parseNum(document.getElementById(rowId + '_leaves').value);
        entry.absenceDays = parseNum(document.getElementById(rowId + '_absence').value);

        const leaveAllowance   = entry.leavesUsed  * entry.dailyRate;
        const absenceDeduction = entry.absenceDays * entry.dailyRate;

        entry.net = entry.totalFixed + entry.bonus + leaveAllowance - entry.deduction - absenceDeduction - entry.advanceDeduction;
        if (entry.net < 0) entry.net = 0;

        document.getElementById(rowId + '_net').innerText = entry.net.toFixed(2);
        recalcPayrollTotal();
    }

    function recalcPayrollTotal() {
        let tBasic=0, tBonus=0, tDed=0, tLeaves=0, tAbs=0, tAdv=0, tNet=0;
        window.hrPayrollGrid.forEach(e => {
            tBasic  += e.totalFixed;
            tBonus  += e.bonus;
            tDed    += e.deduction;
            tLeaves += e.leavesUsed;
            tAbs    += e.absenceDays;
            tAdv    += e.advanceDeduction;
            tNet    += e.net;
        });
        setText('pr-total-basic',     tBasic.toFixed(2));
        setText('pr-total-bonus',     tBonus.toFixed(2));
        setText('pr-total-deduction', tDed.toFixed(2));
        setText('pr-total-leaves',    tLeaves.toFixed(0) + ' يوم');
        setText('pr-total-absence',   tAbs.toFixed(0) + ' يوم');
        setText('pr-total-advances',  tAdv.toFixed(2));
        setText('pr-total-net',       tNet.toFixed(2));
    }

    async function savePayroll(isDraft = false) {
        if (!window.hrPayrollGrid || window.hrPayrollGrid.length === 0) {
            alert('جدول المسير فارغ'); return;
        }
        const month      = document.getElementById('payroll-month').value;
        const projFilter = document.getElementById('payroll-project-filter').value;
        const existingId = document.getElementById('payroll-id') ? document.getElementById('payroll-id').value : '';

        if (isDraft) {
            if (!confirm(`هل تريد حفظ مسير شهر ${month} كمسودة؟`)) return;
        } else {
            if (!confirm(`هل تريد اعتماد مسير شهر ${month}؟\nسيتم إنشاء القيود المحاسبية تلقائياً.`)) return;
        }

        let totalNetOverall = 0, totalAdvancesOverall = 0, totalExpenseOverall = 0;
        let totalsByProject = {}; // To group expenses by project

        for (const entry of window.hrPayrollGrid) {
            totalNetOverall      += entry.net;
            totalAdvancesOverall += entry.advanceDeduction;
            
            const expense = entry.net + entry.advanceDeduction;
            const pId = entry.employee.project_id || 'null';
            
            if (!totalsByProject[pId]) totalsByProject[pId] = { net: 0, advances: 0, expense: 0 };
            totalsByProject[pId].net += entry.net;
            totalsByProject[pId].advances += entry.advanceDeduction;
            totalsByProject[pId].expense += expense;

            // update leave balance
            if (!isDraft && entry.leavesUsed > 0) {
                entry.employee.leave_balance = (parseFloat(entry.employee.leave_balance) || 0) - entry.leavesUsed;
                if (entry.employee.leave_balance < 0) entry.employee.leave_balance = 0;
                delete entry.employee._last_updated;
                await window.DB.update('employees', entry.employee);
            }

            // update advances paid
            if (!isDraft && entry.advanceDeduction > 0) {
                let left = entry.advanceDeduction;
                for (const adv of advances.filter(a => {
                    if (String(a.employee_id) !== String(entry.employee.id)) return false;
                    if (!a.start_month) return true;
                    
                    const sYear = parseInt(a.start_month.split('-')[0]);
                    const sMonth = parseInt(a.start_month.split('-')[1]);
                    const cYear = parseInt(month.split('-')[0]);
                    const cMonth = parseInt(month.split('-')[1]);
                    const startIdx = sYear * 12 + sMonth;
                    const currentIdx = cYear * 12 + cMonth;
                    const endIdx = startIdx + (parseInt(a.installments) || 1) - 1;
                    return currentIdx >= startIdx && currentIdx <= endIdx;
                })) {
                    if (left <= 0) break;
                    const inst = (parseFloat(adv.amount) || 0) / (parseInt(adv.installments) || 1);
                    const toDeduct = Math.min(left, inst);
                    adv.paid_amount = (parseFloat(adv.paid_amount) || 0) + toDeduct;
                    adv.paid_by = window.currentUser ? window.currentUser.name : 'Admin';
                    if (adv.paid_amount >= parseFloat(adv.amount)) adv.status = 'completed';
                    delete adv._last_updated;
                    await window.DB.update('advances', adv);
                    left -= toDeduct;
                }
            }
        }

        totalExpenseOverall = totalNetOverall + totalAdvancesOverall;
        const projName = projFilter === 'all'
            ? 'جميع المشاريع'
            : (projects.find(p => String(p.id) === String(projFilter)) || {}).name || '';

        const pid     = existingId ? parseInt(existingId) : Date.now();
        const pRecord = {
            id:         pid,
            month:      month,
            project_id: projFilter,
            grid:       JSON.stringify(window.hrPayrollGrid),
            net_total:  totalNetOverall,
            date:       new Date().toISOString().split('T')[0],
            status:     isDraft ? 'draft' : 'approved'
        };

        if (existingId) {
            delete pRecord._last_updated;
            await window.DB.update('payrolls', pRecord);
        } else {
            const newId = await window.DB.add('payrolls', pRecord);
            pRecord.id = newId; // Update our record with the real DB ID
        }

        const actualPid = pRecord.id; // Now this is definitely the real DB ID (e.g. 26)

        if (!isDraft) {
            const transRows = [];
            
            // Push rows per project
            for (const pId in totalsByProject) {
                const t = totalsByProject[pId];
                const parsedProjId = (pId === 'null' || !pId) ? null : parseInt(pId);
                
                if (t.expense > 0) {
                    transRows.push({ account_id: salariesExpenseAccountId, debit: t.expense, credit: 0, project_id: parsedProjId });
                }
                if (t.net > 0) {
                    transRows.push({ account_id: accruedSalariesAccountId, debit: 0, credit: t.net, project_id: parsedProjId });
                }
            }
            
            // Push advances
            if (totalAdvancesOverall > 0) {
                transRows.push({ account_id: advancesAccountId, debit: 0, credit: totalAdvancesOverall, project_id: null });
            }

            await window.DB.add('journal_entries', {
                id: Date.now() + 1,
                date: new Date().toISOString().split('T')[0],
                desc: `استحقاق رواتب ${month} - ${projName}`,
                reference: `PR-${actualPid}`,
                status: 'posted',
                created_by: 'نظام الموارد البشرية',
                total: totalExpenseOverall,
                rows: transRows
            });

            await updateAccountBalance(salariesExpenseAccountId, totalExpenseOverall, 0);
            await updateAccountBalance(accruedSalariesAccountId, 0, totalNetOverall);
            await updateAccountBalance(advancesAccountId,        0, totalAdvancesOverall);
        }

        // reload
        employees    = toArray(await window.DB.getAll('employees'));
        advances     = toArray(await window.DB.getAll('advances'));
        payrolls     = toArray(await window.DB.getAll('payrolls'));
        transactions = toArray(await window.DB.getAll('journal_entries'));
        accounts     = toArray(await window.DB.getAll('accounts'));

        updateDashboardStats();
        renderArchive();
        showToast(isDraft ? 'تم حفظ المسودة بنجاح' : 'تم اعتماد المسير وإنشاء القيود المحاسبية بنجاح');
        
        // Clear grid
        window.hrPayrollGrid = [];
        document.getElementById('hr-payroll-tbody').innerHTML =
            `<tr><td colspan="9" style="text-align:center; padding:20px; color:var(--success);">✅ ${isDraft ? 'تم حفظ المسودة بنجاح.' : 'تم اعتماد المسير بنجاح.'}</td></tr>`;
        if (document.getElementById('payroll-id')) {
            document.getElementById('payroll-id').value = '';
        }
    }

    function openPayPayrollModal(id) {
        const p = payrolls.find(x => String(x.id) === String(id));
        if (!p) return;
        
        document.getElementById('pay-payroll-id').value = p.id;
        document.getElementById('pay-payroll-month').value = p.month;
        
        const grid = JSON.parse(p.grid || '[]');
        const container = document.getElementById('pay-payroll-employees');
        container.innerHTML = '';
        
        let totalAmount = 0;
        
        grid.forEach(row => {
            if (!row.paid) {
                totalAmount += (parseFloat(row.net) || 0);
                const empName = row.employee ? row.employee.name : 'موظف مجهول';
                const netVal = parseFloat(row.net || 0).toFixed(2);
                const item = document.createElement('div');
                item.style.marginBottom = '8px';
                item.style.borderBottom = '1px solid var(--border)';
                item.style.paddingBottom = '8px';
                item.innerHTML = `
                    <label style="display:flex; justify-content:space-between; align-items:center; cursor:pointer; width:100%;">
                        <div style="display:flex; align-items:center; gap:8px;">
                            <input type="checkbox" class="pay-emp-checkbox" value="${row.employee.id}" data-net="${netVal}" checked>
                            <span style="font-weight:600;">${empName}</span>
                        </div>
                        <strong style="color:var(--success); font-size:15px;">${netVal}</strong>
                    </label>
                `;
                container.appendChild(item);
            }
        });
        
        if (container.innerHTML === '') {
            container.innerHTML = '<div style="color:var(--success); text-align:center;">تم سداد رواتب جميع الموظفين في هذا المسير.</div>';
            totalAmount = 0;
        }
        
        document.getElementById('pay-payroll-amount').value = totalAmount;
        document.getElementById('pay-payroll-amount-display').value = parseFloat(totalAmount).toFixed(2);
        
        // Add change listener to checkboxes
        const checkboxes = container.querySelectorAll('.pay-emp-checkbox');
        checkboxes.forEach(cb => {
            cb.addEventListener('change', () => {
                let newTotal = 0;
                container.querySelectorAll('.pay-emp-checkbox:checked').forEach(c => {
                    newTotal += parseFloat(c.getAttribute('data-net'));
                });
                document.getElementById('pay-payroll-amount').value = newTotal;
                document.getElementById('pay-payroll-amount-display').value = parseFloat(newTotal).toFixed(2);
            });
        });
        
        const tSelect = document.getElementById('pay-payroll-treasury');
        tSelect.innerHTML = '<option value="">-- اختر الخزينة/البنك --</option>';
        accounts.filter(a => a.name.includes('خزينة') || a.name.includes('صندوق') || a.name.includes('بنك') || a.name.includes('مصرف') || a.name.includes('خزنة') || a.name.includes('عهد')).forEach(a => {
            tSelect.innerHTML += `<option value="${a.id}">${a.name}</option>`;
        });
        
        showModal('hr-pay-payroll-modal');
    }

    async function executePayPayroll() {
        const payrollId = document.getElementById('pay-payroll-id').value;
        const amount     = parseFloat(document.getElementById('pay-payroll-amount').value);
        const treasuryId = document.getElementById('pay-payroll-treasury').value;
        const month      = document.getElementById('pay-payroll-month').value;
        
        if (!treasuryId) { alert('يرجى اختيار الخزينة'); return; }
        if (amount <= 0) { alert('إجمالي السداد يجب أن يكون أكبر من الصفر'); return; }

        const p = payrolls.find(x => String(x.id) === String(payrollId));
        if (!p) return;

        // Get checked employees
        const container = document.getElementById('pay-payroll-employees');
        const checkedCheckboxes = container.querySelectorAll('.pay-emp-checkbox:checked');
        const checkedEmpIds = Array.from(checkedCheckboxes).map(cb => cb.value);

        if (checkedEmpIds.length === 0) { alert('الرجاء تحديد موظف واحد على الأقل للسداد'); return; }

        // Update grid
        let grid = JSON.parse(p.grid || '[]');
        let numPaidNow = 0;
        grid.forEach(row => {
            if (row.employee && checkedEmpIds.includes(String(row.employee.id))) {
                row.paid = true;
                numPaidNow++;
            }
        });
        p.grid = JSON.stringify(grid);
        await window.DB.update('payrolls', p);

        const transId = Date.now();
        const transRows = [
            { account_id: accruedSalariesAccountId, debit: amount, credit: 0, project_id: null },
            { account_id: parseInt(treasuryId), debit: 0, credit: amount, project_id: null }
        ];

        await window.DB.add('journal_entries', {
            id: transId,
            date: new Date().toISOString().split('T')[0],
            desc: `سداد رواتب شهر ${month} نقداً (لعدد ${numPaidNow} موظف)`,
            reference: `PAY-${transId}`,
            status: 'draft',
            created_by: 'نظام الموارد البشرية',
            total: amount,
            rows: transRows
        });
        
        // إنشاء سند صرف
        await window.DB.add('transactions', {
            id: Date.now() + 1,
            date: new Date().toISOString().split('T')[0],
            type: 'payment',
            contact_id: null,
            amount: amount,
            account_id: parseInt(treasuryId),
            category: 'رواتب',
            desc: `سداد رواتب شهر ${month} نقداً لعدد ${numPaidNow} موظف`,
            created_by: 'نظام الموارد البشرية'
        });

        await updateAccountBalance(accruedSalariesAccountId, amount, 0);
        await updateAccountBalance(parseInt(treasuryId), 0, amount);

        transactions = toArray(await window.DB.getAll('journal_entries'));
        accounts     = toArray(await window.DB.getAll('accounts'));
        hideModal('hr-pay-payroll-modal');
        renderArchive();
        showToast('✅ تم تسجيل صرف الرواتب للموظفين المحددين بنجاح');
    }

    // ======================
    // LEDGER
    // ======================

    function prepareLedgerView() {
        const eSelect = document.getElementById('ledger-employee-select');
        eSelect.innerHTML = '<option value="">اختر موظف...</option>' +
            getVisibleEmployees().map(e => `<option value="${e.id}">${e.name}</option>`).join('');
        const today    = new Date().toISOString().split('T')[0];
        const firstDay = today.slice(0,8) + '01';
        document.getElementById('ledger-date-from').value = firstDay;
        document.getElementById('ledger-date-to').value   = today;
        document.getElementById('hr-ledger-tbody').innerHTML = '';
        setText('ledger-final-balance', '0');
    }

    function generateLedger() {
        const empId = document.getElementById('ledger-employee-select').value;
        const from  = document.getElementById('ledger-date-from').value;
        const to    = document.getElementById('ledger-date-to').value;
        if (!empId) { alert('يرجى اختيار موظف'); return; }
        const emp = employees.find(e => String(e.id) === String(empId));

        let entries = [];

        advances.filter(a => String(a.employee_id) === String(empId) && a.date >= from && a.date <= to)
            .forEach(a => {
                // Only show if the journal entry hasn't been deleted
                const isJournalDeleted = !transactions.some(t => t.reference === 'ADV-' + a.id);
                if (!isJournalDeleted) {
                    entries.push({ date: a.date, desc: `سلفة نقدية (${parseInt(a.installments)||1} قسط)`, debit: parseFloat(a.amount)||0, credit: 0 });
                }
            });

        payrolls.filter(p => p.date >= from && p.date <= to).forEach(p => {
            // Only show if the journal entry hasn't been deleted
            const isJournalDeleted = !transactions.some(t => t.reference === 'PR-' + p.id);
            if (!isJournalDeleted) {
                const grid = JSON.parse(p.grid || '[]');
                const row  = grid.find(g => String(g.employee && g.employee.id) === String(empId));
                if (row) {
                    entries.push({ date: p.date, desc: `استحقاق راتب ${p.month}`, debit: 0, credit: parseFloat(row.net)||0 });
                    if ((row.advanceDeduction||0) > 0)
                        entries.push({ date: p.date, desc: `سداد قسط سلفة من راتب ${p.month}`, debit: 0, credit: parseFloat(row.advanceDeduction) });
                    
                    if (row.paid && (parseFloat(row.net)||0) > 0) {
                        const paymentTx = transactions.find(t => t.reference && t.reference.startsWith('PAY-') && t.desc && t.desc.includes(p.month));
                        const payDate = paymentTx ? paymentTx.date : p.date;
                        entries.push({ date: payDate, desc: `سداد راتب ${p.month}`, debit: parseFloat(row.net)||0, credit: 0 });
                    }
                }
            }
        });

        entries.sort((a,b) => new Date(a.date) - new Date(b.date));
        let balance = 0;
        const tbody = document.getElementById('hr-ledger-tbody');
        if (entries.length === 0) {
            tbody.innerHTML = '<tr><td colspan="5" style="text-align:center; padding:20px; color:var(--text-muted);">لا توجد حركات في هذه الفترة</td></tr>';
            setText('ledger-final-balance', '0');
            return;
        }
        tbody.innerHTML = entries.map(e => {
            balance += (e.debit||0) - (e.credit||0);
            return `<tr>
                <td>${e.date}</td>
                <td>${e.desc}</td>
                <td style="color:var(--danger)">${e.debit > 0 ? e.debit.toFixed(2) : '-'}</td>
                <td style="color:var(--success)">${e.credit > 0 ? e.credit.toFixed(2) : '-'}</td>
                <td style="font-weight:bold">${balance.toFixed(2)}</td>
            </tr>`;
        }).join('');

        window._ledgerEmp     = emp;
        window._ledgerBalance = balance > 0
            ? `${Math.abs(balance).toFixed(2)} (عليه)`
            : balance < 0
            ? `${Math.abs(balance).toFixed(2)} (له)`
            : '0 (متوازن)';
        window._ledgerEntries = entries;

        setText('ledger-final-balance', window._ledgerBalance);
    }

    function sendLedgerWhatsApp() {
        if (!window._ledgerEmp) { alert('يرجى عرض الكشف أولاً'); return; }
        const phone = window._ledgerEmp.phone;
        if (!phone) { alert('الموظف ليس لديه رقم هاتف مسجل'); return; }
        let msg = `مرحباً ${window._ledgerEmp.name}\n\nكشف حسابك:\n`;
        window._ledgerEntries.forEach(e => {
            msg += `${e.date}: ${e.desc}`;
            if (e.debit > 0)  msg += ` | عليك: ${e.debit}\n`;
            if (e.credit > 0) msg += ` | لك: ${e.credit}\n`;
        });
        msg += `\nالرصيد النهائي: ${window._ledgerBalance}\n\nمع تحيات قسم الموارد البشرية.`;
        window.open(`https://wa.me/${phone.replace(/[^0-9]/g,'')}?text=${encodeURIComponent(msg)}`, '_blank');
    }

    // ======================
    // ACCOUNT BALANCE
    // ======================

    async function updateAccountBalance(accId, debit, credit) {
        if (!accId) return;
        const acc = accounts.find(a => String(a.id) === String(accId));
        if (acc) {
            acc.balance = (parseFloat(acc.balance) || 0) + (parseFloat(debit)||0) - (parseFloat(credit)||0);
            delete acc._last_updated;
            await window.DB.update('accounts', acc);
        }
    }

    // ======================
    // MODAL HELPERS
    // ======================

    function showModal(id) {
        const el = document.getElementById(id);
        if (el) el.style.display = 'flex';
    }
    function hideModal(id) {
        const el = document.getElementById(id);
        if (el) el.style.display = 'none';
    }

    // ======================
    // TOAST NOTIFICATION
    // ======================

    function showToast(msg) {
        let t = document.getElementById('hr-toast');
        if (!t) {
            t = document.createElement('div');
            t.id = 'hr-toast';
            t.style.cssText = 'position:fixed;bottom:30px;left:50%;transform:translateX(-50%);background:#27ae60;color:white;padding:14px 28px;border-radius:30px;font-size:14px;font-weight:600;z-index:9999;box-shadow:0 4px 20px rgba(0,0,0,0.3);transition:opacity 0.3s;';
            document.body.appendChild(t);
        }
        t.innerText = msg;
        t.style.opacity = '1';
        t.style.display = 'block';
        setTimeout(() => { t.style.opacity = '0'; setTimeout(() => t.style.display='none', 300); }, 3500);
    }

    
    // ======================
    // ARCHIVE PAYROLLS
    // ======================
    function renderArchive() {
        const tbody = document.getElementById('hr-archive-tbody');
        if (!tbody) return;

        let visiblePayrolls = payrolls;
        if (currentUser && (currentUser.role !== 'مدير عام' || (currentUser.allowed_projects && currentUser.allowed_projects.length > 0))) {
            const vpIds = getVisibleProjects().map(p => String(p.id));
            visiblePayrolls = payrolls.filter(p => p.project_id !== 'all' && vpIds.includes(String(p.project_id)));
        }

        if (visiblePayrolls.length === 0) {
            tbody.innerHTML = '<tr><td colspan="7" style="text-align:center; padding:20px; color:var(--text-muted);">لا يوجد مسيرات.</td></tr>';
            document.getElementById('hr-archive-pagination').innerHTML = '';
            return;
        }
        
        // Pagination
        const limit = 100;
        const totalPages = Math.ceil(visiblePayrolls.length / limit);
        if (window.hrArchivePage > totalPages) window.hrArchivePage = totalPages;
        if (window.hrArchivePage < 1) window.hrArchivePage = 1;
        const start = (window.hrArchivePage - 1) * limit;
        const paginatedList = visiblePayrolls.slice(start, start + limit);

        tbody.innerHTML = paginatedList.map(p => {
            const isDraft = p.status === 'draft';
            const hasJournal = transactions.some(t => t.reference === 'PR-' + p.id);
            const grid = JSON.parse(p.grid || '[]');
            const allPaid = grid.length > 0 && grid.every(row => row.paid);
            
            let badge;
            if (isDraft) {
                badge = '<span class="badge" style="background:#f59e0b;color:#fff;padding:4px 8px;border-radius:4px;font-size:11px;">مسودة</span>';
            } else {
                badge = hasJournal ? '<span class="badge" style="background:var(--success);color:#fff;padding:4px 8px;border-radius:4px;font-size:11px;">مرحل</span>' : '<span class="badge" style="background:var(--danger);color:#fff;padding:4px 8px;border-radius:4px;font-size:11px;">محذوف من الحسابات</span>';
            }
            
            let payBtn = '';
            if (!isDraft) {
                payBtn = !allPaid 
                    ? `<button class="action-btn" style="background:var(--success); color:#fff;" onclick="HRApp.openPayPayrollModal(${p.id})">💸 صرف الرواتب</button>`
                    : `<span class="badge" style="background:var(--success);color:#fff;padding:4px 8px;border-radius:4px;font-size:11px; margin-right:5px;">تم الصرف</span>`;
            }

            const resumeBtn = isDraft ? `<button class="action-btn" style="background:var(--primary); color:#fff;" onclick="HRApp.resumeDraft(${p.id})">✏️ إكمال المسودة</button>` : '';

            const projName = p.project_id === 'all' ? 'جميع المشاريع' : (projects.find(pr => String(pr.id) === String(p.project_id)) || {}).name || 'غير محدد';
            
            return `<tr>
                <td>#${p.id}</td>
                <td>${p.month}</td>
                <td>${projName}</td>
                <td>${p.date}</td>
                <td style="font-weight:bold; color:var(--success);">${parseFloat(p.net_total).toFixed(2)}</td>
                <td>${badge}</td>
                <td style="display: flex; gap: 5px;">
                    ${resumeBtn}
                    ${payBtn}
                    <button class="action-btn btn-delete" onclick="HRApp.deletePayroll(${p.id})">🗑️ إلغاء</button>
                    <button class="action-btn" style="background:#3b82f6; color:#fff;" onclick="HRApp.viewArchivedPayroll(${p.id})">👁️ التفاصيل</button>
                </td>
            </tr>`;
        }).join('');
        
        renderPaginationControls(visiblePayrolls.length, window.hrArchivePage, 'hr-archive-pagination', 'changeArchivePage');
    }

    async function deletePayroll(id) {
        if (!confirm('هل أنت متأكد من الإلغاء؟')) return;

        const p = payrolls.find(x => String(x.id) === String(id));
        if (!p) return;

        const isDraft = p.status === 'draft';

        try {
            if (!isDraft) {
                // Restore leaves & advances
                const grid = JSON.parse(p.grid || '[]');
                for (const entry of grid) {
                    if (entry.leavesUsed > 0 && entry.employee) {
                        const empIndex = employees.findIndex(e => String(e.id) === String(entry.employee.id));
                        if (empIndex >= 0) {
                            employees[empIndex].leave_balance = (parseFloat(employees[empIndex].leave_balance) || 0) + entry.leavesUsed;
                            delete employees[empIndex]._last_updated;
                            await window.DB.update('employees', employees[empIndex]);
                        }
                    }
                    
                    if (entry.advanceDeduction > 0 && entry.employee) {
                        let toRestore = entry.advanceDeduction;
                        // Find completed or active advances for this employee to restore paid amount
                        // Only consider advances that started on or before this payroll's month
                        const empAdvs = advances.filter(a => {
                            if (String(a.employee_id) !== String(entry.employee.id)) return false;
                            if (!a.start_month) return true;
                            return a.start_month <= p.month;
                        }).sort((a,b) => b.id - a.id);

                        for (const adv of empAdvs) {
                            if (toRestore <= 0) break;
                            const paid = parseFloat(adv.paid_amount) || 0;
                            if (paid > 0) {
                                const restoreAmt = Math.min(paid, toRestore);
                                adv.paid_amount = paid - restoreAmt;
                                if (adv.paid_amount < parseFloat(adv.amount)) adv.status = 'active';
                                delete adv._last_updated;
                                await window.DB.update('advances', adv);
                                toRestore -= restoreAmt;
                            }
                        }
                    }
                }
            }

            if (!isDraft) {
                // Delete Journal Entry & Payments
                const journal = transactions.find(t => t.reference === 'PR-' + p.id);
                if (journal) {
                    const rows = journal.rows || [];
                    for (const d of rows) {
                        await updateAccountBalance(d.account_id, d.credit, d.debit); // reverse
                    }
                    await window.DB.remove('journal_entries', journal.id);
                }
                
                // Note: Since we don't have the payment ID, we search all transactions for a payment related to this month
                const allTransRaw = await window.DB.getAll('transactions');
                const allTrans = Array.isArray(allTransRaw) ? allTransRaw : Object.values(allTransRaw || {});
                const voucher = allTrans.find(t => t.type === 'payment' && t.category === 'رواتب' && (t.desc || '').includes(p.month));
                if (voucher) {
                    await window.DB.remove('transactions', voucher.id);
                }
            }

            // Finally, remove the payroll itself
            await window.DB.remove('payrolls', id);
            
            // Refresh
            payrolls = payrolls.filter(x => String(x.id) !== String(id));
            if (!isDraft) {
                const journal = transactions.find(t => t.reference === 'PR-' + p.id);
                if (journal) transactions = transactions.filter(t => String(t.id) !== String(journal.id));
            }
            
            renderArchive();
            updateDashboardStats();
            showToast('تم إلغاء مسير الرواتب بنجاح واسترجاع الأرصدة');
            
        } catch(e) {
            console.error('Delete payroll error', e);
            alert('حدث خطأ أثناء الإلغاء: ' + e.message);
        }
    }
    
    function resumeDraft(id) {
        const p = payrolls.find(x => String(x.id) === String(id));
        if (!p) return;
        
        // Switch tab first so preparePayrollView() runs and wipes the old state
        showView('hr-payroll');

        // Now populate the state with the draft data
        document.getElementById('payroll-month').value = p.month;
        document.getElementById('payroll-project-filter').value = p.project_id || 'all';
        document.getElementById('payroll-id').value = p.id;
        
        window.hrPayrollGrid = JSON.parse(p.grid || '[]');
        renderPayrollGrid();
        
        showToast('تم فتح المسودة لتعديلها');
    }
    
    function viewArchivedPayroll(id) {
        const p = payrolls.find(x => String(x.id) === String(id));
        if (!p) return;
        
        const projName = p.project_id === 'all' ? 'جميع المشاريع' : (projects.find(pr => String(pr.id) === String(p.project_id)) || {}).name || 'غير محدد';
        document.getElementById('hr-view-payroll-title').innerText = `تفاصيل مسير الرواتب - شهر ${p.month} (${projName})`;
        
        const tbody = document.getElementById('hr-view-payroll-tbody');
        const grid = JSON.parse(p.grid || '[]');
        
        let tBasic=0, tAllow=0, tBonus=0, tLeave=0, tDed=0, tAbs=0, tAdv=0, tNet=0;

        if (grid.length === 0) {
            tbody.innerHTML = '<tr><td colspan="9" style="text-align:center;">لا توجد بيانات تفصيلية مسجلة لهذا المسير.</td></tr>';
        } else {
            tbody.innerHTML = grid.map(row => {
                let empName = row.employee ? row.employee.name : 'موظف محذوف';
                if (p.project_id === 'all' && row.employee && row.employee.project_id) {
                    const empProjName = (projects.find(pr => String(pr.id) === String(row.employee.project_id)) || {}).name;
                    if (empProjName) empName += `<br><span style="font-size:10px; color:gray;">${empProjName}</span>`;
                }
                const leaveDays = row.leavesUsed || 0;
                const dailyRate = row.dailyRate || 0;
                const leaveVal = leaveDays * dailyRate;
                const basic = parseFloat(row.basic_salary || row.employee?.basic_salary || 0);
                const allow = parseFloat(row.allowances || ((parseFloat(row.employee?.housing_allowance||0))+(parseFloat(row.employee?.transport_allowance||0))) || 0);
                const bonus = parseFloat(row.bonus||row.overtime||0);
                const ded = parseFloat(row.deductions||row.deduction||0);
                const absDays = row.absences||row.absenceDays||0;
                const absVal = parseFloat(row.absenceDeduction||0);
                const adv = parseFloat(row.advanceDeduction||0);
                const net = parseFloat(row.net||0);

                tBasic += basic;
                tAllow += allow;
                tBonus += bonus;
                tLeave += leaveVal;
                tDed += ded;
                tAbs += absVal;
                tAdv += adv;
                tNet += net;

                return `<tr>
                    <td>${empName}</td>
                    <td>${basic.toFixed(2)}</td>
                    <td>${allow.toFixed(2)}</td>
                    <td>${bonus.toFixed(2)}</td>
                    <td>${leaveDays} أيام (${leaveVal.toFixed(2)})</td>
                    <td>${ded.toFixed(2)}</td>
                    <td>${absDays} (${absVal.toFixed(2)})</td>
                    <td>${adv.toFixed(2)}</td>
                    <td style="color:var(--success); font-weight:bold;">${net.toFixed(2)}</td>
                </tr>`;
            }).join('');
        }
        
        setText('view-total-basic', tBasic.toFixed(2));
        setText('view-total-allowances', tAllow.toFixed(2));
        setText('view-total-bonus', tBonus.toFixed(2));
        setText('view-total-leaves', tLeave.toFixed(2));
        setText('view-total-deductions', tDed.toFixed(2));
        setText('view-total-absence', tAbs.toFixed(2));
        setText('view-total-advances', tAdv.toFixed(2));
        setText('view-total-net', tNet.toFixed(2));
        
        document.getElementById('hr-view-payroll-modal').style.display = 'flex';
    }
    
        // ======================
    // BULK ATTENDANCE
    // ======================

    async function viewEmployeeStatement(empId, empName) {
        document.getElementById('hr-statement-emp-id').value = empId;
        document.getElementById('hr-statement-emp-name').value = empName;
        
        const monthInput = document.getElementById('hr-statement-month');
        if (!monthInput.value) {
            const now = new Date();
            monthInput.value = `${now.getFullYear()}-${String(now.getMonth()+1).padStart(2, '0')}`;
        }
        
        await fetchAndRenderStatement();
        
        const modal = document.getElementById('hr-statement-modal');
        if (modal) modal.style.display = 'flex';
    }

    async function refreshEmployeeStatement() {
        await fetchAndRenderStatement();
    }

    async function fetchAndRenderStatement() {
        const empId = document.getElementById('hr-statement-emp-id').value;
        const empName = document.getElementById('hr-statement-emp-name').value;
        const month = document.getElementById('hr-statement-month').value;
        
        if (!empId) return;

        document.getElementById('loading-overlay').style.display = 'flex';
        try {
            const res = await fetch(`api.php?store=get_employee_absences&emp_id=${empId}&month=${month}`);
            const data = await res.json();
            
            document.getElementById('hr-statement-modal-title').innerText = `كشف الدوام - ${empName} (${month})`;
            const tbody = document.getElementById('hr-statement-tbody');
            
            if (!data || data.length === 0) {
                tbody.innerHTML = '<tr><td colspan="3" style="text-align:center;">لا يوجد سجل دوام مسجل في هذا الشهر</td></tr>';
            } else {
                tbody.innerHTML = data.map(record => {
                    const statusColor = record.status === 'غياب' ? 'var(--danger)' : (record.status === 'إجازة' ? 'var(--hr-accent)' : 'var(--success)');
                    const statusBg = record.status === 'غياب' ? 'rgba(231, 76, 60, 0.1)' : 'transparent';
                    return `<tr style="background:${statusBg}">
                        <td>${record.date}</td>
                        <td style="color:${statusColor}; font-weight:bold;">${record.status}</td>
                        <td>${record.notes || '-'}</td>
                    </tr>`;
                }).join('');
            }
        } catch (e) {
            console.error(e);
            alert('حدث خطأ أثناء جلب الكشف');
        } finally {
            document.getElementById('loading-overlay').style.display = 'none';
        }
    }

    function prepareAttendanceView() {
        const dateInput = document.getElementById('hr-attendance-date');
        if (!dateInput.value) {
            dateInput.value = new Date().toISOString().split('T')[0];
        }

        // Populate projects dropdown
        const projectSelect = document.getElementById('hr-attendance-project');
        if (projectSelect) {
            const allowedProjects = getVisibleProjects();
            let optionsHTML = '';
            
            // If user is admin or has multiple projects, show "All"
            if (currentUser && currentUser.role === 'مدير عام') {
                optionsHTML += '<option value="all">الكل</option>';
            } else if (allowedProjects.length > 1) {
                optionsHTML += '<option value="all">كل المواقع التابعة لي</option>';
            }

            optionsHTML += allowedProjects.map(p => `<option value="${p.id}">${p.name}</option>`).join('');
            projectSelect.innerHTML = optionsHTML;

            // If only one project is allowed, it will be the only option and selected by default
            if (allowedProjects.length === 1 && (!currentUser || currentUser.role !== 'مدير عام')) {
                projectSelect.value = allowedProjects[0].id;
                projectSelect.disabled = true;
            } else {
                projectSelect.disabled = false;
            }
        }

        loadAttendanceForDate();
    }

    async function loadAttendanceForDate() {
        const dateInput = document.getElementById('hr-attendance-date');
        const projectSelect = document.getElementById('hr-attendance-project');
        
        if (!dateInput.value) {
            document.getElementById('hr-attendance-tbody').innerHTML = '<tr><td colspan="4" style="text-align:center;">يرجى اختيار التاريخ أولاً</td></tr>';
            return;
        }

        const date = dateInput.value;
        const selectedProject = projectSelect ? projectSelect.value : 'all';
        const allowedProjectIds = getVisibleProjects().map(p => String(p.id));

        const tbody = document.getElementById('hr-attendance-tbody');
        tbody.innerHTML = '<tr><td colspan="4" style="text-align:center;">جاري تحميل البيانات...</td></tr>';

        try {
            const res = await fetch('api.php?store=get_bulk_attendance&date=' + date);
            let data = await res.json();
            
            if (data.error) throw new Error(data.error);

            // Filter data based on allowed projects AND selected project
            data = data.filter(emp => {
                // Check if employee is in user's allowed projects
                if (currentUser && currentUser.role !== 'مدير عام') {
                    if (!emp.project_id || !allowedProjectIds.includes(String(emp.project_id))) {
                        return false; // User doesn't have permission to see this employee's project
                    }
                }
                
                // Check against the selected filter
                if (selectedProject !== 'all') {
                    return String(emp.project_id) === String(selectedProject);
                }
                
                return true;
            });

            window.currentBulkAttendance = data; 
            
            if (data.length === 0) {
                tbody.innerHTML = '<tr><td colspan="4" style="text-align:center;">لا يوجد موظفين نشطين لعرضهم في هذا الموقع</td></tr>';
                return;
            }

            tbody.innerHTML = '';
            data.forEach((emp, index) => {
                const tr = document.createElement('tr');
                tr.innerHTML = `
                    <td style="text-align:center;">${index + 1}</td>
                    <td>${emp.name}</td>
                    <td style="text-align:center; display:flex; justify-content:center; gap:15px; align-items:center;">
                        <label style="cursor:pointer; display:flex; align-items:center; gap:5px; color:var(--success);">
                            <input type="radio" name="att_status_${emp.employee_id}" value="حضور" ${emp.status === 'حضور' ? 'checked' : ''} onchange="HRApp.updateAttendanceLocal(${emp.employee_id}, 'status', 'حضور')">
                            حضور
                        </label>
                        <label style="cursor:pointer; display:flex; align-items:center; gap:5px; color:var(--danger);">
                            <input type="radio" name="att_status_${emp.employee_id}" value="غياب" ${emp.status === 'غياب' ? 'checked' : ''} onchange="HRApp.updateAttendanceLocal(${emp.employee_id}, 'status', 'غياب')">
                            غياب
                        </label>
                        <label style="cursor:pointer; display:flex; align-items:center; gap:5px; color:var(--hr-accent);">
                            <input type="radio" name="att_status_${emp.employee_id}" value="إجازة" ${emp.status === 'إجازة' ? 'checked' : ''} onchange="HRApp.updateAttendanceLocal(${emp.employee_id}, 'status', 'إجازة')">
                            إجازة
                        </label>
                    </td>
                    <td>
                        <input type="text" value="${emp.notes || ''}" placeholder="ملاحظات..." onchange="HRApp.updateAttendanceLocal(${emp.employee_id}, 'notes', this.value)" style="width:100%; padding:8px; border-radius:6px; border:1px solid rgba(255,255,255,0.2); background:var(--input-bg, transparent); color:var(--text-color, inherit); font-family:'Cairo';">
                    </td>
                `;
                tbody.appendChild(tr);
            });
        } catch (e) {
            console.error(e);
            tbody.innerHTML = '<tr><td colspan="4" style="text-align:center; color:#e74c3c;">حدث خطأ أثناء جلب البيانات</td></tr>';
        }
    }

    function updateAttendanceLocal(empId, field, value) {
        if (!window.currentBulkAttendance) return;
        const emp = window.currentBulkAttendance.find(e => String(e.employee_id) === String(empId));
        if (emp) {
            emp[field] = value;
        }
    }

    async function saveDailyAttendance() {
        const dateInput = document.getElementById('hr-attendance-date');
        if (!dateInput.value) {
            showToast('يرجى اختيار التاريخ أولاً');
            return;
        }

        if (!window.currentBulkAttendance || window.currentBulkAttendance.length === 0) {
            showToast('لا توجد بيانات للحفظ');
            return;
        }

        document.getElementById('loading-overlay').style.display = 'flex';

        try {
            const payload = {
                date: dateInput.value,
                records: window.currentBulkAttendance
            };

            const res = await fetch('api.php?store=save_bulk_attendance', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });

            const data = await res.json();
            if (data.error) throw new Error(data.error);

            showToast('تم حفظ كشف الحضور والانصراف بنجاح!');
        } catch (e) {
            console.error(e);
            alert('خطأ أثناء الحفظ: ' + e.message);
        } finally {
            document.getElementById('loading-overlay').style.display = 'none';
        }
    }

    // ======================
    // BOOTSTRAP
    // ======================
    window.onload = init;

    return {
        login:               loginFromForm,
        logout,
        openEmployeeModal,
        closeEmployeeModal,
        filterEmployees: () => { window.hrEmployeesPage = 1; renderEmployees(); },
        filterAdvances:  () => { window.advancesCurrentPage = 1; renderAdvances(); },
        saveEmployee,
        deleteEmployee,
        openAdvanceModal,
        closeAdvanceModal,
        saveAdvance,
        deleteAdvance,
        deletePayroll,
        viewArchivedPayroll,
        generatePayroll,
        recalcPayrollRow,
        savePayroll,
        executePayPayroll,
        openPayPayrollModal,
        generateLedger,
        sendLedgerWhatsApp,
        showView,
        renderEmployees,
        renderAdvances,
        prepareAttendanceView,
        loadAttendanceForDate,
        updateAttendanceLocal,
        saveDailyAttendance,
        viewEmployeeStatement,
        refreshEmployeeStatement,
        resumeDraft
    };
})();


