/**
 * ServiceAccountingSection — صف صدور سند حسابدار + تنظیم سهم‌ها + بهای تمام‌شده
 */
import SectionBase from '../../accounting/SectionBase.js';

const FIELDS = [
    { key: 'tech_service_pct', label: 'سهم کارشناس از خدمات (%)', group: 'کارشناس' },
    { key: 'tech_parts_pct', label: 'سهم کارشناس از قطعات (%)', group: 'کارشناس' },
    { key: 'senior_service_pct', label: 'سهم کارشناس ارشد از خدمات (%)', group: 'کارشناس ارشد' },
    { key: 'senior_team_override_pct', label: 'پاداش ارشد از کل فاکتور (%)', group: 'کارشناس ارشد' },
    { key: 'parts_cogs_pct', label: 'بهای تمام‌شده قطعات (%)', group: 'بهای تمام‌شده' },
    { key: 'supplier_margin_pct', label: 'حاشیه تأمین‌کننده (%)', group: 'تأمین‌کننده' },
    { key: 'discount_company_pct', label: 'سهم شرکت از تخفیف (%)', group: 'تخفیف/پاداش' },
    { key: 'reward_expense_per_point', label: 'هزینه هر امتیاز پاداش (ریال)', group: 'تخفیف/پاداش', step: 1 },
    { key: 'overhead_energy_pct', label: 'سربار انرژی (%)', group: 'سربار' },
    { key: 'overhead_repair_pct', label: 'سربار تعمیرگاه (%)', group: 'سربار' },
];

export default class ServiceAccountingSection extends SectionBase {
    async template() {
        return `
        <div class="acc-section-wrap svc-acc-wrap">
            <div class="acc-toolbar">
                <h2 class="acc-section-title">💰 صدور سند خدمات (حسابدار)</h2>
                <div style="display:flex;gap:8px;flex-wrap:wrap;">
                    <button class="acc-btn acc-btn--secondary" data-ref="tabQueue" data-tab="queue">📋 صف صدور</button>
                    <button class="acc-btn acc-btn--secondary" data-ref="tabPortal" data-tab="portal">🏢 هویت شعبه</button>
                    <button class="acc-btn acc-btn--secondary" data-ref="tabConfig" data-tab="config">⚙️ تنظیم سهم‌ها</button>
                    <button class="acc-btn acc-btn--secondary" data-ref="tabCost" data-tab="cost">📊 بهای تمام‌شده</button>
                    <button class="acc-btn acc-btn--secondary" data-ref="tabGraph" data-tab="graph">🕸 گراف فعالیت</button>
                    <button class="acc-btn acc-btn--secondary" data-ref="tabPreview" data-tab="preview">🔍 پیش‌نمایش</button>
                </div>
            </div>
            <div data-ref="officeBanner" class="svc-acc-office-banner"></div>
            <div data-ref="panel"></div>
        </div>`;
    }

    async afterRender() {
        this._tab = 'queue';
        this._serviceTypes = {};
        this._config = {};
        this._portal = {};
        this._canPost = false;
        this._canConfig = false;
        await this._loadMeta();
        this._renderOfficeBanner();
        this._bindTabs();
        await this._renderTab();
    }

    _renderOfficeBanner() {
        const el = this.ref('officeBanner');
        if (!el || !this._portal?.office_name) return;
        el.innerHTML = `
        <div class="svc-acc-office">
            <span class="svc-acc-office__tag">${this.escape(this._portal.ledger_tag || 'SERVICE')}</span>
            <strong>${this.escape(this._portal.subsystem_label || 'پورتال خدمات')}</strong>
            <span>— شعبه: <b>${this.escape(this._portal.office_name)}</b> (${this.escape(this._portal.office_code)})</span>
            <small>همه اسناد با برچسب [${this.escape(this._portal.ledger_tag)}|${this.escape(this._portal.office_name)}] در ERP ثبت می‌شوند</small>
        </div>`;
    }

    _bindTabs() {
        this.root.querySelectorAll('[data-tab]').forEach(btn => {
            btn.addEventListener('click', async () => {
                this._tab = btn.dataset.tab;
                this.root.querySelectorAll('[data-tab]').forEach(b =>
                    b.classList.toggle('acc-btn--primary', b.dataset.tab === this._tab));
                await this._renderTab();
            });
        });
        this.root.querySelector('[data-tab="queue"]')?.classList.add('acc-btn--primary');
    }

    async _loadMeta() {
        try {
            const res = await this.api.get('service/accounting/config');
            const d = res?.data ?? res ?? {};
            this._config = d.config ?? {};
            this._serviceTypes = d.service_types ?? {};
            this._defaults = d.defaults ?? {};
            this._portal = d.portal ?? {};
            this._canPost = !!d.can_post;
            this._canConfig = !!d.can_config;
        } catch {
            this._config = {};
            this._serviceTypes = {};
            this._portal = {};
        }
    }

    async _renderTab() {
        const panel = this.ref('panel');
        if (!panel) return;
        if (this._tab === 'queue') await this._renderQueue(panel);
        else if (this._tab === 'portal') await this._renderPortal(panel);
        else if (this._tab === 'config') await this._renderConfig(panel);
        else if (this._tab === 'cost') await this._renderCost(panel);
        else if (this._tab === 'graph') await this._renderGraph(panel);
        else await this._renderPreview(panel);
    }

    async _renderQueue(panel) {
        panel.innerHTML = '<div class="acc-loading">⏳</div>';
        try {
            const res = await this.api.get('service/accounting/pending');
            const d = res?.data ?? {};
            const invoices = d.invoices ?? [];
            const other = d.other ?? [];
            const counts = d.counts ?? {};

            panel.innerHTML = `
            <div class="svc-acc-queue">
                <div class="svc-acc-queue-stats">
                    <span>📋 ${counts.total ?? 0} مورد در صف</span>
                    <span>فاکتور: ${counts.invoices ?? 0}</span>
                    <span>سایر: ${counts.other ?? 0}</span>
                </div>
                <h4>فاکتورهای خدمات (SERVICE_INVOICE)</h4>
                <table class="acc-table">
                    <thead><tr>
                        <th>SRD</th><th>مشتری</th><th>مبلغ</th><th>رویداد</th><th>وضعیت</th><th></th>
                    </tr></thead>
                    <tbody>${invoices.length ? invoices.map(r => `
                        <tr>
                            <td><b>${this.escape(r.report_no || r.id)}</b></td>
                            <td>${this.escape(r.customer_name || '—')}</td>
                            <td>${Number(r.total || 0).toLocaleString('fa-IR')}</td>
                            <td>${r.event_id ? `#${r.event_id}` : '—'}</td>
                            <td>${this._stateBadge(r.workflow_state)}</td>
                            <td>
                                <button class="acc-btn acc-btn--sm" data-preview-report="${r.id}">👁</button>
                                ${this._canPost ? `<button class="acc-btn acc-btn--sm acc-btn--success" data-post-report="${r.id}">✅ صدور سند</button>` : ''}
                            </td>
                        </tr>`).join('') : '<tr><td colspan="6">صف خالی — SRD نهایی‌شده‌ای بدون سند نیست</td></tr>'}
                    </tbody>
                </table>
                ${other.length ? `
                <h4 style="margin-top:20px;">دریافت / تأمین‌کننده</h4>
                <table class="acc-table">
                    <thead><tr><th>نوع</th><th>رویداد</th><th>مبلغ</th><th>وضعیت</th><th></th></tr></thead>
                    <tbody>${other.map(j => `
                        <tr>
                            <td>${this.escape(j.event_type)}</td>
                            <td>#${j.acc_event_id}</td>
                            <td>${Number(j.amount || 0).toLocaleString('fa-IR')}</td>
                            <td>${this._stateBadge(j.workflow_state)}</td>
                            <td>${this._canPost ? `<button class="acc-btn acc-btn--sm acc-btn--success" data-post-event="${j.acc_event_id}">✅ صدور</button>` : ''}</td>
                        </tr>`).join('')}
                    </tbody>
                </table>` : ''}
                <div data-ref="queuePreview" style="margin-top:16px;"></div>
            </div>`;

            panel.querySelectorAll('[data-post-report]').forEach(btn => {
                btn.addEventListener('click', () => this._postReport(+btn.dataset.postReport, btn));
            });
            panel.querySelectorAll('[data-post-event]').forEach(btn => {
                btn.addEventListener('click', () => this._postEvent(+btn.dataset.postEvent, btn));
            });
            panel.querySelectorAll('[data-preview-report]').forEach(btn => {
                btn.addEventListener('click', () => this._previewInQueue(+btn.dataset.previewReport));
            });
        } catch (e) {
            panel.innerHTML = `<div class="acc-error">❌ ${this.escape(e.message)}</div>`;
        }
    }

    _stateBadge(state) {
        if (state === 'posted') return '<span style="color:#059669;">✅ صادر شده</span>';
        if (state === 'failed') return '<span style="color:#dc2626;">❌ خطا</span>';
        if (state === 'pending' || !state) return '<span style="color:#f59e0b;">⏳ در انتظار صدور</span>';
        return this.escape(state || '—');
    }

    async _postReport(id, btn) {
        if (!confirm('صدور سند حسابداری ERP برای این فاکتور خدمات؟')) return;
        btn.disabled = true;
        btn.textContent = '...';
        try {
            const res = await this.api.post(`service/accounting/post/${id}`);
            alert(res?.message || (res?.success ? 'سند صادر شد' : 'خطا'));
            await this._renderQueue(this.ref('panel'));
        } catch (e) {
            alert('خطا: ' + e.message);
            btn.disabled = false;
            btn.textContent = '✅ صدور سند';
        }
    }

    async _postEvent(id, btn) {
        if (!confirm(`صدور سند ERP برای رویداد #${id}؟`)) return;
        btn.disabled = true;
        try {
            const res = await this.api.post(`service/accounting/post-event/${id}`);
            alert(res?.message || (res?.success ? 'سند صادر شد' : 'خطا'));
            await this._renderQueue(this.ref('panel'));
        } catch (e) {
            alert('خطا: ' + e.message);
            btn.disabled = false;
        }
    }

    async _previewInQueue(id) {
        const out = this.ref('queuePreview');
        if (!out) return;
        out.innerHTML = '<div class="acc-loading">⏳</div>';
        try {
            const res = await this.api.get(`service/accounting/preview/${id}`);
            out.innerHTML = this._splitsHtml(res?.data ?? {});
        } catch (e) {
            out.innerHTML = `<div class="acc-error">${this.escape(e.message)}</div>`;
        }
    }

    async _renderPortal(panel) {
        const p = this._portal;
        panel.innerHTML = `
        <div class="svc-acc-portal">
            <p class="svc-acc-hint">برای تفکیک چند دفتر/شعبه خدماتی، هویت این پورتال را مشخص کنید. در اسناد ERP و ابعاد <strong>BRANCH</strong> ثبت می‌شود.</p>
            <form data-ref="portalForm" class="svc-acc-grid" style="max-width:520px;">
                <label class="acc-form-group"><span>کد شعبه</span>
                    <input name="office_code" value="${this.escape(p.office_code || '')}" ${this._canConfig ? '' : 'readonly'}></label>
                <label class="acc-form-group"><span>نام شعبه / دفتر خدمات</span>
                    <input name="office_name" value="${this.escape(p.office_name || '')}" ${this._canConfig ? '' : 'readonly'}></label>
                <label class="acc-form-group"><span>عنوان سیستم</span>
                    <input name="subsystem_label" value="${this.escape(p.subsystem_label || '')}" ${this._canConfig ? '' : 'readonly'}></label>
                <label class="acc-form-group"><span>برچسب دفتر (ledger)</span>
                    <input name="ledger_tag" value="${this.escape(p.ledger_tag || 'SERVICE')}" ${this._canConfig ? '' : 'readonly'}></label>
                ${this._canConfig ? '<button type="submit" class="acc-btn acc-btn--primary">💾 ذخیره هویت شعبه</button>' : '<p style="color:#94a3b8;">فقط مدیر می‌تواند ویرایش کند</p>'}
            </form>
        </div>`;
        if (this._canConfig) {
            panel.querySelector('[data-ref="portalForm"]')?.addEventListener('submit', async (e) => {
                e.preventDefault();
                const body = Object.fromEntries(new FormData(e.target).entries());
                await this.api.put('service/accounting/portal', body);
                this._portal = body;
                this._renderOfficeBanner();
                this._toast('✅ هویت شعبه ذخیره شد');
            });
        }
    }

    async _renderConfig(panel) {
        if (!this._canConfig) {
            panel.innerHTML = '<div class="acc-empty">تنظیم درصد سهم‌ها فقط برای مدیر سیستم است.</div>';
            return;
        }
        const stOpts = `<option value="_default">پیش‌فرض (همه خدمات)</option>` +
            Object.entries(this._serviceTypes).map(([k, v]) =>
                `<option value="${this.escape(k)}">${this.escape(v)}</option>`).join('');

        const groups = [...new Set(FIELDS.map(f => f.group))];
        const fieldsHtml = groups.map(g => `
            <div class="svc-acc-group">
                <h4>${this.escape(g)}</h4>
                <div class="svc-acc-grid">
                    ${FIELDS.filter(f => f.group === g).map(f => `
                        <label class="acc-form-group">
                            <span>${this.escape(f.label)}</span>
                            <input type="number" name="${f.key}" step="${f.step || 0.1}" min="0"
                                   value="${this._config[f.key] ?? this._defaults?.[f.key] ?? 0}">
                        </label>`).join('')}
                </div>
            </div>`).join('');

        panel.innerHTML = `
        <div class="svc-acc-config">
            <div class="acc-form-row" style="margin-bottom:16px;">
                <label class="acc-form-group">
                    <span>نوع خدمت</span>
                    <select data-ref="serviceTypeSel">${stOpts}</select>
                </label>
                <label class="acc-form-group svc-acc-check">
                    <input type="checkbox" name="auto_post" ${this._config.auto_post ? 'checked' : ''}>
                    صدور خودکار (پیشنهاد: خاموش — حسابدار صادر کند)
                </label>
                <label class="acc-form-group svc-acc-check">
                    <input type="checkbox" name="use_dimensions" ${this._config.use_dimensions !== false ? 'checked' : ''}>
                    ابعاد: مشتری / کارشناس / شعبه / نوع خدمت
                </label>
            </div>
            <form data-ref="configForm">${fieldsHtml}
                <div style="margin-top:16px;display:flex;gap:8px;">
                    <button type="submit" class="acc-btn acc-btn--primary">💾 ذخیره</button>
                </div>
            </form>
        </div>`;

        const sel = panel.querySelector('[data-ref="serviceTypeSel"]');
        sel?.addEventListener('change', async () => {
            const type = sel.value === '_default' ? '' : sel.value;
            const q = type ? `?service_type=${encodeURIComponent(type)}` : '';
            const res = await this.api.get(`service/accounting/config${q}`);
            this._config = res?.data?.config ?? {};
            await this._renderConfig(panel);
        });

        panel.querySelector('[data-ref="configForm"]')?.addEventListener('submit', async (e) => {
            e.preventDefault();
            const fd = new FormData(e.target);
            const body = Object.fromEntries(fd.entries());
            body.auto_post = !!panel.querySelector('[name="auto_post"]')?.checked;
            body.use_dimensions = !!panel.querySelector('[name="use_dimensions"]')?.checked;
            FIELDS.forEach(f => { body[f.key] = parseFloat(body[f.key]) || 0; });
            await this.api.put('service/accounting/config', { service_type: sel?.value || '_default', config: body });
            this._toast('✅ ذخیره شد');
        });
    }

    async _renderCost(panel) {
        panel.innerHTML = '<div class="acc-loading">⏳</div>';
        try {
            const res = await this.api.get('service/accounting/cost-report');
            const d = res?.data ?? {};
            const t = d.totals ?? {};
            const by = d.by_entity ?? [];
            panel.innerHTML = `
            <div class="svc-acc-cost">
                <div class="svc-acc-kpis">
                    ${this._kpi('درآمد', t.revenue, '#1d4ed8')}
                    ${this._kpi('حق‌الزحمه کارشناس', t.tech_fee, '#00A1E4')}
                    ${this._kpi('سهم ارشد', t.senior_fee, '#0077B6')}
                    ${this._kpi('COGS', t.parts_cogs, '#dc2626')}
                    ${this._kpi('سربار', t.overhead, '#64748b')}
                    ${this._kpi('حاشیه', t.margin, '#059669')}
                </div>
                <h4 style="margin:20px 0 10px;">سهم موجودیت‌ها (نفر / شرکت / مشتری)</h4>
                <div class="svc-table-wrap">
                    <table class="acc-table">
                        <thead><tr><th>نوع</th><th>نام</th><th>سهم درآمد</th><th>بهای تمام‌شده</th><th>کارمزد/حاشیه</th></tr></thead>
                        <tbody>
                            ${by.length ? by.map(r => `<tr>
                                <td>${this.escape(r.entity_type)}</td>
                                <td>${this.escape(r.entity_label || '—')}</td>
                                <td>${Number(r.revenue || 0).toLocaleString('fa-IR')}</td>
                                <td>${Number(r.cost || 0).toLocaleString('fa-IR')}</td>
                                <td>${Number(r.margin || 0).toLocaleString('fa-IR')}</td>
                            </tr>`).join('') : '<tr><td colspan="5">داده‌ای نیست</td></tr>'}
                        </tbody>
                    </table>
                </div>
                <p class="svc-acc-hint">برای گراف فعالیت و سهم هر نفر از هر سفارش، تب «گراف فعالیت» را باز کنید.</p>
            </div>`;
        } catch (e) {
            panel.innerHTML = `<div class="acc-error">❌ ${this.escape(e.message)}</div>`;
        }
    }

    async _renderGraph(panel) {
        panel.innerHTML = '<div class="acc-loading">⏳ در حال ساخت گراف بهای فعالیت…</div>';
        try {
            const [gRes, aRes] = await Promise.all([
                this.api.get('service/accounting/cost-graph'),
                this.api.get('service/accounting/activities?all=1'),
            ]);
            const g = gRes?.data ?? {};
            const acts = aRes?.data ?? [];
            this._roles = gRes?.data?.role_labels || aRes?.roles || {};
            const nodes = g.nodes || [];
            const edges = g.edges || [];
            const persons = g.person_shares || [];
            const orders = g.orders || [];

            panel.innerHTML = `
            <div class="svc-abc">
                <div class="svc-abc__intro">
                    <h3>حسابداری صنعتی — بهای تمام‌شده فعالیت‌ها (ABC) + گراف تخصیص</h3>
                    <p>هر سفارش به فعالیت‌های میدانی شکسته می‌شود؛ سپس سهم هر نفر از هر فعالیت مشخص می‌گردد.</p>
                </div>
                <div class="svc-abc__toolbar">
                    <label>شناسه SRD
                        <input type="number" min="1" data-ref="abcReportId" placeholder="مثلاً ۱۲">
                    </label>
                    <button class="acc-btn acc-btn--primary" data-ref="abcLoadOne">نمایش گراف سفارش</button>
                    <button class="acc-btn" data-ref="abcReload">بازه جاری</button>
                    <button class="acc-btn" data-ref="abcAlloc">محاسبه و ذخیره تخصیص</button>
                </div>
                <div class="svc-abc__layout">
                    <div class="svc-abc__graph-wrap">
                        <svg data-ref="abcSvg" class="svc-abc__svg" viewBox="0 0 900 520" role="img" aria-label="گراف بهای فعالیت"></svg>
                        <div class="svc-abc__legend">
                            <span><i class="c-order"></i> سفارش</span>
                            <span><i class="c-act"></i> فعالیت</span>
                            <span><i class="c-person"></i> نفر</span>
                        </div>
                    </div>
                    <div class="svc-abc__side">
                        <h4>سهم نفرها</h4>
                        <div class="svc-table-wrap">
                            <table class="acc-table">
                                <thead><tr><th>نفر</th><th>مبلغ</th><th>سفارش‌ها</th></tr></thead>
                                <tbody data-ref="abcPersons">
                                    ${persons.length ? persons.map(p => `<tr>
                                        <td>${this.escape(p.name)}</td>
                                        <td>${Number(p.amount || 0).toLocaleString('fa-IR')}</td>
                                        <td>${Number(p.orders || 0).toLocaleString('fa-IR')}</td>
                                    </tr>`).join('') : '<tr><td colspan="3">هنوز تخصیصی نیست — یک SRD را محاسبه کنید</td></tr>'}
                                </tbody>
                            </table>
                        </div>
                        <h4 style="margin-top:16px;">سفارش‌ها</h4>
                        <div class="svc-table-wrap">
                            <table class="acc-table">
                                <thead><tr><th>کد</th><th>مشتری</th><th>درآمد</th><th>بهای فعالیت</th><th>نفر</th></tr></thead>
                                <tbody>
                                    ${orders.length ? orders.map(o => `<tr data-rid="${o.report_id}" class="svc-abc__order-row">
                                        <td><button type="button" class="acc-btn acc-btn--secondary" data-open-rid="${o.report_id}">${this.escape(o.tracking || o.report_id)}</button></td>
                                        <td>${this.escape(o.customer || '—')}</td>
                                        <td>${Number(o.revenue || 0).toLocaleString('fa-IR')}</td>
                                        <td>${Number(o.cost || 0).toLocaleString('fa-IR')}</td>
                                        <td>${Number(o.persons || 0).toLocaleString('fa-IR')}</td>
                                    </tr>`).join('') : '<tr><td colspan="5">سفارش نهایی در بازه نیست</td></tr>'}
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
                <div data-ref="abcDetail" class="svc-abc__detail"></div>
                <details class="svc-abc__acts">
                    <summary>کاتالوگ فعالیت‌ها (${acts.length})</summary>
                    <div class="svc-table-wrap">
                        <table class="acc-table">
                            <thead><tr><th>کد</th><th>نام</th><th>استخر</th><th>وزن</th><th>محرک</th><th>نقش‌ها</th></tr></thead>
                            <tbody>
                                ${acts.map(a => `<tr>
                                    <td><code>${this.escape(a.code)}</code></td>
                                    <td>${this.escape(a.name)}</td>
                                    <td>${this.escape(a.pool)}</td>
                                    <td>${a.weight}</td>
                                    <td>${this.escape(a.driver)}</td>
                                    <td>${this.escape((a.roles || []).join('، '))}</td>
                                </tr>`).join('')}
                            </tbody>
                        </table>
                    </div>
                </details>
                <div class="svc-abc__crew">
                    <h4>خدمه سفارش (چندنفره)</h4>
                    <div class="acc-form-row">
                        <label>شناسه درخواست (request_id)
                            <input type="number" min="1" data-ref="crewReqId">
                        </label>
                        <button class="acc-btn" data-ref="crewLoad">بارگذاری خدمه</button>
                    </div>
                    <div data-ref="crewBox"></div>
                </div>
            </div>`;

            this._paintAbcGraph(panel.querySelector('[data-ref="abcSvg"]'), nodes, edges);

            panel.querySelector('[data-ref="abcReload"]')?.addEventListener('click', () => this._renderGraph(panel));
            panel.querySelector('[data-ref="abcLoadOne"]')?.addEventListener('click', async () => {
                const id = panel.querySelector('[data-ref="abcReportId"]')?.value;
                if (!id) return;
                await this._loadGraphReport(panel, id);
            });
            panel.querySelector('[data-ref="abcAlloc"]')?.addEventListener('click', async () => {
                const id = panel.querySelector('[data-ref="abcReportId"]')?.value;
                if (!id) { this._toast('شناسه SRD را وارد کنید'); return; }
                await this.api.post(`service/accounting/allocate/${id}`, {});
                this._toast('✅ تخصیص ذخیره شد');
                await this._loadGraphReport(panel, id);
            });
            panel.querySelectorAll('[data-open-rid]').forEach(btn => {
                btn.addEventListener('click', async () => {
                    const id = btn.getAttribute('data-open-rid');
                    panel.querySelector('[data-ref="abcReportId"]').value = id;
                    await this._loadGraphReport(panel, id);
                });
            });
            panel.querySelector('[data-ref="crewLoad"]')?.addEventListener('click', () => this._loadCrewEditor(panel));
        } catch (e) {
            panel.innerHTML = `<div class="acc-error">❌ ${this.escape(e.message)}</div>`;
        }
    }

    async _loadGraphReport(panel, reportId) {
        const detail = panel.querySelector('[data-ref="abcDetail"]');
        if (detail) detail.innerHTML = '<div class="acc-loading">⏳</div>';
        try {
            const [gRes, cRes] = await Promise.all([
                this.api.get(`service/accounting/cost-graph?report_id=${reportId}`),
                this.api.get(`service/accounting/activity-cost/${reportId}`),
            ]);
            const g = gRes?.data ?? {};
            this._paintAbcGraph(panel.querySelector('[data-ref="abcSvg"]'), g.nodes || [], g.edges || []);
            const persons = panel.querySelector('[data-ref="abcPersons"]');
            if (persons) {
                const list = g.person_shares || [];
                persons.innerHTML = list.length ? list.map(p => `<tr>
                    <td>${this.escape(p.name)}</td>
                    <td>${Number(p.amount || 0).toLocaleString('fa-IR')}</td>
                    <td>${Number(p.orders || 1).toLocaleString('fa-IR')}</td>
                </tr>`).join('') : '<tr><td colspan="3">—</td></tr>';
            }
            const alloc = cRes?.data ?? {};
            const lines = alloc.lines || [];
            const shares = alloc.person_shares || [];
            if (detail) {
                detail.innerHTML = `
                <h4>جزئیات تخصیص سفارش #${this.escape(String(reportId))}</h4>
                <div class="svc-abc__pools">
                    ${Object.entries(alloc.pools || {}).map(([k, v]) =>
                        `<div class="svc-acc-kpi"><span>${this.escape(k)}</span><b>${Number(v).toLocaleString('fa-IR')}</b></div>`
                    ).join('')}
                </div>
                <div class="svc-table-wrap" style="margin-top:12px;">
                    <table class="acc-table">
                        <thead><tr><th>فعالیت</th><th>نفر</th><th>نقش</th><th>محرک</th><th>سهم٪</th><th>مبلغ</th></tr></thead>
                        <tbody>
                            ${lines.map(l => `<tr>
                                <td>${this.escape(l.activity_name)}</td>
                                <td>${this.escape(l.person_label)}</td>
                                <td>${this.escape(l.role_code)}</td>
                                <td>${Number(l.driver_qty || 0).toLocaleString('fa-IR')}</td>
                                <td>${Number(l.share_pct || 0).toLocaleString('fa-IR')}</td>
                                <td><strong>${Number(l.amount || 0).toLocaleString('fa-IR')}</strong></td>
                            </tr>`).join('')}
                        </tbody>
                    </table>
                </div>
                <h4 style="margin-top:14px;">جمع سهم هر نفر از این سفارش</h4>
                <div class="svc-table-wrap">
                    <table class="acc-table">
                        <thead><tr><th>نفر</th><th>نقش</th><th>بهای فعالیت</th><th>سهم درآمد خدمات</th></tr></thead>
                        <tbody>
                            ${shares.map(p => `<tr>
                                <td>${this.escape(p.name)}</td>
                                <td>${this.escape(p.role || '')}</td>
                                <td>${Number(p.amount || 0).toLocaleString('fa-IR')}</td>
                                <td>${Number(p.revenue_share || 0).toLocaleString('fa-IR')}</td>
                            </tr>`).join('') || '<tr><td colspan="4">—</td></tr>'}
                        </tbody>
                    </table>
                </div>`;
            }
            if (alloc.request_id) {
                const reqInp = panel.querySelector('[data-ref="crewReqId"]');
                if (reqInp) reqInp.value = alloc.request_id;
            }
        } catch (e) {
            if (detail) detail.innerHTML = `<div class="acc-error">${this.escape(e.message)}</div>`;
        }
    }

    async _loadCrewEditor(panel) {
        const box = panel.querySelector('[data-ref="crewBox"]');
        const reqId = panel.querySelector('[data-ref="crewReqId"]')?.value;
        if (!box || !reqId) return;
        box.innerHTML = '<div class="acc-loading">⏳</div>';
        try {
            const res = await this.api.get(`service/accounting/crew/${reqId}`);
            const crew = res?.data ?? [];
            const roles = res?.roles || this._roles || {};
            this._roleMap = roles;
            box.innerHTML = `
            <p class="svc-acc-hint">وزن و ساعت هر نفر مبنای تخصیص فعالیت‌هاست. پس از ذخیره، «محاسبه و ذخیره تخصیص» را بزنید.</p>
            <div data-ref="crewRows">
                ${crew.map((m, i) => this._crewRowHtml(m, i)).join('') || this._crewRowHtml({}, 0)}
            </div>
            <div style="display:flex;gap:8px;margin-top:10px;">
                <button type="button" class="acc-btn" data-ref="crewAdd">+ نفر</button>
                <button type="button" class="acc-btn acc-btn--primary" data-ref="crewSave">💾 ذخیره خدمه</button>
            </div>`;
            box.querySelector('[data-ref="crewAdd"]')?.addEventListener('click', () => {
                const wrap = box.querySelector('[data-ref="crewRows"]');
                const i = wrap.children.length;
                wrap.insertAdjacentHTML('beforeend', this._crewRowHtml({}, i));
            });
            box.querySelector('[data-ref="crewSave"]')?.addEventListener('click', async () => {
                const members = [...box.querySelectorAll('[data-crew-row]')].map(row => ({
                    user_id: +row.querySelector('[name=user_id]')?.value || 0,
                    role: row.querySelector('[name=role]')?.value || 'lead',
                    weight: parseFloat(row.querySelector('[name=weight]')?.value) || 1,
                    hours: parseFloat(row.querySelector('[name=hours]')?.value) || 0,
                    note: row.querySelector('[name=note]')?.value || '',
                })).filter(m => m.user_id > 0);
                await this.api.put(`service/accounting/crew/${reqId}`, { crew: members });
                this._toast('✅ خدمه ذخیره شد');
            });
        } catch (e) {
            box.innerHTML = `<div class="acc-error">${this.escape(e.message)}</div>`;
        }
    }

    _crewRowHtml(m = {}, i = 0) {
        const role = m.role || 'lead';
        const roles = this._roleMap || { lead: 'کارشناس مسئول', assistant: 'کمک‌کارشناس', senior: 'کارشناس ارشد', helper: 'کمک میدانی' };
        const opts = Object.entries(roles).filter(([k]) => k !== 'company')
            .map(([k, v]) => `<option value="${k}" ${k === role ? 'selected' : ''}>${this.escape(v)}</option>`).join('');
        return `<div class="svc-abc__crew-row" data-crew-row="${i}">
            <input name="user_id" type="number" min="1" placeholder="user_id" value="${m.user_id || ''}">
            <select name="role">${opts}</select>
            <input name="weight" type="number" step="0.1" min="0.1" placeholder="وزن" value="${m.weight ?? 1}">
            <input name="hours" type="number" step="0.5" min="0" placeholder="ساعت" value="${m.hours ?? 0}">
            <input name="note" type="text" placeholder="یادداشت" value="${this.escape(m.note || m.name || '')}">
        </div>`;
    }

    _paintAbcGraph(svg, nodes, edges) {
        if (!svg) return;
        const W = 900, H = 520;
        const TYPE_POS = {
            order:    { x: W * 0.18, y: H * 0.5 },
            activity: { x: W * 0.5,  y: H * 0.5 },
            person:   { x: W * 0.82, y: H * 0.5 },
        };
        const COLOR = { order: '#00A1E4', activity: '#F2994A', person: '#27AE60' };
        const placed = nodes.map((n, i) => {
            const seed = TYPE_POS[n.type] || { x: W / 2, y: H / 2 };
            const jitter = (i % 7) * 28 - 70;
            return {
                ...n,
                x: seed.x + (Math.random() - 0.5) * 40,
                y: Math.max(40, Math.min(H - 40, seed.y + jitter + (Math.random() - 0.5) * 30)),
                vx: 0, vy: 0,
            };
        });
        const map = Object.fromEntries(placed.map(n => [n.id, n]));

        for (let t = 0; t < 90; t++) {
            placed.forEach(n => { n.fx = 0; n.fy = 0; });
            for (let i = 0; i < placed.length; i++) {
                for (let j = i + 1; j < placed.length; j++) {
                    const a = placed[i], b = placed[j];
                    const dx = b.x - a.x, dy = b.y - a.y;
                    const d2 = dx * dx + dy * dy + 0.01;
                    const f = 2800 / d2;
                    const d = Math.sqrt(d2);
                    a.fx -= f * dx / d; a.fy -= f * dy / d;
                    b.fx += f * dx / d; b.fy += f * dy / d;
                }
            }
            edges.forEach(e => {
                const a = map[e.from], b = map[e.to];
                if (!a || !b) return;
                const dx = b.x - a.x, dy = b.y - a.y;
                const d = Math.sqrt(dx * dx + dy * dy) + 0.01;
                const f = (d - 120) * 0.06;
                a.fx += f * dx / d; a.fy += f * dy / d;
                b.fx -= f * dx / d; b.fy -= f * dy / d;
            });
            placed.forEach(n => {
                const anchor = TYPE_POS[n.type] || { x: W / 2, y: H / 2 };
                n.vx = (n.vx + n.fx) * 0.8 - (n.x - anchor.x) * 0.02;
                n.vy = (n.vy + n.fy) * 0.8 - (n.y - anchor.y) * 0.02;
                n.x = Math.max(60, Math.min(W - 60, n.x + n.vx));
                n.y = Math.max(40, Math.min(H - 40, n.y + n.vy));
            });
        }

        const maxAmt = Math.max(1, ...edges.map(e => Number(e.amount || 0)));
        const lines = edges.map(e => {
            const a = map[e.from], b = map[e.to];
            if (!a || !b) return '';
            const w = 1 + 4 * (Number(e.amount || 0) / maxAmt);
            return `<line x1="${a.x}" y1="${a.y}" x2="${b.x}" y2="${b.y}" stroke="#94a3b8" stroke-width="${w}" opacity=".55"/>
                <text x="${(a.x + b.x) / 2}" y="${(a.y + b.y) / 2 - 6}" font-size="10" fill="#64748b" text-anchor="middle">${Number(e.amount || 0).toLocaleString('fa-IR')}</text>`;
        }).join('');

        const circles = placed.map(n => {
            const r = n.type === 'order' ? 22 : (n.type === 'activity' ? 18 : 16);
            const c = COLOR[n.type] || '#64748b';
            const label = (n.label || '').slice(0, 22);
            return `<g>
                <circle cx="${n.x}" cy="${n.y}" r="${r}" fill="${c}" opacity=".92"/>
                <text x="${n.x}" y="${n.y + r + 14}" font-size="11" fill="#1e293b" text-anchor="middle">${this.escape(label)}</text>
            </g>`;
        }).join('');

        svg.innerHTML = `<rect width="${W}" height="${H}" fill="#f8fafc"/>${lines}${circles}`;
    }

    async _renderPreview(panel) {
        panel.innerHTML = `
        <div class="svc-acc-preview">
            <div class="acc-form-row">
                <label class="acc-form-group"><span>شناسه SRD</span>
                    <input type="number" data-ref="reportIdInp" min="1"></label>
                <button class="acc-btn acc-btn--primary" data-ref="previewBtn">محاسبه</button>
            </div>
            <div data-ref="previewOut"></div>
        </div>`;
        panel.querySelector('[data-ref="previewBtn"]')?.addEventListener('click', async () => {
            const id = panel.querySelector('[data-ref="reportIdInp"]')?.value;
            if (!id) return;
            const out = panel.querySelector('[data-ref="previewOut"]');
            out.innerHTML = '<div class="acc-loading">⏳</div>';
            const res = await this.api.get(`service/accounting/preview/${id}`);
            out.innerHTML = this._splitsHtml(res?.data ?? {});
        });
    }

    _splitsHtml(s) {
        const a = s.amounts || {};
        const c = s.costs || {};
        const ps = s.activity_cost?.person_shares || [];
        return `<div class="svc-acc-split-box">
            <div class="svc-acc-grid">${[
                ['جمع', a.total], ['کارشناس', c.tech_fee], ['ارشد', c.senior_fee],
                ['COGS', c.parts_cogs], ['سربار', c.overhead_total],
            ].map(([l, v]) => `<div><span>${l}</span><b>${Number(v || 0).toLocaleString('fa-IR')}</b></div>`).join('')}</div>
            ${ps.length ? `<h4 style="margin:14px 0 8px;">سهم نفرها از فعالیت‌ها</h4>
            <ul style="margin:0;padding-right:18px;font-size:.9rem;">
                ${ps.map(p => `<li>${this.escape(p.name)} — ${Number(p.amount || 0).toLocaleString('fa-IR')}</li>`).join('')}
            </ul>` : ''}
        </div>`;
    }

    _kpi(label, val, color) {
        return `<div class="svc-acc-kpi" style="border-top-color:${color}">
            <span>${label}</span><b>${Number(val || 0).toLocaleString('fa-IR')}</b></div>`;
    }

    _toast(msg) {
        const el = document.createElement('div');
        el.textContent = msg;
        el.style.cssText = 'position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:#166534;color:#fff;padding:10px 20px;border-radius:8px;z-index:9999;';
        document.body.appendChild(el);
        setTimeout(() => el.remove(), 3000);
    }
}
