/**
 * EventDefinitionSection.js
 * مدیریت Template های رویداد (versioned JSON mapping)
 * حالت Template + Exception (manual_entries)
 */

import SectionBase from "../SectionBase.js";
const BaseView = SectionBase;

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

// Template پیش‌فرض برای فرم JSON
const DEFAULT_MAPPING = {
    pairs: [
        { dr_gl_id: null, cr_gl_id: null, source_field: "amount", desc: "" }
    ]
};

export default class EventDefinitionSection extends BaseView {

    static title = "";

    constructor(props = {}) {
        super(props);
        this.api       = props.api;
        this._templates = [];
        this._accounts  = [];
        this._filterType = "";
    }

    async template() {
        return `
            <div class="event-toolbar">
                <button class="acc-btn acc-btn--primary acc-btn--sm" data-ref="addBtn">
                    + Template جدید
                </button>
                <input class="event-type-filter" data-ref="typeFilter" type="text"
                       placeholder="جستجوی نوع رویداد..." style="min-width:200px;">
                <label style="font-size:12px;display:flex;align-items:center;gap:6px;margin-right:auto;">
                    <input type="checkbox" data-ref="activeOnly"> فقط فعال
                </label>
            </div>

            <!-- راهنمای ساختار Template -->
            <div style="background:#f0fdf4;border:1px solid #bbf7d0;border-radius:10px;padding:12px 16px;
                        margin-bottom:16px;font-size:12px;color:#166534;line-height:1.7;">
                <strong>📌 ساختار mapping_logic:</strong> هر template از آرایه‌ای از
                <code>pairs</code> تشکیل می‌شود. هر pair یک جفت بدهکار/بستانکار است.
                مقدار <code>source_field</code> نام فیلد متناظر در
                <code>event_payload</code> است (مثلاً <code>net_amount</code>).
                اگر ندانید، مستقیماً <code>amount</code> را وارد کنید.
            </div>

            <div data-ref="templatesList"></div>
        `;
    }

    async afterRender() {
        this.on(this.ref("addBtn"),     "click",  () => this._openForm(null));
        this.on(this.ref("typeFilter"), "input",  e => {
            this._filterType = e.target.value.trim().toLowerCase();
            this._renderList();
        });
        this.on(this.ref("activeOnly"), "change", () => this._renderList());
        await this._loadAll();
    }

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

    async _loadAll() {
        const list = this.ref("templatesList");
        list.innerHTML = `<div class="acc-loading"><div class="acc-spinner"></div>در حال بارگذاری...</div>`;

        try {
            const [tplRes, accRes] = await Promise.all([
                this.api.get("/accounting/templates"),
                this.api.get("/accounting/accounts", { flat: 1 }),
            ]);
            this._templates = tplRes?.data ?? [];
            this._accounts  = accRes?.data  ?? [];
            this._renderList();
        } catch {
            list.innerHTML = `<div class="acc-error">خطا در دریافت اطلاعات</div>`;
        }
    }

    /* ---------- Render ---------- */

    _renderList() {
        const list       = this.ref("templatesList");
        const activeOnly = this.ref("activeOnly")?.checked ?? false;

        let items = this._templates;
        if (this._filterType)  items = items.filter(t => (t.event_type ?? "").toLowerCase().includes(this._filterType));
        if (activeOnly)        items = items.filter(t => t.is_active == 1);

        if (!items.length) {
            list.innerHTML = `<div class="acc-empty">Template‌ای یافت نشد.</div>`;
            return;
        }

        // Group by event_type
        const groups = {};
        items.forEach(t => {
            const k = t.event_type || "نامشخص";
            if (!groups[k]) groups[k] = [];
            groups[k].push(t);
        });

        list.innerHTML = Object.entries(groups).map(([et, tpls]) => `
            <div class="event-type-group">
                <div class="event-type-group__header">
                    ⚡ ${this.escape(et)}
                    <small style="font-weight:400;margin-right:8px;color:#6b7280;">(${tpls.length} نسخه)</small>
                </div>
                ${tpls.map(t => this._templateRowHtml(t)).join("")}
            </div>
        `).join("");

        list.querySelectorAll("[data-action='edit']").forEach(btn => {
            const id = Number(btn.closest(".rule-row").dataset.id);
            const t  = this._templates.find(x => x.id === id);
            btn.addEventListener("click", () => this._openForm(t));
        });

        list.querySelectorAll("[data-action='toggle']").forEach(btn => {
            const id = Number(btn.closest(".rule-row").dataset.id);
            const t  = this._templates.find(x => x.id === id);
            btn.addEventListener("click", () => this._toggleActive(t));
        });

        list.querySelectorAll("[data-action='delete']").forEach(btn => {
            const id = Number(btn.closest(".rule-row").dataset.id);
            const t  = this._templates.find(x => x.id === id);
            btn.addEventListener("click", () => this._delete(t));
        });
    }

    _templateRowHtml(t) {
        const logic  = typeof t.mapping_logic === "string"
            ? JSON.parse(t.mapping_logic) : (t.mapping_logic ?? {});
        const pairs  = logic?.pairs ?? [];

        const pairBadges = pairs.map(p => {
            const from = this._accountLabel(p.dr_gl_id);
            const to   = this._accountLabel(p.cr_gl_id);
            return `
                <span class="flow-direction" style="font-size:11px;gap:4px;">
                    <span class="flow-direction__from" style="font-size:10px;">${this.escape(from)}</span>
                    <span class="flow-direction__arrow">→</span>
                    <span class="flow-direction__to"   style="font-size:10px;">${this.escape(to)}</span>
                    <span style="font-size:10px;color:#94a3b8;">[${this.escape(p.source_field || "direct")}]</span>
                </span>
            `;
        }).join("");

        return `
            <div class="rule-row" data-id="${t.id}">
                <div class="rule-row__main">
                    <div class="rule-row__title" style="display:flex;align-items:center;gap:8px;">
                        ${this.escape(t.template_name || `Template #${t.id}`)}
                        <span style="font-size:11px;background:#e0f2fe;color:#0369a1;padding:1px 8px;border-radius:8px;">
                            v${t.version}
                        </span>
                        <span class="status-badge ${t.is_active ? "status-badge--confirmed" : "status-badge--cancelled"}">
                            ${t.is_active ? "فعال" : "غیرفعال"}
                        </span>
                    </div>
                    <div class="rule-row__meta" style="margin-top:6px;flex-direction:column;gap:4px;">
                        ${pairBadges || `<span style="color:#94a3b8;font-size:11px;">بدون pair</span>`}
                        ${t.description ? `<span style="color:#64748b;font-size:11px;">${this.escape(t.description)}</span>` : ""}
                    </div>
                </div>
                <div class="rule-row__actions">
                    <button class="acc-btn acc-btn--secondary acc-btn--sm" data-action="edit">ویرایش</button>
                    <button class="acc-btn acc-btn--secondary acc-btn--sm" data-action="toggle">
                        ${t.is_active ? "غیرفعال" : "فعال"} کن
                    </button>
                    <button class="acc-btn acc-btn--danger acc-btn--sm" data-action="delete">حذف</button>
                </div>
            </div>
        `;
    }

    _accountLabel(id) {
        if (!id) return "?";
        const a = this._accounts.find(x => String(x.id) === String(id) || String(x.account_id) === String(id));
        return a ? `${a.code ?? a.account_code} — ${a.name ?? a.account_name}` : `#${id}`;
    }

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

    _openForm(tpl = null) {
        const isEdit   = !!tpl;
        const accOpts  = this._accounts.map(a =>
            `<option value="${a.id ?? a.account_id}">
                ${this.escape((a.code ?? a.account_code) + " — " + (a.name ?? a.account_name))}
             </option>`
        ).join("");

        const initLogic = isEdit
            ? (typeof tpl.mapping_logic === "string" ? tpl.mapping_logic : JSON.stringify(tpl.mapping_logic, null, 2))
            : JSON.stringify(DEFAULT_MAPPING, null, 2);

        const overlay = document.createElement("div");
        overlay.className = "acc-modal-overlay";
        overlay.innerHTML = `
            <div class="acc-modal" style="max-width:680px;max-height:90vh;overflow-y:auto;">
                <button class="acc-modal__close" type="button">✕</button>
                <div class="acc-modal__title">
                    ${isEdit ? `ویرایش Template — v${tpl.version}` : "Template جدید"}
                </div>
                <form id="tpl-form">
                    <div class="doc-form-row">
                        <div class="acc-form-group">
                            <label>نوع رویداد (event_type) *</label>
                            <input name="event_type" value="${this.escape(tpl?.event_type ?? "")}"
                                   placeholder="مثال: SALES_INVOICE" required
                                   ${isEdit ? "readonly style='background:#f8fafc'" : ""}>
                        </div>
                        <div class="acc-form-group">
                            <label>نام Template</label>
                            <input name="template_name" value="${this.escape(tpl?.template_name ?? "")}">
                        </div>
                    </div>

                    <div class="acc-form-group">
                        <label>توضیحات</label>
                        <input name="description" value="${this.escape(tpl?.description ?? "")}">
                    </div>

                    <!-- ساخت بصری Pairs -->
                    <div style="margin-bottom:8px;font-size:13px;font-weight:600;color:#374151;">
                        🔗 Pairs (بدهکار / بستانکار)
                    </div>
                    <div id="pairs-builder" style="margin-bottom:12px;"></div>
                    <button type="button" id="add-pair-btn"
                            class="acc-btn acc-btn--secondary acc-btn--sm">+ افزودن Pair</button>

                    <!-- JSON پیشرفته -->
                    <details style="margin-top:16px;">
                        <summary style="cursor:pointer;font-size:12px;color:#64748b;padding:8px 0;">
                            ⚙️ ویرایش JSON مستقیم (پیشرفته)
                        </summary>
                        <div class="acc-form-group" style="margin-top:8px;">
                            <textarea id="logic-json" rows="10"
                                      style="font-family:monospace;font-size:12px;">${this.escape(initLogic)}</textarea>
                            <small style="color:#94a3b8;">ساختار: { "pairs": [{ "dr_gl_id":N, "cr_gl_id":N, "source_field":"...", "desc":"..." }] }</small>
                        </div>
                    </details>

                    <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" id="tpl-submit">
                            ${isEdit ? "ذخیره" : "ایجاد Template"}
                        </button>
                    </div>
                </form>
            </div>
        `;

        document.body.appendChild(overlay);

        // Parse initial pairs
        let pairs = [];
        try { pairs = JSON.parse(initLogic)?.pairs ?? []; } catch {}

        const builder = overlay.querySelector("#pairs-builder");
        const jsonTA  = overlay.querySelector("#logic-json");

        const renderPairs = () => {
            builder.innerHTML = "";
            pairs.forEach((p, i) => {
                const row = document.createElement("div");
                row.style.cssText = "display:grid;grid-template-columns:1fr 1fr 1fr 80px auto;gap:8px;margin-bottom:8px;align-items:end;";
                row.innerHTML = `
                    <div class="acc-form-group" style="margin:0">
                        <label style="font-size:11px;">بدهکار (DR)</label>
                        <select class="pair-dr">${accOpts}</select>
                    </div>
                    <div class="acc-form-group" style="margin:0">
                        <label style="font-size:11px;">بستانکار (CR)</label>
                        <select class="pair-cr">${accOpts}</select>
                    </div>
                    <div class="acc-form-group" style="margin:0">
                        <label style="font-size:11px;">source_field</label>
                        <input class="pair-src" type="text" value="${this.escape(p.source_field || "amount")}" placeholder="amount">
                    </div>
                    <div class="acc-form-group" style="margin:0">
                        <label style="font-size:11px;">شرح</label>
                        <input class="pair-desc" type="text" value="${this.escape(p.desc || "")}">
                    </div>
                    <button type="button" class="acc-btn acc-btn--danger acc-btn--sm pair-del" style="margin-top:20px;">✕</button>
                `;

                // Set selected values
                row.querySelector(".pair-dr").value = p.dr_gl_id ?? "";
                row.querySelector(".pair-cr").value = p.cr_gl_id ?? "";

                // Sync to JSON
                const syncJson = () => {
                    pairs[i] = {
                        dr_gl_id:     Number(row.querySelector(".pair-dr").value) || null,
                        cr_gl_id:     Number(row.querySelector(".pair-cr").value) || null,
                        source_field: row.querySelector(".pair-src").value.trim() || "amount",
                        desc:         row.querySelector(".pair-desc").value.trim(),
                    };
                    jsonTA.value = JSON.stringify({ pairs }, null, 2);
                };

                row.querySelectorAll("select, input").forEach(el => el.addEventListener("change", syncJson));
                row.querySelectorAll("input").forEach(el => el.addEventListener("input", syncJson));

                row.querySelector(".pair-del").addEventListener("click", () => {
                    pairs.splice(i, 1);
                    renderPairs();
                    jsonTA.value = JSON.stringify({ pairs }, null, 2);
                });

                builder.appendChild(row);
            });
        };

        renderPairs();

        overlay.querySelector("#add-pair-btn").addEventListener("click", () => {
            pairs.push({ dr_gl_id: null, cr_gl_id: null, source_field: "amount", desc: "" });
            renderPairs();
        });

        // JSON textarea sync → rebuild pairs
        jsonTA.addEventListener("change", () => {
            try {
                const parsed = JSON.parse(jsonTA.value);
                pairs = parsed?.pairs ?? [];
                renderPairs();
            } catch { /* invalid JSON, keep as-is */ }
        });

        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("#tpl-form").addEventListener("submit", async e => {
            e.preventDefault();
            const fd  = overlay.querySelector("#tpl-form");
            let logicJson = jsonTA.value.trim();

            // Validate JSON
            try {
                const parsed = JSON.parse(logicJson);
                if (!parsed.pairs) throw new Error("کلید pairs وجود ندارد");
            } catch (err) {
                alert("mapping_logic نامعتبر: " + err.message);
                return;
            }

            const body = {
                event_type:    fd.querySelector("[name='event_type']").value.trim(),
                template_name: fd.querySelector("[name='template_name']").value.trim(),
                description:   fd.querySelector("[name='description']").value.trim(),
                mapping_logic: JSON.parse(logicJson),
                is_active:     1,
            };

            const btn = overlay.querySelector("#tpl-submit");
            btn.disabled = true;
            btn.textContent = "در حال ذخیره...";

            try {
                if (isEdit) {
                    await this.api.put(`/accounting/templates/${tpl.id}`, body);
                } else {
                    await this.api.post("/accounting/templates", body);
                }
                close();
                await this._loadAll();
            } catch (err) {
                btn.disabled = false;
                btn.textContent = isEdit ? "ذخیره" : "ایجاد Template";
                alert("خطا: " + (err?.message ?? ""));
            }
        });
    }

    /* ---------- Toggle Active / Delete ---------- */

    async _toggleActive(tpl) {
        try {
            await this.api.put(`/accounting/templates/${tpl.id}`, { is_active: tpl.is_active ? 0 : 1 });
            await this._loadAll();
        } catch (err) {
            alert("خطا: " + (err?.message ?? ""));
        }
    }

    async _delete(tpl) {
        if (!confirm(`حذف (غیرفعال) template «${tpl.template_name || tpl.event_type} v${tpl.version}»؟`)) return;
        try {
            await this.api.delete(`/accounting/templates/${tpl.id}`);
            await this._loadAll();
        } catch (err) {
            alert("خطا: " + (err?.message ?? ""));
        }
    }
}
