/**
 * ServiceReportsSection.js — گزارش فنی + SRD (ویزارد ۱۳ مرحله‌ای)
 */
import SectionBase from "../../accounting/SectionBase.js";

const STEPS = [
    { id: 1,  title: "نوع خدمت" },
    { id: 2,  title: "مشتری" },
    { id: 3,  title: "دستگاه" },
    { id: 4,  title: "شرح درخواست" },
    { id: 5,  title: "گزارش کارشناسی" },
    { id: 6,  title: "خدمات انجام‌شده" },
    { id: 7,  title: "قطعات" },
    { id: 8,  title: "مواد مصرفی" },
    { id: 9,  title: "هزینه جانبی" },
    { id: 10, title: "پیشنهاد فنی" },
    { id: 11, title: "قرارداد PM" },
    { id: 12, title: "جمع مالی" },
    { id: 13, title: "تأیید نهایی" },
];

const SERVICE_TYPE_ICONS = {
    phone_consult: "📞",
    online_consult: "💻",
    site_visit: "🔍",
    troubleshooting: "⚡",
    repair: "🛠",
    pm: "📅",
    overhaul: "⚙️",
    install: "🏗",
    parts_supply: "🔩",
    equipment_purchase: "🏭",
    contract_support: "📋",
};

export default class ServiceReportsSection extends SectionBase {

    constructor(props) {
        super(props);
        this._meta = null;
        this._wizard = null;
    }

    async template() {
        return `
        <div class="acc-section-wrap">
            <div class="acc-toolbar">
                <h2 class="acc-section-title">📄 گزارش فنی (SRD)</h2>
                <div style="display:flex;gap:8px;">
                    <button class="acc-btn acc-btn--primary" data-ref="newBtn">➕ گزارش جدید</button>
                    <button class="acc-btn acc-btn--secondary" data-ref="refreshBtn">🔄</button>
                </div>
            </div>
            <div data-ref="wrap"><div class="acc-loading">⏳</div></div>
        </div>`;
    }

    async afterRender() {
        try {
            this._meta = (await this.api.get("service/meta")) ?? {};
        } catch { this._meta = {}; }
        await this._load();
        this.on(this.ref("refreshBtn"), "click", () => this._load());
        this.on(this.ref("newBtn"), "click", () => this._openWizard());
    }

    async _load() {
        this.ref("wrap").innerHTML = `<div class="acc-loading">⏳</div>`;
        try {
            const res = await this.api.get("service/reports");
            this._rows = res?.data ?? [];
            this._renderList();
        } catch (e) {
            this.ref("wrap").innerHTML = `<div class="acc-error">❌ ${this.escape(e.message)}</div>`;
        }
    }

    _renderList() {
        if (!this._rows.length) {
            this.ref("wrap").innerHTML = `<div class="acc-empty">گزارشی ثبت نشده — «گزارش جدید» بزنید</div>`;
            return;
        }
        this.ref("wrap").innerHTML = `
        <table class="acc-table">
            <thead><tr>
                <th>شماره</th><th>مشتری</th><th>موضع</th><th>وضعیت</th><th>مبلغ</th><th>حسابداری</th><th></th>
            </tr></thead>
            <tbody>
            ${this._rows.map(r => `<tr>
                <td><b>${this.escape(r.report_no)}</b></td>
                <td>${this.escape(r.customer_name)}</td>
                <td><small>${this.escape(r.site_label || "—")}</small></td>
                <td>${r.status === "final"
                    ? '<span style="color:#059669;font-weight:700;">✅ نهایی</span>'
                    : '<span style="color:#f59e0b;">📝 پیش‌نویس</span>'}
                    ${r.senior_review_status === "pending" ? '<br><small style="color:#f59e0b;">⏳ بازبینی ارشد</small>' : ""}
                    ${r.senior_review_status === "rejected" ? '<br><small style="color:#dc2626;">❌ رد ارشد</small>' : ""}</td>
                <td>${Number(r.total || 0).toLocaleString("fa-IR")}</td>
                <td>${r.acc_revenue_event_id
                    ? `<span class="acc-link-badge" title="سند حسابداری">🔗 #${r.acc_revenue_event_id}</span>
                       ${r.acc_workflow_state === 'posted' ? '<br><small style="color:#059669;">✅ صادر</small>'
                       : r.acc_workflow_state ? `<br><small style="color:#f59e0b;">⏳ ${this.escape(r.acc_workflow_state)}</small>` : ''}`
                    : (r.status === "final" ? '<small style="color:#f59e0b;">⏳ صف حسابدار</small>' : "—")}</td>
                <td>
                    <button class="acc-btn acc-btn--sm" data-edit="${r.id}">✏️</button>
                    ${r.status !== "final" && r.request_id
                        ? `<button class="acc-btn acc-btn--sm" data-cost="${r.id}" title="درخواست تأیید هزینه">💰</button>`
                        : ""}
                    ${r.status === "final"
                        ? `<button class="acc-btn acc-btn--sm" data-view="${r.id}">👁</button>`
                        : `<button class="acc-btn acc-btn--sm acc-btn--primary" data-finalize="${r.id}">✅</button>`}
                </td>
            </tr>`).join("")}
            </tbody>
        </table>`;

        this.ref("wrap").querySelectorAll("[data-edit]").forEach(b =>
            b.addEventListener("click", () => this._openWizard(+b.dataset.edit))
        );
        this.ref("wrap").querySelectorAll("[data-cost]").forEach(b =>
            b.addEventListener("click", () => this._requestCostApproval(+b.dataset.cost))
        );
        this.ref("wrap").querySelectorAll("[data-finalize]").forEach(b =>
            b.addEventListener("click", () => this._finalize(+b.dataset.finalize))
        );
        this.ref("wrap").querySelectorAll("[data-view]").forEach(b =>
            b.addEventListener("click", () => this._viewReport(+b.dataset.view))
        );
    }

    async _viewReport(id) {
        try {
            const res = await this.api.get(`service/reports/${id}`);
            const url = res?.data?.public_url;
            if (url) window.open(url, "_blank");
            else alert("لینک عمومی موجود نیست — گزارش را نهایی کنید.");
        } catch (e) { alert(e.message); }
    }

    async _openWizard(reportId = null) {
        let data = {
            service_type: "repair",
            service_lines: [], part_lines: [], material_lines: [], extra_costs: [],
            recommendations: [], pm_offer: {}, technical_readings: {},
            complaint_tags: [], discount: 0, tax: 0, paid: 0,
        };

        if (reportId) {
            const res = await this.api.get(`service/reports/${reportId}`);
            data = { ...data, ...(res?.data ?? {}), id: reportId };
        } else {
            const res = await this.api.post("service/reports", {});
            data.id = res?.data?.id;
            data.report_no = res?.data?.report_no;
            data.public_token = res?.data?.public_token;
        }

        this._wizard = { step: 1, data, visited: new Set([1]) };
        this._renderWizardModal();
    }

    _renderWizardModal() {
        const w = this._wizard;
        if (!w) return;

        let existing = document.getElementById("svc-wizard-modal");
        if (existing) existing.remove();

        const types = this._meta.service_types ?? {};
        const tags  = this._meta.complaint_tags ?? [];
        const pmOpts = this._meta.pm_options ?? {};
        const d = w.data;
        const step = w.step;

        const visited = w.visited || new Set([step]);
        visited.add(step);

        const stepNav = `
            <div class="svc-srd-stepper">
                <div class="svc-srd-step-meta">
                    <span class="svc-srd-step-badge">مرحله ${step} از ${STEPS.length}</span>
                    <strong class="svc-srd-step-name">${STEPS[step - 1].title}</strong>
                </div>
                <div class="svc-srd-progress"><div class="svc-srd-progress-bar" style="width:${Math.round((step / STEPS.length) * 100)}%"></div></div>
                <div class="svc-srd-dots" role="tablist">
                    ${STEPS.map(s => `
                        <button type="button" class="svc-srd-dot ${s.id === step ? "is-active" : ""} ${visited.has(s.id) && s.id !== step ? "is-done" : ""}"
                            data-goto-step="${s.id}" title="${this.escape(s.title)}">
                            <span class="svc-srd-dot-num">${visited.has(s.id) && s.id !== step ? "✓" : s.id}</span>
                        </button>`).join("")}
                </div>
            </div>`;

        let body = "";

        if (step === 1) {
            body = `<div class="svc-srd-type-grid">
                ${Object.entries(types).map(([k, v]) => `
                <label class="svc-srd-type-card ${d.service_type === k ? "is-selected" : ""}">
                    <input type="radio" name="service_type" value="${k}" ${d.service_type === k ? "checked" : ""}>
                    <span class="svc-srd-type-icon">${SERVICE_TYPE_ICONS[k] || "🔧"}</span>
                    <span class="svc-srd-type-label">${this.escape(v)}</span>
                </label>`).join("")}
            </div>`;
        } else if (step === 2) {
            const rd = d.report_date || new Date().toISOString().slice(0, 10);
            body = `
                <div class="acc-form-group"><label>شماره گزارش</label><input class="acc-input" value="${this.escape(d.report_no)}" disabled></div>
                <div class="acc-form-group"><label>تاریخ</label><input name="report_date" type="date" class="acc-input" value="${this.escape(rd)}"></div>
                <div class="acc-form-group"><label>نام مشتری</label><input name="customer_name" class="acc-input" value="${this.escape(d.customer_name ?? "")}"></div>
                <div class="acc-form-group"><label>شرکت</label><input name="company" class="acc-input" value="${this.escape(d.company ?? "")}"></div>
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;">
                    <div class="acc-form-group"><label>تلفن</label><input name="phone" class="acc-input" dir="ltr" value="${this.escape(d.phone ?? "")}"></div>
                    <div class="acc-form-group"><label>ایمیل</label><input name="email" class="acc-input" dir="ltr" value="${this.escape(d.email ?? "")}"></div>
                </div>
                <div class="acc-form-group"><label>آدرس</label><textarea name="address" class="acc-input" rows="2">${this.escape(d.address ?? "")}</textarea></div>
                <div class="acc-form-group"><label>شناسه پرونده</label><input name="case_no" class="acc-input" value="${this.escape(d.case_no ?? "")}"></div>
                <div class="acc-form-group"><label>موضع / سایت</label><input name="site_label" class="acc-input" value="${this.escape(d.site_label ?? "")}"></div>`;
        } else if (step === 3) {
            const snap = d.device_snapshot ?? {};
            body = `
                <div class="acc-form-group"><label>نوع</label><input name="device_type" class="acc-input" value="${this.escape(snap.device_type ?? "")}"></div>
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;">
                    <div class="acc-form-group"><label>برند</label><input name="brand" class="acc-input" value="${this.escape(snap.brand ?? "")}"></div>
                    <div class="acc-form-group"><label>مدل</label><input name="model" class="acc-input" value="${this.escape(snap.model ?? "")}"></div>
                </div>
                <div class="acc-form-group"><label>سریال</label><input name="serial_no" class="acc-input" dir="ltr" value="${this.escape(snap.serial_no ?? "")}"></div>
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;">
                    <div class="acc-form-group"><label>ظرفیت</label><input name="capacity" class="acc-input" value="${this.escape(snap.capacity ?? "")}"></div>
                    <div class="acc-form-group"><label>مبرد</label><input name="refrigerant" class="acc-input" value="${this.escape(snap.refrigerant ?? "")}"></div>
                </div>
                <div class="acc-form-group"><label>محل نصب</label><input name="install_location" class="acc-input" value="${this.escape(snap.install_location ?? "")}"></div>
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;">
                    <div class="acc-form-group"><label>ساعات کارکرد</label><input name="operating_hours" type="number" class="acc-input" value="${snap.operating_hours ?? 0}"></div>
                    <div class="acc-form-group"><label>آخرین سرویس</label><input name="last_service_date" type="date" class="acc-input" value="${this.escape(snap.last_service_date ?? "")}"></div>
                </div>`;
        } else if (step === 4) {
            body = `
                <div style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px;">
                    ${tags.map(t => {
                        const sel = (d.complaint_tags || []).includes(t);
                        return `<label style="font-size:12px;padding:4px 10px;border:1px solid ${sel ? "#1d4ed8" : "#e2e8f0"};border-radius:20px;cursor:pointer;">
                            <input type="checkbox" name="tag" value="${this.escape(t)}" ${sel ? "checked" : ""} style="margin-left:4px;">${this.escape(t)}
                        </label>`;
                    }).join("")}
                </div>
                <div class="acc-form-group"><label>شرح درخواست</label>
                    <textarea name="complaint_text" class="acc-input" rows="4">${this.escape(d.complaint_text ?? "")}</textarea></div>`;
        } else if (step === 5) {
            const tr = d.technical_readings ?? {};
            const fields = [
                ["suction_pressure", "فشار مکش"], ["discharge_pressure", "فشار دهش"],
                ["superheat", "سوپرهیت"], ["subcool", "سابکول"],
                ["compressor_amps", "آمپر"], ["voltage", "ولتاژ"],
                ["ambient_temp", "دمای محیط"], ["inlet_temp", "دمای ورود"],
                ["outlet_temp", "دمای خروج"], ["oil_status", "روغن"], ["filter_status", "فیلتر"],
            ];
            body = fields.map(([k, lbl]) => `
                <div class="acc-form-group"><label>${lbl}</label>
                    <input name="${k}" class="acc-input" value="${this.escape(tr[k] ?? "")}"></div>
            `).join("") + `<div class="acc-form-group"><label>نتیجه عیب‌یابی</label>
                <textarea name="diagnosis_result" class="acc-input" rows="3">${this.escape(d.diagnosis_result ?? "")}</textarea></div>
                <div class="acc-form-group"><label>📷 عکس قبل از کار</label>
                    <input type="file" accept="image/*" multiple data-photo="before" class="acc-input">
                    <div data-photo-preview="before" style="display:flex;flex-wrap:wrap;gap:6px;margin-top:6px;">
                        ${(d.photos_before || []).map((p, i) => `<img src="${this.escape(p)}" style="width:60px;height:60px;object-fit:cover;border-radius:6px;" data-rm-before="${i}">`).join("")}
                    </div></div>
                <div class="acc-form-group"><label>📷 عکس بعد از کار</label>
                    <input type="file" accept="image/*" multiple data-photo="after" class="acc-input">
                    <div data-photo-preview="after" style="display:flex;flex-wrap:wrap;gap:6px;margin-top:6px;">
                        ${(d.photos_after || []).map((p, i) => `<img src="${this.escape(p)}" style="width:60px;height:60px;object-fit:cover;border-radius:6px;" data-rm-after="${i}">`).join("")}
                    </div></div>`;
        } else if (step === 6) {
            body = this._lineEditor("service_lines", d.service_lines, [
                { key: "desc", label: "شرح", w: "2fr" },
                { key: "qty", label: "تعداد", w: "80px" },
                { key: "unit", label: "واحد", w: "80px" },
                { key: "unit_price", label: "قیمت واحد", w: "100px" },
            ]);
        } else if (step === 7) {
            body = `
                <div class="acc-form-group">
                    <label>🔍 جستجوی قطعه از انبار</label>
                    <input class="acc-input" id="svc-part-search" placeholder="نام یا کد قطعه...">
                    <div id="svc-part-results"></div>
                </div>` +
            this._lineEditor("part_lines", d.part_lines, [
                { key: "name", label: "قطعه", w: "2fr" },
                { key: "part_no", label: "شماره فنی", w: "100px" },
                { key: "qty", label: "تعداد", w: "70px" },
                { key: "unit_price", label: "قیمت", w: "90px" },
            ]);
        } else if (step === 8) {
            body = this._lineEditor("material_lines", d.material_lines, [
                { key: "desc", label: "شرح", w: "2fr" },
                { key: "qty", label: "مقدار", w: "70px" },
                { key: "unit", label: "واحد", w: "70px" },
                { key: "unit_price", label: "قیمت", w: "90px" },
            ]);
        } else if (step === 9) {
            const presets = this._meta.extra_cost_presets || [];
            body = (presets.length ? `<div style="display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px;">
                ${presets.map(p => `<button type="button" class="acc-btn acc-btn--sm" data-preset-cost data-desc="${this.escape(p.desc)}" data-amount="${p.amount}">+ ${this.escape(p.desc)}</button>`).join("")}
            </div>` : "") +
            this._lineEditor("extra_costs", d.extra_costs, [
                { key: "desc", label: "شرح هزینه", w: "2fr" },
                { key: "amount", label: "مبلغ", w: "120px" },
            ], true);
        } else if (step === 10) {
            const recs = ["تعویض فیلتر درایر", "شستشوی کندانسور", "تعویض فن", "اورهال کمپرسور", "تعویض کنترلر", "سرویس ماه آینده"];
            body = recs.map(r => {
                const sel = (d.recommendations || []).includes(r);
                return `<label style="display:block;padding:8px;border-bottom:1px solid #f1f5f9;">
                    <input type="checkbox" name="rec" value="${this.escape(r)}" ${sel ? "checked" : ""}> ${this.escape(r)}
                </label>`;
            }).join("");
        } else if (step === 11) {
            const pmPrices = this._meta.pm_prices || {};
            body = Object.entries(pmOpts).map(([k, v]) => {
                const sel = d.pm_offer?.plan === k;
                const price = pmPrices[k] || 0;
                return `<label style="display:block;padding:10px;margin:4px 0;border:1px solid #e2e8f0;border-radius:8px;">
                    <input type="radio" name="pm_plan" value="${k}" ${sel ? "checked" : ""}> ☑ ${this.escape(v)}
                    <span style="font-size:11px;color:#1d4ed8;margin-right:8px;">${Number(price).toLocaleString("fa-IR")} ریال</span>
                </label>`;
            }).join("") + `<p style="font-size:11px;color:#64748b;margin-top:8px;">با نهایی‌سازی، پیش‌فاکتور PM به‌صورت خودکار صادر می‌شود.</p>`;
        } else if (step === 12) {
            body = `
                <div style="background:#f8fafc;padding:14px;border-radius:10px;line-height:2;">
                    <div>جمع خدمات: <b>${this._fmt(d.subtotal_services)}</b></div>
                    <div>جمع قطعات: <b>${this._fmt(d.subtotal_parts)}</b></div>
                    <div>جمع مواد: <b>${this._fmt(d.subtotal_materials)}</b></div>
                    <div>جمع جانبی: <b>${this._fmt(d.subtotal_extra)}</b></div>
                    <hr style="border:none;border-top:1px solid #e2e8f0;">
                    <div class="acc-form-group"><label>تخفیف</label><input name="discount" type="number" class="acc-input" value="${d.discount ?? 0}"></div>
                    <div class="acc-form-group"><label>مالیات</label><input name="tax" type="number" class="acc-input" value="${d.tax ?? 0}"></div>
                    <div class="acc-form-group"><label>پرداخت‌شده</label><input name="paid" type="number" class="acc-input" value="${d.paid ?? 0}"></div>
                    <div style="font-size:18px;color:#1d4ed8;font-weight:800;">مبلغ نهایی: ${this._fmt(d.total)}</div>
                    <div>مانده: <b style="color:#dc2626;">${this._fmt(d.balance)}</b></div>
                    ${d.request_id ? `<button type="button" class="acc-btn acc-btn--secondary" data-request-cost style="margin-top:10px;width:100%;">📨 ارسال تأیید هزینه به مشتری</button>` : ""}
                    ${d.cost_approval_status === "pending" ? `<p style="color:#f59e0b;font-size:12px;">⏳ در انتظار تأیید مشتری</p>` : ""}
                </div>`;
        } else if (step === 13) {
            const base = location.origin + (location.pathname.includes("/app") ? location.pathname.replace(/\/app.*/, "") : "");
            const url = d.public_token
                ? `${base}/service-report.php?token=${d.public_token}`
                : "";
            body = `
                <div class="acc-form-group"><label>امضای کارشناس</label><input name="tech_signature" class="acc-input" value="${this.escape(d.tech_signature ?? "")}"></div>
                <div class="acc-form-group"><label>امضای مشتری</label><input name="customer_signature" class="acc-input" value="${this.escape(d.customer_signature ?? "")}"></div>
                <div class="acc-form-group"><label>مهر شرکت</label><input name="company_stamp" class="acc-input" value="${this.escape(d.company_stamp ?? this._meta.company_stamp_default ?? "")}"></div>
                ${url ? `<div style="background:#eff6ff;padding:12px;border-radius:8px;font-size:12px;word-break:break-all;">
                    🔗 لینک آنلاین (QR):<br><a href="${url}" target="_blank">${this.escape(url)}</a>
                </div>` : ""}
                <p style="font-size:12px;color:#64748b;">پس از «نهایی‌سازی» گزارش برای مشتری قابل مشاهده می‌شود.</p>`;
        }

        const modal = document.createElement("div");
        modal.id = "svc-wizard-modal";
        modal.className = "svc-srd-overlay";
        modal.innerHTML = `
        <div class="svc-srd-modal" role="dialog" aria-modal="true">
            <div class="svc-srd-modal-head">
                <div>
                    <h3>📄 گزارش فنی SRD</h3>
                    <small>${this.escape(d.report_no || "پیش‌نویس جدید")}</small>
                </div>
                <button type="button" class="svc-srd-close" aria-label="بستن">✕</button>
            </div>
            ${stepNav}
            <form data-ref="wizardForm" class="svc-srd-body">${body}</form>
            <div class="svc-srd-footer">
                <button type="button" class="acc-btn acc-btn--secondary" data-prev ${step <= 1 ? "disabled" : ""}>◀ قبلی</button>
                <span class="svc-srd-footer-hint">${STEPS[step - 1].title}</span>
                <button type="button" class="acc-btn acc-btn--primary" data-next>${step >= 13 ? "💾 ذخیره" : "بعدی ▶"}</button>
            </div>
        </div>`;

        document.body.appendChild(modal);
        document.body.classList.add("svc-srd-open");
        const close = () => {
            modal.remove();
            document.body.classList.remove("svc-srd-open");
            this._wizard = null;
            this._load();
        };
        modal.querySelector(".svc-srd-close").addEventListener("click", close);
        modal.addEventListener("click", e => { if (e.target === modal) close(); });

        modal.querySelectorAll(".svc-srd-type-card input").forEach(inp => {
            inp.addEventListener("change", () => {
                modal.querySelectorAll(".svc-srd-type-card").forEach(c => c.classList.remove("is-selected"));
                inp.closest(".svc-srd-type-card")?.classList.add("is-selected");
            });
        });

        modal.querySelectorAll("[data-goto-step]").forEach(btn => {
            btn.addEventListener("click", async () => {
                const target = +btn.dataset.gotoStep;
                if (!target || target === w.step) return;
                await this._saveStep(step, modal);
                w.visited = w.visited || new Set();
                w.visited.add(step);
                w.visited.add(target);
                w.step = target;
                this._renderWizardModal();
            });
        });

        modal.querySelector("[data-prev]")?.addEventListener("click", async () => {
            await this._saveStep(step, modal);
            if (w.step > 1) {
                w.visited = w.visited || new Set();
                w.visited.add(w.step);
                w.step--;
                w.visited.add(w.step);
                this._renderWizardModal();
            }
        });
        modal.querySelector("[data-next]")?.addEventListener("click", async () => {
            await this._saveStep(step, modal);
            if (w.step < 13) {
                w.visited = w.visited || new Set();
                w.visited.add(w.step);
                w.step++;
                w.visited.add(w.step);
                this._renderWizardModal();
            }
            else close();
        });

        modal.querySelectorAll("[data-add-line]").forEach(btn => {
            btn.addEventListener("click", () => this._addLineRow(modal, btn.dataset.addLine));
        });

        const partSearch = modal.querySelector("#svc-part-search");
        if (partSearch) {
            partSearch.addEventListener("input", () => {
                clearTimeout(this._partT);
                this._partT = setTimeout(() => this._searchParts(modal, partSearch.value.trim()), 300);
            });
        }

        modal.querySelectorAll("[data-preset-cost]").forEach(btn => {
            btn.addEventListener("click", () => this._addLineRow(modal, "extra_costs", {
                desc: btn.dataset.desc, amount: btn.dataset.amount,
            }));
        });

        modal.querySelectorAll("[data-photo]").forEach(inp => {
            inp.addEventListener("change", () => this._handlePhotoPick(modal, inp.dataset.photo, inp.files));
        });
        modal.querySelector("[data-request-cost]")?.addEventListener("click", async () => {
            await this._saveStep(step, modal);
            await this._requestCostApproval(w.data.id);
        });
    }

    async _handlePhotoPick(modal, kind, files) {
        if (!files?.length || !this._wizard?.data) return;
        const field = kind === "before" ? "photos_before" : "photos_after";
        const arr = [...(this._wizard.data[field] || [])];
        for (const f of files) {
            const dataUrl = await new Promise((res, rej) => {
                const r = new FileReader();
                r.onload = () => res(r.result);
                r.onerror = rej;
                r.readAsDataURL(f);
            });
            if (arr.length < 6) arr.push(dataUrl);
        }
        this._wizard.data[field] = arr;
        this._renderWizardModal();
    }

    async _requestCostApproval(id) {
        if (!confirm("برآورد هزینه برای تأیید مشتری ارسال شود؟")) return;
        try {
            const res = await this.api.post(`service/reports/${id}/request-cost-approval`, {});
            alert(`ارسال شد — مبلغ: ${Number(res?.data?.estimate || 0).toLocaleString("fa-IR")} ریال\nمشتری از تب پیگیری ویجت تأیید می‌کند.`);
            await this._load();
        } catch (e) { alert(e.message); }
    }

    async _searchParts(modal, q) {
        const box = modal.querySelector("#svc-part-results");
        if (!box || q.length < 2) { if (box) box.innerHTML = ""; return; }
        try {
            const res = await this.api.get("service/parts/search", { q });
            const rows = res?.data ?? [];
            if (!rows.length) { box.innerHTML = '<small style="color:#94a3b8;">یافت نشد</small>'; return; }
            box.innerHTML = rows.map(p => `
                <div class="svc-part-pick" data-pid="${p.id}" data-name="${this.escape(p.name)}"
                     data-code="${this.escape(p.code)}" style="padding:6px 8px;border-bottom:1px solid #f1f5f9;cursor:pointer;font-size:11px;">
                    ${this.escape(p.name)} <small style="color:#64748b;">(${this.escape(p.code)}) · موجودی: ${p.stock_qty}</small>
                </div>
            `).join("");
            box.querySelectorAll(".svc-part-pick").forEach(el => {
                el.addEventListener("click", () => this._addPartLine(modal, {
                    product_id: +el.dataset.pid,
                    name: el.dataset.name,
                    part_no: el.dataset.code,
                    qty: 1,
                    unit_price: 0,
                }));
            });
        } catch { box.innerHTML = ""; }
    }

    _addPartLine(modal, part) {
        const body = modal.querySelector('[data-line-body="part_lines"]');
        if (!body) return;
        const idx = body.querySelectorAll("tr").length;
        const tr = document.createElement("tr");
        tr.dataset.idx = idx;
        tr.innerHTML = `
            <td><input name="part_lines_name_${idx}" class="acc-input" style="padding:4px;font-size:12px;" value="${this.escape(part.name)}">
                <input type="hidden" name="part_lines_product_id_${idx}" value="${part.product_id}"></td>
            <td><input name="part_lines_part_no_${idx}" class="acc-input" style="padding:4px;font-size:12px;" value="${this.escape(part.part_no)}"></td>
            <td><input name="part_lines_qty_${idx}" class="acc-input" style="padding:4px;font-size:12px;" value="${part.qty}"></td>
            <td><input name="part_lines_unit_price_${idx}" class="acc-input" style="padding:4px;font-size:12px;" value="${part.unit_price}"></td>
            <td><button type="button" data-rm-line>🗑</button></td>`;
        body.appendChild(tr);
    }

    _lineEditor(field, lines, cols, isAmountOnly = false) {
        lines = lines || [];
        const head = cols.map(c => `<th style="width:${c.w}">${c.label}</th>`).join("");
        const rows = lines.map((ln, i) => this._lineRow(field, cols, ln, i, isAmountOnly)).join("");
        return `
            <table class="acc-table" style="font-size:12px;" data-lines="${field}">
                <thead><tr>${head}<th></th></tr></thead>
                <tbody data-line-body="${field}">${rows}</tbody>
            </table>
            <button type="button" class="acc-btn acc-btn--sm" data-add-line="${field}" style="margin-top:8px;">➕ ردیف</button>`;
    }

    _lineRow(field, cols, ln, idx, isAmountOnly) {
        const cells = cols.map(c =>
            `<td><input name="${field}_${c.key}_${idx}" class="acc-input" style="padding:4px;font-size:12px;" value="${this.escape(ln[c.key] ?? "")}"></td>`
        ).join("");
        return `<tr data-idx="${idx}">${cells}<td><button type="button" data-rm-line>🗑</button></td></tr>`;
    }

    _addLineRow(modal, field, preset = null) {
        const body = modal.querySelector(`[data-line-body="${field}"]`);
        const idx = body.querySelectorAll("tr").length;
        const cols = field === "extra_costs"
            ? [{ key: "desc", w: "2fr" }, { key: "amount", w: "120px" }]
            : field === "part_lines"
                ? [{ key: "name" }, { key: "part_no" }, { key: "qty" }, { key: "unit_price" }]
                : field === "material_lines"
                    ? [{ key: "desc" }, { key: "qty" }, { key: "unit" }, { key: "unit_price" }]
                    : [{ key: "desc" }, { key: "qty" }, { key: "unit" }, { key: "unit_price" }];
        const tr = document.createElement("tr");
        tr.dataset.idx = idx;
        tr.innerHTML = cols.map(c =>
            `<td><input name="${field}_${c.key}_${idx}" class="acc-input" style="padding:4px;font-size:12px;" value="${preset && c.key in preset ? this.escape(String(preset[c.key])) : ""}"></td>`
        ).join("") + `<td><button type="button" data-rm-line>🗑</button></td>`;
        body.appendChild(tr);
    }

    async _saveStep(step, modal) {
        const w = this._wizard;
        if (!w?.data?.id) return;
        const form = modal.querySelector("[data-ref=wizardForm]");
        const fd = new FormData(form);
        const payload = {};

        if (step === 1) {
            payload.service_type = form.querySelector('input[name="service_type"]:checked')?.value ?? w.data.service_type;
        } else if (step === 2) {
            ["customer_name", "company", "phone", "email", "address", "case_no", "site_label", "report_date"].forEach(k => {
                if (fd.has(k)) payload[k] = fd.get(k);
            });
        } else if (step === 3) {
            payload.device_snapshot = {
                device_type: fd.get("device_type") ?? "",
                brand: fd.get("brand") ?? "",
                model: fd.get("model") ?? "",
                serial_no: fd.get("serial_no") ?? "",
                capacity: fd.get("capacity") ?? "",
                refrigerant: fd.get("refrigerant") ?? "",
                install_location: fd.get("install_location") ?? "",
                operating_hours: parseInt(fd.get("operating_hours") || "0", 10),
                last_service_date: fd.get("last_service_date") ?? "",
            };
        } else if (step === 4) {
            payload.complaint_tags = [...form.querySelectorAll('input[name="tag"]:checked')].map(i => i.value);
            payload.complaint_text = fd.get("complaint_text") ?? "";
        } else if (step === 5) {
            const tr = {};
            form.querySelectorAll("input[name]").forEach(inp => {
                if (!["diagnosis_result"].includes(inp.name)) tr[inp.name] = inp.value;
            });
            payload.technical_readings = tr;
            payload.diagnosis_result = fd.get("diagnosis_result") ?? "";
            payload.photos_before = w.data.photos_before || [];
            payload.photos_after = w.data.photos_after || [];
        } else if ([6, 7, 8, 9].includes(step)) {
            const map = { 6: "service_lines", 7: "part_lines", 8: "material_lines", 9: "extra_costs" };
            const field = map[step];
            payload[field] = this._collectLines(form, field);
        } else if (step === 10) {
            payload.recommendations = [...form.querySelectorAll('input[name="rec"]:checked')].map(i => i.value);
        } else if (step === 11) {
            const plan = form.querySelector('input[name="pm_plan"]:checked')?.value;
            const pmPrices = this._meta.pm_prices || {};
            payload.pm_offer = plan ? { plan, selected: true, estimated_price: pmPrices[plan] || 0 } : {};
        } else if (step === 12) {
            payload.discount = parseFloat(fd.get("discount") ?? 0);
            payload.tax = parseFloat(fd.get("tax") ?? 0);
            payload.paid = parseFloat(fd.get("paid") ?? 0);
        } else if (step === 13) {
            payload.tech_signature = fd.get("tech_signature") ?? "";
            payload.customer_signature = fd.get("customer_signature") ?? "";
            payload.company_stamp = fd.get("company_stamp") ?? "";
        }

        try {
            const res = await this.api.put(`service/reports/${w.data.id}`, payload);
            w.data = { ...w.data, ...(res?.data ?? payload) };
        } catch (e) {
            console.error(e);
        }
    }

    _collectLines(form, field) {
        const lines = [];
        const idxs = new Set();
        form.querySelectorAll(`[name^="${field}_"]`).forEach(inp => {
            const m = inp.name.match(new RegExp(`${field}_(\\w+)_(\\d+)`));
            if (m) idxs.add(+m[2]);
        });
        [...idxs].sort((a, b) => a - b).forEach(i => {
            const get = k => form.querySelector(`[name="${field}_${k}_${i}"]`)?.value ?? "";
            if (field === "extra_costs") {
                const amount = parseFloat(get("amount")) || 0;
                if (get("desc") || amount) lines.push({ desc: get("desc"), amount });
            } else if (field === "part_lines") {
                const qty = parseFloat(get("qty")) || 0;
                const unit_price = parseFloat(get("unit_price")) || 0;
                const product_id = parseInt(form.querySelector(`[name="${field}_product_id_${i}"]`)?.value ?? "0", 10) || null;
                lines.push({
                    name: get("name"), part_no: get("part_no"), qty, unit_price,
                    total: qty * unit_price, product_id,
                });
            } else {
                const qty = parseFloat(get("qty")) || 0;
                const unit_price = parseFloat(get("unit_price")) || 0;
                lines.push({
                    desc: get("desc") || get("name"),
                    qty, unit: get("unit"), unit_price,
                    total: qty * unit_price,
                });
            }
        });
        return lines;
    }

    async _finalize(id) {
        if (!confirm("گزارش نهایی شود؟ پس از نهایی‌سازی قابل ویرایش نیست.")) return;
        const wh = prompt("شناسه انبار برای کسر قطعات (اختیاری — Enter برای رد کردن):", "");
        try {
            const res = await this.api.post(`service/reports/${id}/finalize`, {
                warehouse_id: wh && wh.trim() ? parseInt(wh, 10) : 0,
            });
            const url = res?.data?.public_url;
            if (url) {
                if (confirm("گزارش نهایی شد. صفحه چاپ/PDF باز شود؟")) window.open(url, "_blank");
            }
            await this._load();
        } catch (e) {
            alert(e.message);
        }
    }

    _fmt(n) {
        return Number(n || 0).toLocaleString("fa-IR") + " ریال";
    }
}
