// ============================================================
// 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 = [];

    // ======================
    // 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';
        const username = (document.getElementById('login-username').value || '').trim();
        const password = (document.getElementById('login-password').value || '').trim();
        if (!username || !password) {
            errEl.innerText = 'يرجى إدخال اسم المستخدم وكلمة المرور';
            errEl.style.display = 'block';
            return;
        }
        const ok = await waitForDB();
        if (!ok) {
            errEl.innerText = 'خطأ في الاتصال بقاعدة البيانات';
            errEl.style.display = 'block';
            return;
        }
        try {
            const allUsers = await window.DB.getAll('users');
            const found = allUsers.find(u => u.username === username && u.password === 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();
        } finally {
            if (loader) loader.style.display = 'none';
        }
    }

    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);
            }
        }
    }

    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 activeAdv  = advances.filter(a => a.status === 'active').length;
        const totalPaid  = payrolls.reduce((s, p) => s + (parseFloat(p.net_total) || 0), 0);
        const totalAdvAmt = advances.reduce((s, a) => s + ((parseFloat(a.amount) || 0) - (parseFloat(a.paid_amount) || 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.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>';
            return;
        }
        let totalBasic = 0, totalHousing = 0, totalTransport = 0, grandTotal = 0;
        
        const rowsHtml = list.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;
    }

    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
    // ======================

    function renderAdvances() {
        const tbody = document.getElementById('hr-advances-tbody');
        if (!tbody) return;
        const empIds = getVisibleEmployees().map(e => String(e.id));
        const list   = advances.filter(a => empIds.includes(String(a.employee_id)));

        if (list.length === 0) {
            tbody.innerHTML = '<tr><td colspan="8" style="text-align:center; padding:30px; color:var(--text-muted);">لا يوجد سلف مسجلة.</td></tr>';
            return;
        }
        tbody.innerHTML = list.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>';
            return `<tr>
                <td>${adv.date || ''}</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>${badge}</td>
                <td><button class="action-btn btn-delete" onclick="HRApp.deleteAdvance(${adv.id})">🗑️ حذف</button></td>
            </tr>`;
        }).join('');
    }

    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'
        };

        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 allTrans = await window.DB.getAll('transactions');
            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; }

        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;
            advances.filter(a => String(a.employee_id) === String(emp.id) && a.status === 'active').forEach(adv => {
                const remain = (parseFloat(adv.amount) || 0) - (parseFloat(adv.paid_amount) || 0);
                const inst   = (parseFloat(adv.amount) || 0) / (parseInt(adv.installments) || 1);
                advanceDeduction += Math.min(inst, remain);
            });

            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" max="${emp.leave_balance || 0}"
                    oninput="HRApp.recalcPayrollRow(${emp.id})"
                    title="الرصيد المتاح: ${emp.leave_balance || 0} يوم"
                    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 recalcPayrollRow(empId) {
        const rowId = 'pr_' + empId;
        const entry = window.hrPayrollGrid.find(g => String(g.employee.id) === String(empId));
        if (!entry) return;

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

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

        entry.net = entry.totalFixed + entry.bonus - entry.deduction - leaveDeduction - 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() {
        if (!window.hrPayrollGrid || window.hrPayrollGrid.length === 0) {
            alert('جدول المسير فارغ'); return;
        }
        const month      = document.getElementById('payroll-month').value;
        const projFilter = document.getElementById('payroll-project-filter').value;

        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 (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;
                await window.DB.update('employees', entry.employee);
            }

            // update advances paid
            if (entry.advanceDeduction > 0) {
                let left = entry.advanceDeduction;
                for (const adv of advances.filter(a => String(a.employee_id) === String(entry.employee.id) && a.status === 'active')) {
                    if (left <= 0) break;
                    const remain = (parseFloat(adv.amount) || 0) - (parseFloat(adv.paid_amount) || 0);
                    const toDeduct = Math.min(left, remain);
                    adv.paid_amount = (parseFloat(adv.paid_amount) || 0) + toDeduct;
                    if (adv.paid_amount >= parseFloat(adv.amount)) adv.status = 'completed';
                    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     = Date.now();

        const realPid = await window.DB.add('payrolls', {
            id:         pid,
            month:      month,
            project_id: projFilter,
            grid:       JSON.stringify(window.hrPayrollGrid),
            net_total:  totalNetOverall,
            date:       new Date().toISOString().split('T')[0],
            status:     'approved'
        });

        const actualPid = realPid || pid; // Fallback just in case

        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 (advances are usually not project-specific in deduction)
        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();

        // Not showing payment modal automatically as requested.

        setText('hr-payroll-tbody', '');
        document.getElementById('hr-payroll-tbody').innerHTML =
            '<tr><td colspan="9" style="text-align:center; padding:20px; color:var(--success);">✅ تم اعتماد المسير بنجاح.</td></tr>';
        window.hrPayrollGrid = [];
    }

    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);
            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="6" style="text-align:center; padding:20px; color:var(--text-muted);">لا يوجد مسيرات معتمدة.</td></tr>';
            return;
        }

        tbody.innerHTML = visiblePayrolls.map(p => {
            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);
            const 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>';
            
            const 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>`;
            
            return `<tr>
                <td>#${p.id}</td>
                <td>${p.month}</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;">
                    ${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('');
    }

    async function deletePayroll(id) {
        if (!confirm('سيتم إلغاء هذا المسير بالكامل واسترجاع أرصدة الإجازات وسلف الموظفين المرتبطة به وحذف القيد المحاسبي. هل أنت متأكد من الإلغاء؟')) return;

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

        // Restore leaves & advances
        try {
            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;
                        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
                    const empAdvs = advances.filter(a => String(a.employee_id) === String(entry.employee.id)).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';
                            await window.DB.update('advances', adv);
                            toRestore -= restoreAmt;
                        }
                    }
                }
            }

            // 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 allTrans = await window.DB.getAll('transactions');
            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 (journal) transactions = transactions.filter(t => String(t.id) !== String(journal.id));
            
            renderArchive();
            updateDashboardStats();
            showToast('تم إلغاء مسير الرواتب بنجاح واسترجاع الأرصدة');
            
        } catch(e) {
            console.error('Delete payroll error', e);
            alert('حدث خطأ أثناء الإلغاء');
        }
    }
    
    
    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 || '[]');
        
        if (grid.length === 0) {
            tbody.innerHTML = '<tr><td colspan="8" 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>`;
                }
                return `<tr>
                    <td>${empName}</td>
                    <td>${parseFloat(row.basic_salary || row.employee?.basic_salary || 0).toFixed(2)}</td>
                    <td>${parseFloat(row.allowances || ((parseFloat(row.employee?.housing_allowance||0))+(parseFloat(row.employee?.transport_allowance||0))) || 0).toFixed(2)}</td>
                    <td>${parseFloat(row.bonus||row.overtime||0).toFixed(2)}</td>
                    <td>${parseFloat(row.deductions||row.deduction||0).toFixed(2)}</td>
                    <td>${row.absences||row.absenceDays||0} (${parseFloat(row.absenceDeduction||0).toFixed(2)})</td>
                    <td>${parseFloat(row.advanceDeduction||0).toFixed(2)}</td>
                    <td style="color:var(--success); font-weight:bold;">${parseFloat(row.net||0).toFixed(2)}</td>
                </tr>`;
            }).join('');
        }
        
        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,
        saveEmployee,
        deleteEmployee,
        openAdvanceModal,
        closeAdvanceModal,
        saveAdvance,
        deleteAdvance,
        deletePayroll,
        viewArchivedPayroll,
        generatePayroll,
        recalcPayrollRow,
        savePayroll,
        executePayPayroll,
        openPayPayrollModal,
        generateLedger,
        sendLedgerWhatsApp,
        showView,
        renderEmployees,
        prepareAttendanceView,
        loadAttendanceForDate,
        updateAttendanceLocal,
        saveDailyAttendance,
        viewEmployeeStatement,
        refreshEmployeeStatement
    };
})();


