/**
 * ChartOfAccountsSection.js
 * درخت حساب‌ها با ناوبری فلش‌کارت پدر-فرزندی
 */

import SectionBase from "../SectionBase.js";
const BaseView = SectionBase; // alias — sections don't need the full header

const ACCOUNT_TYPES = {
    asset:     "دارایی",
    liability: "بدهی",
    equity:    "حقوق صاحبان سهام",
    revenue:   "درآمد",
    expense:   "هزینه",
    contra:    "کنترایی",
};

const TYPE_COLORS = {
    asset:     "#3b82f6",
    liability: "#f59e0b",
    equity:    "#8b5cf6",
    revenue:   "#10b981",
    expense:   "#ef4444",
    contra:    "#64748b",
};

const _fmtNum = v => new Intl.NumberFormat("fa-IR").format(Number(v || 0));

export default class ChartOfAccountsSection extends BaseView {

    static title = "";

    constructor(props = {}) {
        super(props);
        this.api       = props.api;
        this._stack    = [];   // [{id, name}] — مسیر breadcrumb
        this._accounts = [];
    }

    async template() {
        return `
            <div class="coa-toolbar">
                <nav class="coa-breadcrumb" data-ref="breadcrumb" aria-label="مسیر">
                    <span class="coa-breadcrumb__item" data-id="">ریشه</span>
                </nav>
                <button class="acc-btn acc-btn--primary acc-btn--sm" data-ref="addBtn">+ افزودن حساب</button>
            </div>
            <div class="coa-grid" data-ref="grid"></div>
        `;
    }

    async afterRender() {
        this.on(this.ref("addBtn"), "click", () => this._openForm(null));
        await this._load(null);
    }

    /* ---------- Data ---------- */

    async _load(parentId) {
        const grid = this.ref("grid");
        if (!grid) return;

        grid.innerHTML = `<div class="coa-loading"><div class="acc-spinner"></div>در حال بارگذاری...</div>`;

        try {
            const params = parentId ? { parent_id: parentId } : {};
            const res = await this.api.get("/accounting/accounts", params);
            this._accounts = res?.data ?? [];
            this._renderGrid(grid);
        } catch {
            grid.innerHTML = `<div class="acc-error">خطا در دریافت سرفصل‌ها</div>`;
        }
    }

    /* ---------- Grid ---------- */

    _renderGrid(grid) {
        if (!this._accounts.length) {
            const parentName = this._stack.length
                ? this._stack[this._stack.length - 1].name
                : "ریشه";
            grid.innerHTML = `<div class="coa-empty">حسابی در «${this.escape(parentName)}» یافت نشد.</div>`;
            return;
        }

        grid.innerHTML = "";

        this._accounts.forEach(acc => {
            const card = this._buildCard(acc);
            grid.appendChild(card);
        });
    }

    _buildCard(acc) {
        const hasChildren = (acc.child_count ?? 0) > 0;
        const color = TYPE_COLORS[acc.account_type] ?? "#64748b";
        const card = document.createElement("div");
        card.className = `coa-card ${hasChildren ? "coa-card--has-children" : "coa-card--leaf"}`;
        card.dataset.id = acc.id;
        card.style.borderTop = `3px solid ${color}`;

        card.innerHTML = `
            ${hasChildren ? `<span class="coa-card__children-badge">${acc.child_count}</span>` : ""}
            <div class="coa-card__code">${this.escape(acc.code ?? "")}</div>
            <div class="coa-card__name">${this.escape(acc.name)}</div>
            <span class="coa-card__type" style="background:${color}1a;color:${color}">${ACCOUNT_TYPES[acc.account_type] ?? acc.account_type}</span>
            <div class="coa-card__actions">
                <button class="coa-card__action-btn" data-action="detail">جزئیات</button>
                <button class="coa-card__action-btn" data-action="edit">ویرایش</button>
                <button class="coa-card__action-btn coa-card__action-btn--danger" data-action="delete">حذف</button>
            </div>
        `;

        card.addEventListener("click", e => {
            const action = e.target.closest("[data-action]")?.dataset.action;
            if (action === "detail") { e.stopPropagation(); this._openDetail(acc); return; }
            if (action === "edit")   { e.stopPropagation(); this._openForm(acc); return; }
            if (action === "delete") { e.stopPropagation(); this._delete(acc); return; }
            if (hasChildren) this._drillDown(acc);
        });

        return card;
    }

    /* ---------- Detail modal (tabs) ---------- */

    async _openDetail(acc) {
        const overlay = document.createElement("div");
        overlay.className = "acc-modal-overlay";
        overlay.innerHTML = `
            <div class="acc-modal" style="max-width:660px;max-height:90vh;overflow-y:auto;">
                <button class="acc-modal__close" type="button">✕</button>
                <div class="acc-modal__title">${this.escape(acc.code ?? "")} — ${this.escape(acc.name ?? "")}</div>
                <div data-ref="detailBody">
                    <div class="acc-loading"><div class="acc-spinner"></div>در حال بارگذاری...</div>
                </div>
            </div>`;
        document.body.appendChild(overlay);

        const close = () => overlay.remove();
        overlay.querySelector(".acc-modal__close").addEventListener("click", close);
        overlay.addEventListener("click", e => { if (e.target === overlay) close(); });

        const body = overlay.querySelector("[data-ref='detailBody']");
        const reload = async (activeTab) => {
            body.innerHTML = `<div class="acc-loading"><div class="acc-spinner"></div>در حال بارگذاری...</div>`;
            try {
                const [detRes, dimRes] = await Promise.all([
                    this.api.get(`/accounting/accounts/${acc.id}/detail`),
                    this.api.get("/accounting/dimensions"),
                ]);
                const d = detRes?.data;
                if (!d) throw new Error("داده‌ای دریافت نشد");
                this._allDims = dimRes?.data ?? [];
                this._renderDetail(body, d, reload, activeTab);
            } catch (e) {
                body.innerHTML = `<div class="acc-error">خطا: ${this.escape(e?.message ?? "")}</div>`;
            }
        };
        await reload();
    }

    _renderDetail(container, d, reload, activeTab) {
        const acc = d.account;

        /* — آرتیکل‌ها (خواستهٔ اصلی) — */
        const articlesHtml = d.articles.length ? d.articles.map(a => {
            const isDR = a.role === "DR";
            const roleBadge = isDR
                ? `<span class="coa-art-role" style="background:#fee2e2;color:#dc2626">بدهکار</span>`
                : `<span class="coa-art-role" style="background:#dcfce7;color:#059669">بستانکار</span>`;
            const cp = `${this.escape(a.counterpart.code || "")} ${this.escape(a.counterpart.name || "")}`.trim();
            const flow = isDR
                ? `<span class="flow-direction__from">${this.escape(acc.code)}</span> → <span class="flow-direction__to">${this.escape(cp)}</span>`
                : `<span class="flow-direction__from">${this.escape(cp)}</span> → <span class="flow-direction__to">${this.escape(acc.code)}</span>`;
            return `
                <div class="coa-art-row">
                    <div class="coa-art-head">
                        <span class="coa-art-event">⚡ ${this.escape(a.event_type)}</span>
                        ${roleBadge}
                        <span class="coa-art-src">[${this.escape(a.source_field || "direct")}]</span>
                    </div>
                    ${a.desc ? `<div class="coa-art-desc">${this.escape(a.desc)}</div>` : ""}
                    <div class="coa-art-flow">${flow}</div>
                </div>`;
        }).join("") : `<div class="acc-empty">این حساب در هیچ آرتیکلِ template‌ای استفاده نشده است.</div>`;

        /* — گردش و مانده — */
        const b = d.balance;
        const balanceHtml = `
            <div class="coa-bal-grid">
                <div class="coa-bal-box" style="border-color:#dc2626">
                    <div class="coa-bal-v" style="color:#dc2626">${_fmtNum(b.total_debit)}</div>
                    <div class="coa-bal-l">جمع بدهکار</div>
                </div>
                <div class="coa-bal-box" style="border-color:#059669">
                    <div class="coa-bal-v" style="color:#059669">${_fmtNum(b.total_credit)}</div>
                    <div class="coa-bal-l">جمع بستانکار</div>
                </div>
                <div class="coa-bal-box" style="border-color:#2563eb">
                    <div class="coa-bal-v" style="color:#2563eb">${_fmtNum(Math.abs(b.net_balance))}</div>
                    <div class="coa-bal-l">مانده (${Number(b.net_balance) >= 0 ? "بدهکار" : "بستانکار"})</div>
                </div>
            </div>
            <div class="coa-art-desc" style="text-align:center;margin-top:10px;">${_fmtNum(b.flow_count)} آرتیکلِ تأییدشده</div>`;

        /* — ابعاد (متصل به این حساب — قابلِ ویرایش) — */
        const linked = d.account_dims || [];
        const linkedIds = new Set(linked.map(x => String(x.dim_id)));
        const available = (this._allDims || []).filter(x => !linkedIds.has(String(x.id)));
        const dimRows = linked.length ? linked.map(r => `
            <div class="coa-kv">
                <span>🏷️ ${this.escape(r.dim_name)} <small style="color:#94a3b8">(${this.escape(r.group_name || "")})</small></span>
                <span style="display:flex;align-items:center;gap:8px;">
                    <b style="color:${r.is_required == 1 ? "#dc2626" : "#64748b"};font-size:12px;">${r.is_required == 1 ? "الزامی" : "اختیاری"}</b>
                    <button class="acc-btn acc-btn--danger acc-btn--sm" data-dim-del="${r.id}">حذف</button>
                </span>
            </div>`).join("") : `<div class="acc-empty">بُعدی به این حساب وصل نشده است.</div>`;
        const addCtrl = available.length ? `
            <div style="display:flex;gap:8px;align-items:center;margin-top:12px;border-top:1px dashed #e2e8f0;padding-top:12px;">
                <select data-ref="dimAddSel" style="flex:1;">${available.map(x => `<option value="${x.id}">${this.escape((x.dim_name || x.name) + " — " + (x.group_name || x.dim_type || ""))}</option>`).join("")}</select>
                <label style="font-size:12px;display:flex;align-items:center;gap:4px;"><input type="checkbox" data-ref="dimAddReq" checked> الزامی</label>
                <button class="acc-btn acc-btn--primary acc-btn--sm" data-dim-add>+ اتصال</button>
            </div>`
            : (this._allDims && this._allDims.length ? `<div style="font-size:12px;color:#94a3b8;margin-top:10px;">همهٔ ابعاد وصل شده‌اند.</div>`
               : `<div style="font-size:12px;color:#94a3b8;margin-top:10px;">ابتدا در تبِ «ابعاد» بُعد تعریف کنید.</div>`);
        const dimHtml = dimRows + addCtrl;

        /* — آخرین اسناد — */
        const recentHtml = d.recent_flows.length ? `
            <table class="flows-table">
                <thead><tr><th>سند</th><th>رویداد</th><th>جهت</th><th>مبلغ</th><th>تأیید</th><th>تاریخ</th></tr></thead>
                <tbody>
                    ${d.recent_flows.map(f => {
                        const inn = f.direction === "in";
                        return `<tr>
                            <td style="font-family:monospace;font-size:11px;">#${f.event_id}</td>
                            <td>${this.escape(f.event_type || "")}</td>
                            <td style="color:${inn ? "#059669" : "#dc2626"};font-weight:600;">${inn ? "⬇ بستانکار" : "⬆ بدهکار"}</td>
                            <td class="num">${_fmtNum(f.amount)}</td>
                            <td><span class="status-badge ${f.is_confirmed == 1 ? "status-badge--confirmed" : "status-badge--draft"}">${f.is_confirmed == 1 ? "✓" : "⏳"}</span></td>
                            <td style="font-size:11px;color:#64748b;">${f.created_at ? String(f.created_at).split("T")[0].split(" ")[0] : ""}</td>
                        </tr>`;
                    }).join("")}
                </tbody>
            </table>` : `<div class="acc-empty">سندی برای این حساب ثبت نشده است.</div>`;

        /* — اطلاعات — */
        const pathStr = d.path.length ? d.path.map(p => this.escape(p.name)).join(" › ") : "ریشه";
        const infoHtml = `
            <div class="coa-kv"><span>کد حساب</span><b style="font-family:monospace">${this.escape(acc.code || "")}</b></div>
            <div class="coa-kv"><span>نام حساب</span><b>${this.escape(acc.name || "")}</b></div>
            <div class="coa-kv"><span>نوع</span><b>${ACCOUNT_TYPES[acc.account_type] ?? this.escape(acc.account_type || "")}</b></div>
            <div class="coa-kv"><span>مسیر</span><b>${pathStr}</b></div>
            <div class="coa-kv"><span>شناسهٔ GL (account_id)</span><b style="font-family:monospace">${this.escape(String(acc.id))}</b></div>`;

        container.innerHTML = `
            <div class="coa-tabs">
                <button class="coa-tab coa-tab--active" data-tab="articles">🔗 آرتیکل‌ها (${d.articles.length})</button>
                <button class="coa-tab" data-tab="balance">📊 گردش و مانده</button>
                <button class="coa-tab" data-tab="dims">🏷️ ابعاد (${(d.account_dims || []).length})</button>
                <button class="coa-tab" data-tab="recent">📄 آخرین اسناد</button>
                <button class="coa-tab" data-tab="info">ℹ️ اطلاعات</button>
            </div>
            <div class="coa-tabpane coa-tabpane--active" data-pane="articles">${articlesHtml}</div>
            <div class="coa-tabpane" data-pane="balance">${balanceHtml}</div>
            <div class="coa-tabpane" data-pane="dims">${dimHtml}</div>
            <div class="coa-tabpane" data-pane="recent">${recentHtml}</div>
            <div class="coa-tabpane" data-pane="info">${infoHtml}</div>`;

        const switchTab = key => {
            container.querySelectorAll(".coa-tab").forEach(x => x.classList.toggle("coa-tab--active", x.dataset.tab === key));
            container.querySelectorAll(".coa-tabpane").forEach(p => p.classList.toggle("coa-tabpane--active", p.dataset.pane === key));
        };
        container.querySelectorAll(".coa-tab").forEach(t => {
            t.addEventListener("click", () => switchTab(t.dataset.tab));
        });
        if (activeTab) switchTab(activeTab);

        // اتصال/حذفِ بُعد به حساب (و ماندن روی تبِ ابعاد بعد از reload)
        const aid = d.account.id;
        container.querySelector("[data-dim-add]")?.addEventListener("click", async () => {
            const sel = container.querySelector("[data-ref='dimAddSel']");
            const req = container.querySelector("[data-ref='dimAddReq']");
            if (!sel?.value) return;
            try {
                await this.api.post(`/accounting/accounts/${aid}/dims`, { dim_id: Number(sel.value), is_required: req?.checked ? 1 : 0 });
                if (reload) await reload("dims");
            } catch (e) { alert("خطا: " + (e?.message ?? "")); }
        });
        container.querySelectorAll("[data-dim-del]").forEach(btn => {
            btn.addEventListener("click", async () => {
                try {
                    await this.api.delete(`/accounting/account-dims/${btn.dataset.dimDel}`);
                    if (reload) await reload("dims");
                } catch (e) { alert("خطا: " + (e?.message ?? "")); }
            });
        });
    }

    /* ---------- Breadcrumb ---------- */

    _drillDown(acc) {
        this._stack.push({ id: acc.id, name: acc.name });
        this._refreshBreadcrumb();
        this._load(acc.id);
    }

    _drillUp(targetIndex) {
        this._stack = this._stack.slice(0, targetIndex);
        this._refreshBreadcrumb();
        const parentId = this._stack.length ? this._stack[this._stack.length - 1].id : null;
        this._load(parentId);
    }

    _refreshBreadcrumb() {
        const bc = this.ref("breadcrumb");
        if (!bc) return;

        const items = [{ id: null, name: "ریشه" }, ...this._stack];

        bc.innerHTML = items.map((item, i) => {
            const isLast = i === items.length - 1;
            if (isLast) {
                return `<span class="coa-breadcrumb__current">${this.escape(item.name)}</span>`;
            }
            return `
                <span class="coa-breadcrumb__item" data-idx="${i}">${this.escape(item.name)}</span>
                <span class="coa-breadcrumb__sep">›</span>
            `;
        }).join("");

        bc.querySelectorAll(".coa-breadcrumb__item").forEach(el => {
            el.addEventListener("click", () => this._drillUp(Number(el.dataset.idx)));
        });
    }

    /* ---------- Form ---------- */

    _openForm(account = null) {
        const isEdit   = !!account;
        const parentId = this._stack.length ? this._stack[this._stack.length - 1].id : null;

        const typeOptions = Object.entries(ACCOUNT_TYPES)
            .map(([k, v]) => `<option value="${k}" ${account?.account_type === k ? "selected" : ""}>${v}</option>`)
            .join("");

        const overlay = document.createElement("div");
        overlay.className = "acc-modal-overlay";
        overlay.innerHTML = `
            <div class="acc-modal">
                <button class="acc-modal__close" type="button">✕</button>
                <div class="acc-modal__title">${isEdit ? "ویرایش حساب" : "افزودن حساب"}</div>
                <form class="acc-modal-form">
                    <div class="acc-form-group">
                        <label>کد حساب</label>
                        <input name="code" type="text" value="${this.escape(account?.code ?? "")}" placeholder="مثال: 1121" required>
                    </div>
                    <div class="acc-form-group">
                        <label>نام حساب</label>
                        <input name="name" type="text" value="${this.escape(account?.name ?? "")}" required>
                    </div>
                    <div class="acc-form-group">
                        <label>نوع حساب</label>
                        <select name="account_type">${typeOptions}</select>
                    </div>
                    <div class="acc-form-group">
                        <label>توضیحات</label>
                        <textarea name="description" rows="2">${this.escape(account?.description ?? "")}</textarea>
                    </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" data-ref="submitBtn">
                            ${isEdit ? "ذخیره" : "افزودن"}
                        </button>
                    </div>
                </form>
            </div>
        `;

        document.body.appendChild(overlay);

        const close = () => overlay.remove();
        overlay.querySelector(".acc-modal__close").addEventListener("click", close);
        overlay.querySelector("[data-action='cancel']").addEventListener("click", close);
        overlay.addEventListener("click", e => { if (e.target === overlay) close(); });

        overlay.querySelector("form").addEventListener("submit", async e => {
            e.preventDefault();
            const fd   = new FormData(e.target);
            const body = {
                code:         fd.get("code"),
                name:         fd.get("name"),
                account_type: fd.get("account_type"),
                description:  fd.get("description"),
                parent_id:    account?.parent_id ?? parentId,
            };

            const btn = overlay.querySelector("[data-ref='submitBtn']");
            btn.disabled = true;
            btn.textContent = "در حال ذخیره...";

            try {
                if (isEdit) {
                    await this.api.put(`/accounting/accounts/${account.id}`, body);
                } else {
                    await this.api.post("/accounting/accounts", body);
                }
                close();
                await this._load(parentId);
            } catch (err) {
                btn.disabled = false;
                btn.textContent = isEdit ? "ذخیره" : "افزودن";
                alert("خطا: " + (err?.message ?? "لطفاً دوباره تلاش کنید"));
            }
        });
    }

    /* ---------- Delete ---------- */

    async _delete(acc) {
        if (!confirm(`آیا از حذف حساب «${acc.name}» اطمینان دارید؟`)) return;
        try {
            await this.api.delete(`/accounting/accounts/${acc.id}`);
            const parentId = this._stack.length ? this._stack[this._stack.length - 1].id : null;
            await this._load(parentId);
        } catch (err) {
            alert("خطا در حذف: " + (err?.message ?? ""));
        }
    }
}
