/**
 * PayrollRunSection.js — اجرای حقوق و دستمزد
 *
 * جریان:
 *   ایجاد دوره (draft)
 *   → تولید فیش‌ها (generated)   ← محاسبه از اجزای حقوقی
 *   → نهایی‌سازی (finalized)     ← ثبت رویداد SALARY_RECOGNITION
 *   → پرداخت (paid)              ← ثبت رویداد SALARY_PAYMENT
 */
import SectionBase from "../../accounting/SectionBase.js";

const PERSIAN_MONTHS = ['','فروردین','اردیبهشت','خرداد','تیر','مرداد','شهریور',
                        'مهر','آبان','آذر','دی','بهمن','اسفند'];

const STATUS_META = {
    draft:     { label: "پیش‌نویس",   cls: "status-badge--draft",     color: "#f59e0b" },
    generated: { label: "فیش‌تولیدشده", cls: "status-badge--pending",  color: "#3b82f6" },
    finalized: { label: "نهایی‌شده",   cls: "status-badge--confirmed", color: "#059669" },
    paid:      { label: "پرداخت‌شده",  cls: "status-badge--confirmed", color: "#7c3aed" },
};

export default class PayrollRunSection extends SectionBase {

    constructor(props = {}) {
        super(props);
        this._view           = "list";   // 'list' | 'detail'
        this._periods        = [];
        this._projects       = [];
        this._selectedPeriod = null;
        this._slips          = [];
    }

    async template() {
        return `<div data-ref="root"></div>`;
    }

    async afterRender() {
        await this._loadProjects();
        await this._showList();
    }

    async _loadProjects() {
        try {
            const res = await this.api.get("/pc/projects", { per_page: 200 }).catch(() => null);
            this._projects = res?.data ?? [];
        } catch { /* non-fatal */ }
    }

    /* ══════════════════════════════════════════════════════════════
       LIST VIEW
    ══════════════════════════════════════════════════════════════ */

    async _showList() {
        this._view = "list";
        const root = this.ref("root");
        root.innerHTML = `
            <div style="display:flex;gap:10px;align-items:center;margin-bottom:16px;flex-wrap:wrap;">
                <button class="acc-btn acc-btn--primary" data-ref="newBtn">➕ دوره حقوقی جدید</button>
                <button class="acc-btn acc-btn--secondary acc-btn--sm" data-ref="refreshBtn">🔄</button>
            </div>
            <div data-ref="listBody"></div>
        `;
        this._bindRef();
        this.on(this.ref("newBtn"),    "click", () => this._openCreatePeriod());
        this.on(this.ref("refreshBtn"),"click", () => this._loadList());
        await this._loadList();
    }

    _bindRef() {
        this.ref("root")?.querySelectorAll("[data-ref]").forEach(el => {
            this.refs[el.dataset.ref] = el;
        });
    }

    async _loadList() {
        const body = this.ref("listBody");
        if (!body) return;
        body.innerHTML = `<div class="acc-loading"><div class="acc-spinner"></div></div>`;
        try {
            const res = await this.api.get("/payroll/periods");
            this._periods = res?.data ?? [];
            this._renderList(body);
        } catch {
            body.innerHTML = `<div class="acc-error">خطا در بارگذاری دوره‌ها</div>`;
        }
    }

    _renderList(body) {
        if (!this._periods.length) {
            body.innerHTML = `<div class="acc-empty">هیچ دوره حقوقی‌ای ثبت نشده است. با دکمه بالا شروع کنید.</div>`;
            return;
        }
        body.innerHTML = "";
        this._periods.forEach(p => {
            body.appendChild(this._buildPeriodCard(p));
        });
    }

    _buildPeriodCard(p) {
        const meta = STATUS_META[p.status] ?? STATUS_META.draft;
        const div  = document.createElement("div");
        div.className = "payroll-period-card";
        div.style.borderRight = `4px solid ${meta.color}`;
        div.innerHTML = `
            <div style="flex:1;min-width:0;">
                <div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;">
                    <div style="font-size:16px;font-weight:800;color:#1e293b;">${this.escape(p.period_name)}</div>
                    <span class="status-badge ${meta.cls}">${meta.label}</span>
                    ${p.project_name ? `<span style="font-size:11px;background:#ede9fe;color:#4f46e5;border-radius:8px;padding:2px 9px;font-weight:600;">🏗 ${this.escape(p.project_name)}</span>` : ""}
                    ${p.recognition_event_id ? `<span class="acc-link-badge">🔗 شناخت #${p.recognition_event_id}</span>` : ""}
                    ${p.payment_event_id     ? `<span class="acc-link-badge" style="background:#ede9fe;color:#5b21b6;">💳 پرداخت #${p.payment_event_id}</span>` : ""}
                </div>
                ${p.slip_count > 0 ? `
                <div class="sp-kpi-row" style="margin-top:12px;margin-bottom:0;">
                    <div class="sp-kpi sp-kpi--blue"  style="padding:10px 14px;"><div class="sp-kpi__value">${p.slip_count}</div><div class="sp-kpi__label">پرسنل</div></div>
                    <div class="sp-kpi sp-kpi--green" style="padding:10px 14px;"><div class="sp-kpi__value">${this._fmt(p.total_gross)}</div><div class="sp-kpi__label">ناخالص ﷼</div></div>
                    <div class="sp-kpi sp-kpi--orange" style="padding:10px 14px;"><div class="sp-kpi__value">${this._fmt(p.total_deductions)}</div><div class="sp-kpi__label">کسورات ﷼</div></div>
                    <div class="sp-kpi sp-kpi--purple" style="padding:10px 14px;"><div class="sp-kpi__value">${this._fmt(p.total_net)}</div><div class="sp-kpi__label">خالص ﷼</div></div>
                </div>` : ""}
            </div>
            <div style="display:flex;flex-direction:column;gap:6px;align-items:flex-end;min-width:130px;">
                <button class="acc-btn acc-btn--secondary acc-btn--sm" data-action="detail">📋 مشاهده جزئیات</button>
                ${p.status === "draft" ? `<button class="acc-btn acc-btn--primary acc-btn--sm" data-action="generate">⚙️ تولید فیش‌ها</button>` : ""}
                ${p.status === "generated" ? `<button class="acc-btn acc-btn--primary acc-btn--sm" data-action="generate" style="background:#3b82f6;border-color:#3b82f6;">🔄 بازتولید فیش‌ها</button><button class="acc-btn acc-btn--primary acc-btn--sm" data-action="finalize" style="background:#059669;border-color:#059669;">✅ نهایی‌سازی</button>` : ""}
                ${p.status === "finalized" ? `<button class="acc-btn acc-btn--primary acc-btn--sm" data-action="pay" style="background:#7c3aed;border-color:#7c3aed;">💳 ثبت پرداخت</button>` : ""}
            </div>
        `;
        div.querySelector("[data-action='detail']").addEventListener("click", () => this._showDetail(p));
        div.querySelector("[data-action='generate']")?.addEventListener("click", e => { e.stopPropagation(); this._generate(p.id, div); });
        div.querySelector("[data-action='finalize']")?.addEventListener("click", e => { e.stopPropagation(); this._finalize(p.id); });
        div.querySelector("[data-action='pay']")?.addEventListener("click",      e => { e.stopPropagation(); this._pay(p.id); });
        return div;
    }

    /* ── Create period modal ────────────────────────────────────── */

    _openCreatePeriod() {
        const monthOpts = PERSIAN_MONTHS.slice(1).map((m, i) =>
            `<option value="${i + 1}">${m}</option>`
        ).join("");

        const projectOpts = this._projects.length
            ? `<option value="">— بدون پروژه —</option>` +
              this._projects.map(p => `<option value="${p.id}">${this.escape(p.name)}</option>`).join("")
            : null;

        const ov = document.createElement("div"); ov.className = "acc-modal-overlay";
        ov.innerHTML = `
            <div class="acc-modal" style="max-width:420px;">
                <button class="acc-modal__close">✕</button>
                <div class="acc-modal__title">ایجاد دوره حقوقی جدید</div>
                <form>
                    <div class="doc-form-row">
                        <div class="acc-form-group">
                            <label>سال شمسی *</label>
                            <input name="year" type="number" min="1390" max="1450" value="1403" required>
                        </div>
                        <div class="acc-form-group">
                            <label>ماه *</label>
                            <select name="month">${monthOpts}</select>
                        </div>
                    </div>
                    ${projectOpts ? `
                    <div class="acc-form-group">
                        <label>پروژه (اختیاری)</label>
                        <select name="project_id">${projectOpts}</select>
                    </div>` : ""}
                    <div class="acc-modal__actions">
                        <button type="button" class="acc-btn acc-btn--secondary" data-action="cancel">انصراف</button>
                        <button type="submit" class="acc-btn acc-btn--primary">ایجاد دوره</button>
                    </div>
                </form>
            </div>`;
        document.body.appendChild(ov);
        const close = () => ov.remove();
        ov.querySelector(".acc-modal__close").addEventListener("click", close);
        ov.querySelector("[data-action='cancel']").addEventListener("click", close);
        ov.addEventListener("click", ev => { if (ev.target === ov) close(); });
        ov.querySelector("form").addEventListener("submit", async ev => {
            ev.preventDefault();
            const raw  = Object.fromEntries(new FormData(ev.target).entries());
            const body = { year: raw.year, month: raw.month };
            if (raw.project_id) body.project_id = parseInt(raw.project_id);
            const btn  = ev.target.querySelector("[type='submit']");
            btn.disabled = true; btn.textContent = "در حال ایجاد...";
            try {
                await this.api.post("/payroll/periods", body);
                close(); await this._loadList();
            } catch (err) {
                alert("خطا: " + (err?.message ?? ""));
                btn.disabled = false; btn.textContent = "ایجاد دوره";
            }
        });
    }

    /* ── Generate slips ─────────────────────────────────────────── */

    async _generate(periodId, card) {
        if (!confirm("فیش‌های حقوقی تولید شود؟ اگر قبلاً تولید شده بودند بازنویسی می‌شوند.")) return;
        const btn = card?.querySelector("[data-action='generate']");
        if (btn) { btn.disabled = true; btn.textContent = "⏳ در حال محاسبه..."; }
        try {
            const res = await this.api.post(`/payroll/periods/${periodId}/generate`, {});
            this._toast(`✅ ${res.slip_count} فیش تولید شد — خالص کل: ${this._fmt(res.total_net)} ﷼`);
            await this._loadList();
        } catch (err) {
            alert("خطا: " + (err?.message ?? ""));
            if (btn) { btn.disabled = false; btn.textContent = "⚙️ تولید فیش‌ها"; }
        }
    }

    /* ── Finalize period ────────────────────────────────────────── */

    async _finalize(periodId) {
        if (!confirm("دوره را نهایی کنید؟ رویداد حسابداری «شناخت حقوق» ثبت می‌شود.")) return;
        try {
            const res = await this.api.post(`/payroll/periods/${periodId}/finalize`, {});
            if (res?.success) {
                this._toast(`✅ دوره نهایی شد — رویداد #${res.event_id} ثبت گردید`);
                await this._loadList();
            } else { alert("خطا: " + (res?.message ?? "")); }
        } catch (err) { alert("خطا: " + (err?.message ?? "")); }
    }

    /* ── Pay period ─────────────────────────────────────────────── */

    async _pay(periodId) {
        if (!confirm("پرداخت حقوق ثبت شود؟ رویداد حسابداری «پرداخت حقوق» صادر می‌گردد.")) return;
        try {
            const res = await this.api.post(`/payroll/periods/${periodId}/pay`, {});
            if (res?.success) {
                this._toast(`💳 پرداخت حقوق ثبت شد — رویداد #${res.event_id}`, "#7c3aed");
                await this._loadList();
            } else { alert("خطا: " + (res?.message ?? "")); }
        } catch (err) { alert("خطا: " + (err?.message ?? "")); }
    }

    /* ══════════════════════════════════════════════════════════════
       DETAIL VIEW
    ══════════════════════════════════════════════════════════════ */

    async _showDetail(period) {
        this._view           = "detail";
        this._selectedPeriod = period;

        const root = this.ref("root");
        const meta = STATUS_META[period.status] ?? STATUS_META.draft;

        root.innerHTML = `
            <div style="display:flex;align-items:center;gap:12px;margin-bottom:20px;flex-wrap:wrap;">
                <button class="acc-btn acc-btn--secondary" data-ref="backBtn">← بازگشت به لیست</button>
                <h2 style="margin:0;font-size:18px;font-weight:800;color:#1e293b;">${this.escape(period.period_name)}</h2>
                <span class="status-badge ${meta.cls}">${meta.label}</span>
            </div>

            <!-- KPI Row -->
            <div class="sp-kpi-row" style="margin-bottom:20px;">
                <div class="sp-kpi sp-kpi--blue">
                    <div class="sp-kpi__value" data-ref="kpiSlips">${period.slip_count || 0}</div>
                    <div class="sp-kpi__label">تعداد فیش</div>
                </div>
                <div class="sp-kpi sp-kpi--green">
                    <div class="sp-kpi__value" data-ref="kpiGross">${this._fmt(period.total_gross)}</div>
                    <div class="sp-kpi__label">ناخالص (ریال)</div>
                </div>
                <div class="sp-kpi sp-kpi--orange">
                    <div class="sp-kpi__value" data-ref="kpiDed">${this._fmt(period.total_deductions)}</div>
                    <div class="sp-kpi__label">کسورات (ریال)</div>
                </div>
                <div class="sp-kpi sp-kpi--purple">
                    <div class="sp-kpi__value" data-ref="kpiNet">${this._fmt(period.total_net)}</div>
                    <div class="sp-kpi__label">خالص (ریال)</div>
                </div>
            </div>

            <!-- Action bar -->
            <div style="display:flex;gap:10px;margin-bottom:16px;flex-wrap:wrap;" data-ref="actionBar"></div>

            <!-- Slips table -->
            <div data-ref="slipsWrap">
                <div class="acc-loading"><div class="acc-spinner"></div></div>
            </div>
        `;
        this._bindRef();

        this.on(this.ref("backBtn"), "click", () => this._showList());

        // Build action buttons
        this._rebuildActions(period);

        // Load slips
        await this._loadSlips(period.id);
    }

    _rebuildActions(period) {
        const bar = this.ref("actionBar");
        if (!bar) return;
        bar.innerHTML = "";
        if (period.status === "draft" || period.status === "generated") {
            const genBtn = document.createElement("button");
            genBtn.className = "acc-btn acc-btn--primary";
            genBtn.textContent = period.status === "draft" ? "⚙️ تولید فیش‌ها" : "🔄 بازتولید فیش‌ها";
            genBtn.addEventListener("click", async () => {
                if (!confirm("فیش‌های حقوقی تولید / بازتولید شود؟")) return;
                genBtn.disabled = true; genBtn.textContent = "⏳ در حال محاسبه...";
                try {
                    const res = await this.api.post(`/payroll/periods/${period.id}/generate`, {});
                    this._toast(`✅ ${res.slip_count} فیش تولید شد`);
                    // Reload period + slips
                    const pRes = await this.api.get(`/payroll/periods/${period.id}`);
                    period = pRes?.data ?? period;
                    this._selectedPeriod = period;
                    this._updateKPIs(period);
                    this._rebuildActions(period);
                    await this._loadSlips(period.id);
                } catch (err) { alert("خطا: " + (err?.message ?? "")); genBtn.disabled = false; }
            });
            bar.appendChild(genBtn);
        }
        if (period.status === "generated") {
            const finBtn = document.createElement("button");
            finBtn.className = "acc-btn acc-btn--primary";
            finBtn.style.cssText = "background:#059669;border-color:#059669;";
            finBtn.textContent = "✅ نهایی‌سازی و ثبت حسابداری";
            finBtn.addEventListener("click", async () => {
                if (!confirm("دوره نهایی شود و رویداد شناخت حقوق در دفتر کل ثبت گردد؟")) return;
                finBtn.disabled = true; finBtn.textContent = "⏳ در حال ثبت...";
                try {
                    const res = await this.api.post(`/payroll/periods/${period.id}/finalize`, {});
                    if (res?.success) {
                        this._toast(`✅ نهایی‌سازی انجام شد — رویداد حسابداری #${res.event_id}`);
                        const pRes = await this.api.get(`/payroll/periods/${period.id}`);
                        period = pRes?.data ?? period;
                        this._selectedPeriod = period;
                        this._updateKPIs(period);
                        this._rebuildActions(period);
                        await this._loadSlips(period.id);
                    } else { alert("خطا: " + (res?.message ?? "")); finBtn.disabled = false; }
                } catch (err) { alert("خطا: " + (err?.message ?? "")); finBtn.disabled = false; }
            });
            bar.appendChild(finBtn);
        }
        if (period.status === "finalized") {
            const payBtn = document.createElement("button");
            payBtn.className = "acc-btn acc-btn--primary";
            payBtn.style.cssText = "background:#7c3aed;border-color:#7c3aed;";
            payBtn.textContent = "💳 ثبت پرداخت حقوق";
            payBtn.addEventListener("click", async () => {
                if (!confirm("پرداخت حقوق ثبت شود؟ رویداد حسابداری «پرداخت» صادر می‌گردد.")) return;
                payBtn.disabled = true; payBtn.textContent = "⏳ در حال ثبت...";
                try {
                    const res = await this.api.post(`/payroll/periods/${period.id}/pay`, {});
                    if (res?.success) {
                        this._toast(`💳 پرداخت ثبت شد — رویداد #${res.event_id}`, "#7c3aed");
                        const pRes = await this.api.get(`/payroll/periods/${period.id}`);
                        period = pRes?.data ?? period;
                        this._selectedPeriod = period;
                        this._updateKPIs(period);
                        this._rebuildActions(period);
                        await this._loadSlips(period.id);
                    } else { alert("خطا: " + (res?.message ?? "")); payBtn.disabled = false; }
                } catch (err) { alert("خطا: " + (err?.message ?? "")); payBtn.disabled = false; }
            });
            bar.appendChild(payBtn);
            // show event link badges
            if (period.recognition_event_id) {
                const b = document.createElement("span");
                b.className = "acc-link-badge"; b.style.fontSize = "12px";
                b.textContent = `🔗 رویداد شناخت #${period.recognition_event_id}`;
                bar.appendChild(b);
            }
        }
        if (period.status === "paid") {
            const done = document.createElement("span");
            done.style.cssText = "display:inline-flex;align-items:center;gap:6px;background:#f3e8ff;color:#6d28d9;border-radius:8px;padding:8px 14px;font-size:13px;font-weight:600;";
            done.textContent = `✅ حقوق پرداخت شده — رویداد #${period.payment_event_id}`;
            bar.appendChild(done);
        }
    }

    _updateKPIs(period) {
        this._setRef("kpiSlips", period.slip_count ?? 0);
        this._setRef("kpiGross", this._fmt(period.total_gross));
        this._setRef("kpiDed",   this._fmt(period.total_deductions));
        this._setRef("kpiNet",   this._fmt(period.total_net));
    }

    async _loadSlips(periodId) {
        const wrap = this.ref("slipsWrap");
        if (!wrap) return;
        wrap.innerHTML = `<div class="acc-loading"><div class="acc-spinner"></div></div>`;
        try {
            const res = await this.api.get(`/payroll/periods/${periodId}/slips`);
            this._slips = res?.data ?? [];
            this._renderSlips(wrap);
        } catch {
            wrap.innerHTML = `<div class="acc-error">خطا در بارگذاری فیش‌ها</div>`;
        }
    }

    _renderSlips(wrap) {
        if (!this._slips.length) {
            wrap.innerHTML = `<div class="acc-empty">هنوز فیشی تولید نشده است. از دکمه «تولید فیش‌ها» استفاده کنید.</div>`;
            return;
        }
        const TH = t => `<th style="padding:9px 12px;text-align:right;font-size:12px;font-weight:700;color:#374151;border-bottom:2px solid #e2e8f0;">${t}</th>`;
        wrap.innerHTML = `
            <div style="overflow-x:auto;">
            <table style="width:100%;border-collapse:collapse;font-size:13px;min-width:560px;">
                <thead><tr style="background:#f8fafc;">
                    ${TH("#")}
                    ${TH("پرسنل")}
                    ${TH("واحد / سمت")}
                    ${TH("ناخالص ﷼")}
                    ${TH("کسورات ﷼")}
                    ${TH("خالص ﷼")}
                    ${TH("عملیات")}
                </tr></thead>
                <tbody id="slips-tbody"></tbody>
            </table>
            </div>`;

        const tbody = wrap.querySelector("#slips-tbody");
        this._slips.forEach((s, idx) => {
            const tr = document.createElement("tr");
            tr.style.cursor = "pointer";
            tr.innerHTML = `
                <td style="padding:9px 12px;color:#94a3b8;font-size:11px;">${idx + 1}</td>
                <td style="padding:9px 12px;font-weight:700;color:#1e293b;">${this.escape(s.emp_name)}</td>
                <td style="padding:9px 12px;font-size:11px;color:#64748b;">${this.escape(s.position || "")}${s.department ? ` / ${this.escape(s.department)}` : ""}</td>
                <td style="padding:9px 12px;text-align:left;font-family:monospace;color:#059669;">${this._fmt(s.gross_salary)}</td>
                <td style="padding:9px 12px;text-align:left;font-family:monospace;color:#dc2626;">${this._fmt(s.total_deductions)}</td>
                <td style="padding:9px 12px;text-align:left;font-family:monospace;font-weight:800;color:#1e293b;font-size:14px;">${this._fmt(s.net_salary)}</td>
                <td style="padding:9px 8px;text-align:center;">
                    <button class="acc-btn acc-btn--secondary acc-btn--sm" data-action="view">ریز فیش</button>
                </td>
            `;
            tr.addEventListener("click", () => this._openSlipDetail(s.id));
            tr.querySelector("[data-action='view']").addEventListener("click", e => { e.stopPropagation(); this._openSlipDetail(s.id); });
            tbody.appendChild(tr);
        });
    }

    /* ── Slip detail modal ──────────────────────────────────────── */

    async _openSlipDetail(slipId) {
        let slip = null;
        try {
            const res = await this.api.get(`/payroll/slips/${slipId}`);
            slip = res?.data;
        } catch { alert("خطا در بارگذاری فیش"); return; }

        const earns = (slip.items ?? []).filter(i => i.type === "earning");
        const deds  = (slip.items ?? []).filter(i => i.type === "deduction");

        const buildItems = (items, color) => items.map(it => `
            <tr>
                <td style="padding:7px 14px;color:#475569;">${this.escape(it.component_name)}</td>
                <td style="padding:7px 14px;text-align:left;font-family:monospace;font-weight:600;color:${color};">
                    ${this._fmt(it.amount)} ﷼
                </td>
            </tr>`
        ).join("");

        const ov = document.createElement("div"); ov.className = "acc-modal-overlay";
        ov.innerHTML = `
            <div class="acc-modal" style="max-width:480px;">
                <button class="acc-modal__close">✕</button>
                <div class="acc-modal__title" style="border-bottom:2px solid #e2e8f0;padding-bottom:12px;margin-bottom:16px;">
                    فیش حقوقی — ${this.escape(slip.emp_name)}
                    <div style="font-size:12px;color:#64748b;font-weight:400;margin-top:4px;">دوره: ${this.escape(slip.period_name ?? "")}</div>
                </div>

                <table style="width:100%;border-collapse:collapse;font-size:13px;margin-bottom:8px;">
                    <tr style="background:#f0fdf4;">
                        <td colspan="2" style="padding:8px 14px;font-weight:700;color:#059669;font-size:12px;">✅ درآمدها</td>
                    </tr>
                    ${buildItems(earns, "#059669")}
                    <tr style="background:#f8fafc;">
                        <td style="padding:8px 14px;font-weight:600;color:#374151;">جمع درآمد ناخالص</td>
                        <td style="padding:8px 14px;text-align:left;font-family:monospace;font-weight:800;color:#059669;">${this._fmt(slip.gross_salary)} ﷼</td>
                    </tr>
                </table>

                <table style="width:100%;border-collapse:collapse;font-size:13px;margin-bottom:8px;">
                    <tr style="background:#fef2f2;">
                        <td colspan="2" style="padding:8px 14px;font-weight:700;color:#dc2626;font-size:12px;">🔻 کسورات</td>
                    </tr>
                    ${buildItems(deds, "#dc2626")}
                    <tr style="background:#f8fafc;">
                        <td style="padding:8px 14px;font-weight:600;color:#374151;">جمع کسورات</td>
                        <td style="padding:8px 14px;text-align:left;font-family:monospace;font-weight:800;color:#dc2626;">${this._fmt(slip.total_deductions)} ﷼</td>
                    </tr>
                </table>

                <table style="width:100%;border-collapse:collapse;font-size:14px;">
                    <tr style="background:#eff6ff;border-top:2px solid #2563eb;">
                        <td style="padding:14px;font-weight:800;color:#1e293b;font-size:15px;">💵 خالص پرداختی</td>
                        <td style="padding:14px;text-align:left;font-family:monospace;font-weight:900;color:#2563eb;font-size:18px;">${this._fmt(slip.net_salary)} ﷼</td>
                    </tr>
                </table>

                <div style="text-align:center;margin-top:16px;">
                    <button class="acc-btn acc-btn--secondary" data-action="close">بستن</button>
                </div>
            </div>`;
        document.body.appendChild(ov);
        const close = () => ov.remove();
        ov.querySelector(".acc-modal__close").addEventListener("click", close);
        ov.querySelector("[data-action='close']").addEventListener("click", close);
        ov.addEventListener("click", ev => { if (ev.target === ov) close(); });
    }

    /* ── Helpers ─────────────────────────────────────────────────── */

    _setRef(name, val) { const el = this.ref(name); if (el) el.textContent = val; }

    _fmt(v) { return new Intl.NumberFormat("fa-IR").format(Math.round(Number(v ?? 0))); }

    _toast(msg, bg = "#059669") {
        const t = document.createElement("div");
        t.style.cssText = `position:fixed;bottom:24px;right:24px;background:${bg};color:#fff;padding:13px 20px;border-radius:10px;font-size:13px;font-weight:600;z-index:9999;box-shadow:0 4px 20px rgba(0,0,0,.15);max-width:400px;`;
        t.textContent = msg;
        document.body.appendChild(t);
        setTimeout(() => t.remove(), 4500);
    }
}
