/**
 * PortalAccountingView — حسابداری مجزا per-portal (انتخابات · خدمات · …)
 */
const TOKEN_KEY = 'acc_token';

const NAV = [
    { key: 'dashboard', label: 'خلاصه', icon: '📊' },
    { key: 'documents', label: 'اسناد', icon: '📑' },
    { key: 'ledger', label: 'دفتر کل', icon: '📒' },
    { key: 'trial', label: 'تراز', icon: '⚖️' },
    { key: 'pl', label: 'سود و زیان', icon: '💹' },
    { key: 'chart', label: 'سرفصل‌ها', icon: '🗂' },
];

const STATE_LABEL = {
    pending: 'در صف', posted: 'پست‌شده', confirmed: 'قطعی', failed: 'خطا', cancelled: 'لغو',
};

export default class PortalAccountingView {
    constructor(opts = {}) {
        this.module = opts.module || 'election';
        this.title = opts.title || 'حسابداری پورتال';
        this.backLinks = opts.backLinks || [];
        this.root = null;
        this.tab = 'dashboard';
        this.token = sessionStorage.getItem(TOKEN_KEY) || localStorage.getItem(TOKEN_KEY) || '';
        this.meta = {};
        this.portal = {};
        this.canPost = false;
        this.dashboard = {};
        this.documents = [];
        this.ledger = [];
        this.trial = {};
        this.pl = {};
        this.chart = [];
        this.dateFrom = new Date().toISOString().slice(0, 8) + '01';
        this.dateTo = new Date().toISOString().slice(0, 10);
        this.selectedDoc = null;
    }

    render(root) {
        this.root = root;
        if (!this.token) { this._paintLogin(); return; }
        this._paintLoading();
        this._load();
    }

    _base() { return window.ACC_PORTAL_CFG?.baseUrl || '/acc-engine/'; }
    _api() { return window.ACC_PORTAL_CFG?.api || '/acc-engine/api.php/acc/v1'; }
    _path(p) { return `/portal-acct/${this.module}${p}`; }

    _fmt(n) { return (Number(n) || 0).toLocaleString('fa-IR') + ' ریال'; }
    _esc(s) { return String(s ?? '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }

    async _get(path, qs = '') {
        const r = await fetch(this._api() + path + (qs ? '?' + qs : ''), { headers: { Authorization: 'Bearer ' + this.token } });
        const res = await r.json();
        if (!r.ok) throw new Error(res.message || 'خطای ' + r.status);
        return res;
    }

    async _post(path) {
        const r = await fetch(this._api() + path, { method: 'POST', headers: { Authorization: 'Bearer ' + this.token, 'Content-Type': 'application/json' } });
        const res = await r.json();
        if (!r.ok || res.success === false) throw new Error(res.message || 'خطا');
        return res;
    }

    _paintLoading() {
        this.root.innerHTML = `<div class="erp-loading"><div class="erp-loading__spinner"></div><p>بارگذاری حسابداری…</p></div>`;
    }

    _paintLogin() {
        const site = this._base();
        const links = this.backLinks.map(l => `<a href="${site}${l.href}">${this._esc(l.label)}</a>`).join(' · ');
        this.root.innerHTML = `
        <div class="erp-login-wrap">
            <div class="erp-login-box">
                <div class="erp-login-box__head">
                    <div class="erp-login-box__logo">📒</div>
                    <h2>${this._esc(this.title)}</h2>
                    <p>دفتر کل · اسناد · تراز · سرفصل‌های خودکار</p>
                </div>
                <div class="erp-login-box__body">
                    <form id="pacct-login-form" class="erp-login-box__form">
                        <div class="erp-field"><label>نام کاربری</label>
                            <input class="erp-input" name="username" required></div>
                        <div class="erp-field"><label>رمز عبور</label>
                            <input class="erp-input" name="password" type="password" required></div>
                        <button class="erp-btn erp-btn--primary" type="submit" style="width:100%">ورود</button>
                        <div id="pacct-login-msg" hidden></div>
                    </form>
                    <div class="erp-login-box__links">${links || `<a href="${site}">پورتال</a>`}</div>
                </div>
            </div>
        </div>`;
        this.root.querySelector('#pacct-login-form').addEventListener('submit', e => this._doLogin(e));
    }

    async _doLogin(e) {
        e.preventDefault();
        const msg = this.root.querySelector('#pacct-login-msg');
        const fd = new FormData(e.target);
        if (msg) msg.hidden = true;
        try {
            const r = await fetch(this._api() + '/public/auth/login', {
                method: 'POST', headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ username: fd.get('username'), password: fd.get('password') }),
            });
            const res = await r.json();
            if (!r.ok || !res.success || !res.token) throw new Error(res.message || 'ورود ناموفق');
            this.token = res.token;
            sessionStorage.setItem(TOKEN_KEY, res.token);
            this._paintLoading();
            await this._load();
        } catch (err) {
            if (msg) { msg.hidden = false; msg.className = 'erp-msg erp-msg--err'; msg.textContent = err.message; }
        }
    }

    async _load() {
        try {
            const metaRes = await this._get(this._path('/meta'));
            this.meta = metaRes.meta || {};
            this.portal = metaRes.portal || {};
            this.canPost = !!metaRes.can_post;
            await this._loadTab();
            this._paint();
        } catch (e) {
            if (String(e.message).match(/403|401|دسترسی/)) {
                this.token = ''; sessionStorage.removeItem(TOKEN_KEY); this._paintLogin();
            } else {
                this.root.innerHTML = `<div class="erp-denied"><p>${this._esc(e.message)}</p></div>`;
            }
        }
    }

    async _loadTab() {
        const qs = `date_from=${this.dateFrom}&date_to=${this.dateTo}`;
        if (this.tab === 'dashboard') {
            const d = await this._get(this._path('/dashboard'));
            this.dashboard = d.data || {};
        }
        if (this.tab === 'documents') {
            const d = await this._get(this._path('/documents'), 'limit=100');
            this.documents = d.data || [];
        }
        if (this.tab === 'ledger') {
            const d = await this._get(this._path('/ledger'), qs + '&limit=300');
            this.ledger = d.data || [];
        }
        if (this.tab === 'trial') {
            const d = await this._get(this._path('/trial-balance'), qs);
            this.trial = d.data || {};
        }
        if (this.tab === 'pl') {
            const d = await this._get(this._path('/income-statement'), qs);
            this.pl = d.data || {};
        }
        if (this.tab === 'chart') {
            const c = await this._get(this._path('/chart'));
            this.chart = c.data || [];
        }
    }

    _paint() {
        const site = this._base();
        const tag = this.meta.ledger_tag || this.module.toUpperCase();
        const links = this.backLinks.map(l => `<a href="${site}${l.href}" class="erp-header__link">${this._esc(l.label)}</a>`).join('');
        this.root.innerHTML = `
        <header class="erp-header sacct-header">
            <div class="erp-header__brand">
                <div class="erp-header__logo">📒</div>
                <div>
                    <div class="sacct-header__tag">${this._esc(tag)} · ${this._esc(this.meta.module || this.module)}</div>
                    <div class="erp-header__title">${this._esc(this.meta.subsystem_label || this.title)}</div>
                    <div class="erp-header__subtitle">${this._esc(this.meta.description || '')}</div>
                </div>
            </div>
            <div class="erp-header__actions">${links}<a href="${site}" class="erp-header__link">خروج</a></div>
        </header>
        <div class="sacct-banner">
            <span class="sacct-banner__tag">${this._esc(tag)}</span>
            <strong>${this._esc(this.portal.office_name || '')}</strong>
            <small>ماژول: ${this._esc(this.meta.module)} — حسابداری مجزا · سرفصل‌ها خودکار</small>
        </div>
        <nav class="sacct-nav">${NAV.map(n => `
            <button class="sacct-nav__btn ${this.tab === n.key ? 'sacct-nav__btn--active' : ''}" data-tab="${n.key}">
                ${n.icon} ${n.label}
            </button>`).join('')}</nav>
        ${['ledger','trial','pl'].includes(this.tab) ? this._periodHtml() : ''}
        <main class="sacct-main">${this._panelHtml()}</main>`;

        this.root.querySelectorAll('[data-tab]').forEach(btn => {
            btn.addEventListener('click', async () => {
                this.tab = btn.dataset.tab;
                this._paintLoading();
                await this._loadTab();
                this._paint();
            });
        });
        this._bindPeriod();
        this._bindActions();
    }

    _periodHtml() {
        return `<div class="sacct-period">
            <label>از</label><input type="date" id="pacct-from" value="${this.dateFrom}">
            <label>تا</label><input type="date" id="pacct-to" value="${this.dateTo}">
            <button class="sacct-btn sacct-btn--ghost" id="pacct-apply" type="button">اعمال بازه</button>
        </div>`;
    }

    _bindPeriod() {
        this.root.querySelector('#pacct-apply')?.addEventListener('click', async () => {
            this.dateFrom = this.root.querySelector('#pacct-from')?.value || this.dateFrom;
            this.dateTo = this.root.querySelector('#pacct-to')?.value || this.dateTo;
            this._paintLoading();
            await this._loadTab();
            this._paint();
        });
    }

    _panelHtml() {
        if (this.tab === 'dashboard') return this._dashboardHtml();
        if (this.tab === 'documents') return this._documentsHtml();
        if (this.tab === 'ledger') return this._ledgerHtml();
        if (this.tab === 'trial') return this._trialHtml();
        if (this.tab === 'pl') return this._plHtml();
        if (this.tab === 'chart') return this._chartHtml();
        return '';
    }

    _dashboardHtml() {
        const s = this.dashboard.stats || {};
        return `<div class="sacct-kpi-grid">
            <div class="sacct-kpi"><div class="sacct-kpi__label">در صف</div><div class="sacct-kpi__val">${s.pending ?? 0}</div></div>
            <div class="sacct-kpi"><div class="sacct-kpi__label">قطعی</div><div class="sacct-kpi__val">${s.confirmed ?? 0}</div></div>
            <div class="sacct-kpi sacct-kpi--green"><div class="sacct-kpi__label">درآمد ماه</div><div class="sacct-kpi__val">${this._fmt(s.month_revenue)}</div></div>
            <div class="sacct-kpi sacct-kpi--red"><div class="sacct-kpi__label">هزینه ماه</div><div class="sacct-kpi__val">${this._fmt(s.month_expense)}</div></div>
            <div class="sacct-kpi sacct-kpi--green"><div class="sacct-kpi__label">سود ماه</div><div class="sacct-kpi__val">${this._fmt(s.month_profit)}</div></div>
            <div class="sacct-kpi"><div class="sacct-kpi__label">موقعیت نقد</div><div class="sacct-kpi__val">${this._fmt(s.cash_position)}</div></div>
        </div>
        <div class="sacct-panel"><p class="sacct-hint">هر پورتال دفتر کل و سرفصل‌های مجزای خود را دارد — نیازی به تعریف دستی سر فصل نیست.</p></div>`;
    }

    _documentsHtml() {
        if (!this.documents.length) return `<div class="sacct-panel"><p class="sacct-empty">سندی یافت نشد — تراکنش‌ها پس از ثبت به‌صورت خودکار سند می‌شوند</p></div>`;
        return `<div class="sacct-panel">
            <h3>📑 اسناد (${this.documents.length})</h3>
            <table class="sacct-table"><thead><tr><th>سند</th><th>نوع</th><th>مبلغ</th><th>وضعیت</th><th>تاریخ</th><th></th></tr></thead>
            <tbody>${this.documents.map(r => `<tr>
                <td>#${r.id}<br><small>${this._esc(r.source_module)}</small></td>
                <td>${this._esc(r.event_type)}</td>
                <td class="num">${this._fmt(r.amount)}</td>
                <td><span class="sacct-badge sacct-badge--${r.workflow_state}">${STATE_LABEL[r.workflow_state] || r.workflow_state}</span></td>
                <td class="num">${this._esc((r.created_at || '').slice(0, 10))}</td>
                <td><button class="sacct-btn sacct-btn--ghost" data-doc="${r.id}">جزئیات</button></td>
            </tr>`).join('')}</tbody></table>
            <div id="pacct-doc-detail">${this.selectedDoc ? this._docDetailHtml(this.selectedDoc) : ''}</div>
        </div>`;
    }

    _docDetailHtml(doc) {
        const flows = doc.flows || [];
        return `<div class="sacct-detail"><h4>سند #${doc.id}</h4>
            ${flows.length ? `<table class="sacct-table"><thead><tr><th>بدهکار</th><th>بستانکار</th><th>مبلغ</th></tr></thead><tbody>
            ${flows.map(f => `<tr><td>${this._esc(f.from_code)} ${this._esc(f.from_name)}</td>
                <td>${this._esc(f.to_code)} ${this._esc(f.to_name)}</td><td class="num">${this._fmt(f.amount)}</td></tr>`).join('')}
            </tbody></table>` : '<p>ردیف دفتر ندارد</p>'}</div>`;
    }

    _ledgerHtml() {
        if (!this.ledger.length) return `<div class="sacct-panel"><p class="sacct-empty">ردیف دفتر کل در این بازه نیست</p></div>`;
        return `<div class="sacct-panel"><h3>📒 دفتر کل — ${this._esc(this.meta.ledger_tag)}</h3>
            <table class="sacct-table"><thead><tr><th>تاریخ</th><th>سند</th><th>بدهکار</th><th>بستانکار</th><th>مبلغ</th></tr></thead>
            <tbody>${this.ledger.map(r => `<tr>
                <td>${this._esc((r.created_at||'').slice(0,10))}</td><td>#${r.event_id}</td>
                <td>${this._esc(r.dr_code)} ${this._esc(r.dr_name)}</td>
                <td>${this._esc(r.cr_code)} ${this._esc(r.cr_name)}</td>
                <td class="num">${this._fmt(r.amount)}</td>
            </tr>`).join('')}</tbody></table></div>`;
    }

    _trialHtml() {
        const rows = this.trial.rows || [];
        if (!rows.length) return `<div class="sacct-panel"><p class="sacct-empty">تراز خالی</p></div>`;
        return `<div class="sacct-panel"><h3>⚖️ تراز — ${this.trial.balanced ? '✓' : '⚠'}</h3>
            <table class="sacct-table"><thead><tr><th>کد</th><th>حساب</th><th>بدهکار</th><th>بستانکار</th><th>مانده</th></tr></thead>
            <tbody>${rows.map(r => `<tr><td>${this._esc(r.code)}</td><td>${this._esc(r.name)}</td>
                <td class="num">${this._fmt(r.total_debit)}</td><td class="num">${this._fmt(r.total_credit)}</td>
                <td class="num">${this._fmt(r.net_balance)}</td></tr>`).join('')}
            <tr style="font-weight:700"><td colspan="2">جمع</td>
                <td class="num">${this._fmt(this.trial.total_dr)}</td><td class="num">${this._fmt(this.trial.total_cr)}</td><td></td></tr>
            </tbody></table></div>`;
    }

    _plHtml() {
        const t = this.pl.totals || {};
        const line = rows => (rows||[]).map(r => `<tr><td>${this._esc(r.code)}</td><td>${this._esc(r.name)}</td><td class="num">${this._fmt(r.amount)}</td></tr>`).join('') || '<tr><td colspan="3">—</td></tr>';
        return `<div class="sacct-panel"><h3>💹 سود و زیان</h3>
            <h4>درآمد</h4><table class="sacct-table"><tbody>${line(this.pl.revenue)}</tbody></table>
            <h4>هزینه</h4><table class="sacct-table"><tbody>${line(this.pl.expense_gl)}</tbody></table>
            <div class="sacct-pl-total sacct-pl-total--net"><span>سود خالص</span><span>${this._fmt(t.net_income)}</span></div></div>`;
    }

    _chartHtml() {
        const tree = this._chartTree();
        if (!tree.length) return `<div class="sacct-panel"><p class="sacct-empty">سرفصل‌ها در حال نصب…</p></div>`;
        return `<div class="sacct-panel">
            <h3>🗂 سرفصل‌های حسابداری — ${this._esc(this.meta.ledger_tag)}</h3>
            <p class="sacct-hint">سرفصل‌ها به‌صورت خودکار برای این پورتال ایجاد شده‌اند — نیازی به تعریف دستی در ERP نیست.</p>
            <table class="sacct-table"><thead><tr><th>کد</th><th>نام سر فصل / حساب</th><th>نوع</th></tr></thead>
            <tbody>${tree.map(a => `<tr>
                <td>${this._esc(a.code)}</td>
                <td style="padding-right:${(a.depth||0)*16}px">${a.depth ? '└ ' : ''}${this._esc(a.name)}</td>
                <td>${this._esc(a.account_type)}</td>
            </tr>`).join('')}</tbody></table></div>`;
    }

    _chartTree() {
        const byId = Object.fromEntries(this.chart.map(a => [a.id, a]));
        const roots = this.chart.filter(a => !a.parent_id || !byId[a.parent_id]);
        const out = [];
        const walk = (node, depth) => {
            out.push({ ...node, depth });
            this.chart.filter(c => c.parent_id == node.id).forEach(ch => walk(ch, depth + 1));
        };
        roots.forEach(r => walk(r, 0));
        return out.length ? out : this.chart.map(a => ({ ...a, depth: 0 }));
    }

    _bindActions() {
        this.root.querySelectorAll('[data-doc]').forEach(btn => {
            btn.addEventListener('click', async () => {
                try {
                    const d = await this._get(this._path('/documents/' + btn.dataset.doc));
                    this.selectedDoc = d.data;
                    const el = this.root.querySelector('#pacct-doc-detail');
                    if (el) el.innerHTML = this._docDetailHtml(this.selectedDoc);
                } catch (e) { alert(e.message); }
            });
        });
    }
}
