/**
 * AragShopAdminView — پنل مدیریت فروشگاه عرقیات
 * محصول · کاتالوگ · کوپن · نظرات · hero
 */
const TOKEN_KEY = 'acc_token';

export default class AragShopAdminView {

    constructor() {
        this.root = null;
        this.token = sessionStorage.getItem(TOKEN_KEY) || localStorage.getItem(TOKEN_KEY) || '';
        this.tab = 'products';
        this.products = [];
        this.settings = {};
        this.selectedId = null;
        this.catalog = [];
        this.coupons = [];
        this.reviews = [];
        this.integrations = {};
        this.platformInfo = {};
        this.apiKeys = [];
        this.webhooks = [];
        this.webhookLog = [];
        this.marketers = [];
        this.marketerPayouts = [];
        this._saving = false;
    }

    render(root) {
        this.root = root;
        document.body.classList.add('sp-body');
        this._paint();
        this._load();
    }

    _api() {
        return (window.ACC_SHOP_CFG?.api || '/acc-engine/api.php/acc/v1').replace(/\/$/, '');
    }

    _siteUrl() {
        const base = window.ACC_SHOP_CFG?.baseUrl || '/acc-engine/';
        return base.endsWith('/') ? base : base + '/';
    }

    async _load() {
        try {
            const res = await this._get('/arag/admin/products');
            this.products = res.data || [];
            this.settings = res.settings || {};
            if (!this.selectedId && this.products.length) {
                this.selectedId = this.products[0].id;
            }
            if (this.tab === 'catalog' && this.selectedId) {
                await this._loadCatalog();
            }
            if (this.tab === 'coupons') {
                const c = await this._get('/arag/admin/coupons');
                this.coupons = c.data || [];
            }
            if (this.tab === 'reviews') {
                const r = await this._get('/arag/admin/reviews?status=pending');
                this.reviews = r.data || [];
            }
            if (this.tab === 'integrations') {
                const ig = await this._get('/arag/admin/integrations');
                this.integrations = ig.data || {};
            }
            if (this.tab === 'branding') {
                const b = await this._get('/arag/admin/branding');
                this.settings = { ...this.settings, ...(b.data || {}) };
            }
            if (this.tab === 'developer') {
                const [pi, keys, wh, log] = await Promise.all([
                    this._get('/arag/admin/platform-info'),
                    this._get('/arag/admin/developer/keys'),
                    this._get('/arag/admin/developer/webhooks'),
                    this._get('/arag/admin/developer/webhook-log'),
                ]);
                this.platformInfo = pi || {};
                this.apiKeys = keys.data || [];
                this.webhooks = wh.data || [];
                this.webhookLog = log.data || [];
            }
            if (this.tab === 'marketers') {
                const [m, p] = await Promise.all([
                    this._get('/arag/admin/marketers'),
                    this._get('/arag/admin/marketer-payouts'),
                ]);
                this.marketers = m.data || [];
                this.marketerPayouts = p.data || [];
            }
            this._paint();
        } catch (e) {
            if (!this.token) this._paintDenied();
            else this._paintDenied(e.message);
        }
    }

    async _loadCatalog() {
        if (!this.selectedId) return;
        const res = await this._get(`/arag/admin/families/${this.selectedId}/catalog`);
        this.catalog = res.data || [];
    }

    _paintDenied(msg = '') {
        const site = this._siteUrl();
        this.root.innerHTML = `
        <div class="sp-admin">
            <div class="sp-admin__denied">
                <h2 class="sp-serif">دسترسی مدیریت فروشگاه</h2>
                <p class="sp-note">${msg || 'برای ورود به پنل، ابتدا با حساب مدیر در پورتال ACC وارد شوید.'}</p>
                <p style="margin-top:24px">
                    <a href="${site}">ورود به پورتال</a>
                    &nbsp;·&nbsp;
                    <a href="${site}shop.php">بازگشت به فروشگاه</a>
                </p>
            </div>
        </div>`;
    }

    _paint() {
        const site = this._siteUrl();
        const sel = this.products.find(p => p.id === this.selectedId);
        const tabs = [
            ['products', 'محصولات'],
            ['catalog', 'کاتالوگ (مدل/قیمت)'],
            ['hero', 'صفحه اصلی'],
            ['coupons', 'کوپن‌ها'],
            ['reviews', 'نظرات'],
            ['integrations', 'یکپارچه‌سازی'],
            ['branding', 'برند و وایت‌لیبل'],
            ['marketers', 'بازاریاب‌ها'],
            ['developer', 'API / Webhook'],
        ];

        this.root.innerHTML = `
        <div class="sp-admin">
            <div class="sp-admin__head">
                <div>
                    <h1 class="sp-serif" style="margin:0;font-size:1.5rem">مدیریت فروشگاه</h1>
                    <p class="sp-note" style="margin:6px 0 0">محتوا · قیمت‌گذاری · تخفیف · نظرات</p>
                </div>
                <div>
                    <a href="${site}shop.php" class="sp-btn sp-btn--ghost" style="text-decoration:none">مشاهده فروشگاه</a>
                    <a href="${site}shop-erp.php" class="sp-btn sp-btn--ghost" style="text-decoration:none;margin-right:8px">ERP</a>
                </div>
            </div>
            <div class="sp-admin__tabs">
                ${tabs.map(([k, l]) => `<button class="sp-admin__tab ${this.tab === k ? 'sp-admin__tab--on' : ''}" data-tab="${k}" type="button">${l}</button>`).join('')}
            </div>
            ${this.tab === 'products' ? this._productsHtml(sel) : ''}
            ${this.tab === 'catalog' ? this._catalogHtml(sel) : ''}
            ${this.tab === 'hero' ? this._heroHtml() : ''}
            ${this.tab === 'coupons' ? this._couponsHtml() : ''}
            ${this.tab === 'reviews' ? this._reviewsHtml() : ''}
            ${this.tab === 'integrations' ? this._integrationsHtml() : ''}
            ${this.tab === 'branding' ? this._brandingHtml() : ''}
            ${this.tab === 'marketers' ? this._marketersHtml() : ''}
            ${this.tab === 'developer' ? this._developerHtml() : ''}
        </div>`;
        this._bind();
    }

    _marketersHtml() {
        const rows = (this.marketers || []).map(m => `
            <tr>
                <td>${this._esc(m.display_name)}<br><small dir="ltr">${this._esc(m.phone)}</small></td>
                <td>${this._esc(m.marketer_code)}</td>
                <td>${this._esc(m.status)}</td>
                <td>${Number(m.balance_payable || 0).toLocaleString('fa-IR')}</td>
                <td>${Number(m.credit_balance || 0).toLocaleString('fa-IR')} / ${Number(m.credit_limit || 0).toLocaleString('fa-IR')}</td>
                <td style="white-space:nowrap">
                    ${m.status === 'pending' ? `<button type="button" class="sp-btn" data-mkt-status="${m.id}" data-status="active">تایید</button>
                    <button type="button" class="sp-btn sp-btn--ghost" data-mkt-status="${m.id}" data-status="rejected">رد</button>` : ''}
                    ${m.status === 'active' ? `<button type="button" class="sp-btn sp-btn--ghost" data-mkt-status="${m.id}" data-status="suspended">تعلیق</button>` : ''}
                    ${m.status === 'suspended' ? `<button type="button" class="sp-btn" data-mkt-status="${m.id}" data-status="active">فعال‌سازی</button>` : ''}
                    <button type="button" class="sp-btn sp-btn--ghost" data-mkt-credit="${m.id}">شارژ اعتبار</button>
                    <button type="button" class="sp-btn sp-btn--ghost" data-mkt-limit="${m.id}">سقف اعتبار</button>
                </td>
            </tr>`).join('');
        const payouts = (this.marketerPayouts || []).map(p => `
            <tr>
                <td>${this._esc(p.display_name)} · ${this._esc(p.marketer_code)}</td>
                <td>${Number(p.amount || 0).toLocaleString('fa-IR')}</td>
                <td>${this._esc(p.status)}</td>
                <td>${this._esc((p.created_at || '').slice(0, 16))}</td>
                <td>${p.status === 'requested' ? `
                    <button type="button" class="sp-btn" data-mkt-pay="${p.id}" data-status="paid">پرداخت شد</button>
                    <button type="button" class="sp-btn sp-btn--ghost" data-mkt-pay="${p.id}" data-status="rejected">رد</button>` : '—'}</td>
            </tr>`).join('');
        return `
        <div class="sp-admin__section">
            <h2 class="sp-serif" style="font-size:1.2rem">بازاریاب‌های فروشگاه</h2>
            <p class="sp-note">تایید ثبت‌نام · شارژ اعتبار · تسویه ۷٪ پورسانت · آدرس پنل: <a href="${this._siteUrl()}shop-marketer.php">shop-marketer.php</a></p>
            <table class="sp-admin__table">
                <thead><tr><th>بازاریاب</th><th>کد</th><th>وضعیت</th><th>قابل تسویه</th><th>اعتبار</th><th>عملیات</th></tr></thead>
                <tbody>${rows || '<tr><td colspan="6">بازاریابی ثبت نشده</td></tr>'}</tbody>
            </table>
            <h3 class="sp-serif" style="margin-top:28px;font-size:1.1rem">درخواست‌های تسویه</h3>
            <table class="sp-admin__table">
                <thead><tr><th>بازاریاب</th><th>مبلغ</th><th>وضعیت</th><th>تاریخ</th><th></th></tr></thead>
                <tbody>${payouts || '<tr><td colspan="5">درخواستی نیست</td></tr>'}</tbody>
            </table>
        </div>`;
    }

    _productsHtml(sel) {
        const list = this.products.map(p => `
            <button type="button" class="sp-admin__item ${p.id === this.selectedId ? 'sp-admin__item--on' : ''}" data-pid="${p.id}">
                ${this._esc(p.name)}
                <small>${this._esc(p.slug)}</small>
            </button>`).join('');
        if (!sel) return `<p class="sp-note">محصولی یافت نشد.</p>`;
        let gallery = [];
        try { gallery = JSON.parse(sel.gallery_json || '[]'); } catch { gallery = []; }
        const galleryImgs = gallery.map((url, i) => `
            <div style="position:relative">
                <img src="${this._esc(url)}" alt="">
                <button type="button" data-rmg="${i}" style="position:absolute;top:2px;left:2px;background:#fff;border:1px solid #ccc;font-size:10px;cursor:pointer">×</button>
            </div>`).join('');
        return `
        <div class="sp-admin__grid">
            <div class="sp-admin__list">${list}</div>
            <form class="sp-admin__panel" id="sp-admin-product-form">
                <h2 class="sp-serif" style="margin:0 0 20px">${this._esc(sel.name)}</h2>
                ${sel.bottle_image_url ? `<img class="sp-admin__preview" src="${this._esc(sel.bottle_image_url)}" alt="">` : ''}
                <div class="sp-admin__upload-row">
                    <label class="sp-btn sp-btn--ghost" style="cursor:pointer">آپلود تصویر بطری
                        <input type="file" accept="image/*" data-upload="bottle" hidden></label>
                </div>
                <div class="sp-field"><label>آدرس تصویر بطری</label>
                    <input name="bottle_image_url" value="${this._esc(sel.bottle_image_url)}"></div>
                <div class="sp-field"><label>تگ‌لاین</label>
                    <input name="tagline" value="${this._esc(sel.tagline)}"></div>
                <div class="sp-field"><label>توضیح کوتاه</label>
                    <textarea name="description_short" rows="2">${this._esc(sel.description_short)}</textarea></div>
                <div class="sp-field"><label>توضیح کامل (PDP)</label>
                    <textarea name="description_long" rows="6">${this._esc(sel.description_long)}</textarea></div>
                <div class="sp-field"><label>گالری</label>
                    <div class="sp-admin__gallery" id="sp-admin-gallery">${galleryImgs}</div>
                    <div class="sp-admin__upload-row">
                        <label class="sp-btn sp-btn--ghost" style="cursor:pointer;font-size:12px">افزودن تصویر
                            <input type="file" accept="image/*" data-upload="gallery" hidden></label>
                        <input type="text" id="sp-gallery-url" placeholder="یا URL" style="flex:1;min-width:180px;padding:8px;border:1px solid var(--ax-line)">
                        <button type="button" class="sp-btn sp-btn--ghost" id="sp-gallery-add" style="font-size:12px">افزودن</button>
                    </div>
                </div>
                <button class="sp-btn" type="submit" ${this._saving ? 'disabled' : ''}>ذخیره محصول</button>
                <div class="sp-msg" id="sp-admin-msg" hidden></div>
            </form>
        </div>`;
    }

    _catalogHtml(sel) {
        const list = this.products.map(p => `
            <button type="button" class="sp-admin__item ${p.id === this.selectedId ? 'sp-admin__item--on' : ''}" data-pid="${p.id}">
                ${this._esc(p.name)}</button>`).join('');
        const variants = this.catalog.map(v => `
            <div class="sp-admin__variant" style="border:1px solid var(--ax-line);border-radius:12px;padding:16px;margin-bottom:16px">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
                    <strong>${this._esc(v.name)}</strong>
                    <button type="button" class="sp-btn sp-btn--ghost sp-btn--xs" data-del-variant="${v.id}">حذف مدل</button>
                </div>
                <div class="sp-field"><label>نام مدل</label><input data-vfield="name" data-vid="${v.id}" value="${this._esc(v.name)}"></div>
                <table style="width:100%;font-size:13px;margin-top:12px">
                    <thead><tr><th>بسته</th><th>حجم</th><th>قیمت</th><th></th></tr></thead>
                    <tbody>
                    ${(v.packages || []).map(p => `
                        <tr>
                            <td><input data-pfield="label" data-pid="${p.id}" value="${this._esc(p.label)}" style="width:100%"></td>
                            <td><input data-pfield="volume" data-pid="${p.id}" value="${this._esc(p.volume)}" style="width:80px"></td>
                            <td><input data-pfield="price" data-pid="${p.id}" value="${p.price}" dir="ltr" style="width:100px"></td>
                            <td><button type="button" data-del-pkg="${p.id}" style="border:none;background:none;cursor:pointer;color:#ef4444">×</button></td>
                        </tr>`).join('')}
                    </tbody>
                </table>
                <button type="button" class="sp-btn sp-btn--ghost sp-btn--xs" data-add-pkg="${v.id}" style="margin-top:8px">+ بسته جدید</button>
                <button type="button" class="sp-btn sp-btn--xs" data-save-variant="${v.id}" style="margin-top:8px;margin-right:8px">ذخیره مدل</button>
            </div>`).join('') || '<p class="sp-note">مدلی ثبت نشده — مدل جدید اضافه کنید.</p>';

        return `
        <div class="sp-admin__grid">
            <div class="sp-admin__list">${list}</div>
            <div class="sp-admin__panel">
                <h2 class="sp-serif">${sel ? this._esc(sel.name) : 'کاتالوگ'}</h2>
                ${variants}
                <form id="sp-new-variant-form" style="margin-top:24px;padding-top:16px;border-top:1px dashed var(--ax-line)">
                    <h3 style="font-size:14px;margin:0 0 12px">مدل جدید</h3>
                    <div class="sp-field"><label>نام</label><input name="name" required placeholder="مثلاً درجه یک"></div>
                    <button class="sp-btn sp-btn--ghost" type="submit">افزودن مدل</button>
                </form>
                <div class="sp-msg" id="sp-admin-msg" hidden></div>
            </div>
        </div>`;
    }

    _couponsHtml() {
        const rows = this.coupons.map(c => `
            <tr>
                <td dir="ltr"><strong>${this._esc(c.code)}</strong></td>
                <td>${c.discount_pct}%</td>
                <td>${(+c.min_order).toLocaleString('fa-IR')}</td>
                <td>${c.used_count}${c.max_uses ? '/' + c.max_uses : ''}</td>
                <td>${c.is_active == 1 ? '✅' : '—'}</td>
                <td><button type="button" data-del-coupon="${c.id}" style="border:none;background:none;cursor:pointer;color:#ef4444">حذف</button></td>
            </tr>`).join('');
        return `
        <div class="sp-admin__panel">
            <h2 class="sp-serif">کدهای تخفیف</h2>
            <table style="width:100%;font-size:13px;margin:16px 0">
                <thead><tr><th>کد</th><th>درصد</th><th>حداقل سفارش</th><th>استفاده</th><th>فعال</th><th></th></tr></thead>
                <tbody>${rows || '<tr><td colspan="6">کوپنی نیست</td></tr>'}</tbody>
            </table>
            <form id="sp-new-coupon-form" style="max-width:480px">
                <div class="sp-field"><label>کد</label><input name="code" required dir="ltr" placeholder="SUMMER25"></div>
                <div class="sp-field"><label>درصد تخفیف</label><input name="discount_pct" type="number" min="0" max="100" value="10"></div>
                <div class="sp-field"><label>حداقل سفارش (تومان)</label><input name="min_order" type="number" min="0" value="0"></div>
                <button class="sp-btn" type="submit">افزودن کوپن</button>
            </form>
            <div class="sp-msg" id="sp-admin-msg" hidden></div>
        </div>`;
    }

    _integrationsHtml() {
        const ig = this.integrations;
        return `
        <form class="sp-admin__panel" id="sp-admin-integrations-form" style="max-width:720px">
            <h2 class="sp-serif">یکپارچه‌سازی — SMS · زرین‌پال · AI</h2>

            <h3 style="margin:24px 0 12px;font-size:14px">📱 پیامک OTP</h3>
            <div class="sp-field"><label>
                <input type="checkbox" name="otp_demo" ${ig.otp_demo !== false ? 'checked' : ''}> حالت دمو (نمایش کد در API — بدون SMS واقعی)
            </label></div>
            <div class="sp-field"><label>سرویس SMS</label>
                <select name="sms_provider">
                    <option value="log" ${ig.sms_provider === 'log' ? 'selected' : ''}>لاگ / دمو</option>
                    <option value="kavenegar" ${ig.sms_provider === 'kavenegar' ? 'selected' : ''}>کاوه‌نگار</option>
                    <option value="melipayamak" ${ig.sms_provider === 'melipayamak' ? 'selected' : ''}>ملی‌پیامک</option>
                    <option value="ghasedak" ${ig.sms_provider === 'ghasedak' ? 'selected' : ''}>قاصدک</option>
                </select>
            </div>
            <div class="sp-field"><label>API Key ${ig.sms_has_key ? '✅ (ذخیره شده)' : ''}</label>
                <input name="sms_api_key" type="password" placeholder="برای تغییر وارد کنید" dir="ltr" autocomplete="new-password"></div>
            <div class="sp-field"><label>شماره فرستنده / خط</label>
                <input name="sms_sender" value="${this._esc(ig.sms_sender)}" dir="ltr"></div>
            <div class="sp-field"><label>قالب OTP کاوه‌نگار (lookup)</label>
                <input name="sms_otp_template" value="${this._esc(ig.sms_otp_template || 'verify')}" dir="ltr"></div>

            <h3 style="margin:24px 0 12px;font-size:14px">💳 زرین‌پال</h3>
            <div class="sp-field"><label>
                <input type="checkbox" name="zarinpal_sandbox" ${ig.zarinpal_sandbox !== false ? 'checked' : ''}> حالت Sandbox (تست)
            </label></div>
            <p class="sp-note">برای production تیک Sandbox را بردارید و Merchant ID واقعی وارد کنید.</p>
            <div class="sp-field"><label>Merchant ID</label>
                <input name="zarinpal_merchant" value="${this._esc(ig.zarinpal_merchant)}" dir="ltr"></div>

            <h3 style="margin:24px 0 12px;font-size:14px">🤖 مشاور AI فروش</h3>
            <div class="sp-field"><label>
                <input type="checkbox" name="ai_enabled" ${ig.ai_enabled !== false ? 'checked' : ''}> فعال
            </label></div>
            <div class="sp-field"><label>API Key (OpenAI / DeepSeek / LM Studio) ${ig.ai_has_key ? '✅' : ''}</label>
                <input name="ai_api_key" type="password" placeholder="sk-..." dir="ltr" autocomplete="new-password"></div>
            <div class="sp-field"><label>Base URL</label>
                <input name="ai_base_url" value="${this._esc(ig.ai_base_url || 'https://api.openai.com/v1')}" dir="ltr"></div>
            <div class="sp-field"><label>Model</label>
                <input name="ai_model" value="${this._esc(ig.ai_model || 'gpt-4o-mini')}" dir="ltr"
                    placeholder="gpt-4o-mini | deepseek-chat"></div>
            <p class="sp-note">بدون API Key، موتور قانون‌محور از کاتالوگ پاسخ می‌دهد.</p>

            <button class="sp-btn" type="submit">ذخیره تنظیمات</button>
            <div class="sp-msg" id="sp-admin-msg" hidden></div>
        </form>`;
    }

    _reviewsHtml() {
        const rows = this.reviews.map(r => `
            <div class="sp-admin__review" style="border:1px solid var(--ax-line);border-radius:12px;padding:16px;margin-bottom:12px">
                <div style="display:flex;justify-content:space-between">
                    <strong>${this._esc(r.author_name)} — ${this._esc(r.family_name || '')}</strong>
                    <span>${'★'.repeat(+r.rating || 0)}</span>
                </div>
                <p style="margin:12px 0;font-size:14px">${this._esc(r.body)}</p>
                <div>
                    <button type="button" class="sp-btn sp-btn--xs" data-approve-review="${r.id}">تأیید</button>
                    <button type="button" class="sp-btn sp-btn--ghost sp-btn--xs" data-reject-review="${r.id}">رد</button>
                </div>
            </div>`).join('');
        return `
        <div class="sp-admin__panel">
            <h2 class="sp-serif">نظرات در انتظار تأیید</h2>
            ${rows || '<p class="sp-note">نظر جدیدی در صف نیست.</p>'}
            <div class="sp-msg" id="sp-admin-msg" hidden></div>
        </div>`;
    }

    _heroHtml() {
        const s = this.settings;
        const ann = (s.announcements || []).join('\n');
        return `
        <form class="sp-admin__panel" id="sp-admin-hero-form" style="max-width:640px">
            <h2 class="sp-serif" style="margin:0 0 24px">تنظیمات صفحه اصلی</h2>
            <div class="sp-field"><label>خط بالای عنوان</label>
                <input name="hero_eyebrow" value="${this._esc(s.hero_eyebrow)}"></div>
            <div class="sp-field"><label>عنوان اصلی</label>
                <input name="hero_title" value="${this._esc(s.hero_title)}"></div>
            <div class="sp-field"><label>زیرعنوان</label>
                <textarea name="hero_subtitle" rows="3">${this._esc(s.hero_subtitle)}</textarea></div>
            <div class="sp-field"><label>اعلان‌های نوار بالا (هر خط یک پیام)</label>
                <textarea name="announcements_text" rows="4" placeholder="هر خط یک پیام">${this._esc(ann)}</textarea></div>
            <div class="sp-field"><label>
                <input type="checkbox" name="auto_approve_reviews" ${s.auto_approve_reviews !== false ? 'checked' : ''}> تأیید خودکار نظرات
            </label></div>
            <div class="sp-field"><label>داستان برند</label>
                <textarea name="brand_story" rows="3">${this._esc(s.brand_story)}</textarea></div>
            ${s.hero_poster_url ? `<img class="sp-admin__preview" src="${this._esc(s.hero_poster_url)}" alt="" style="width:100%;max-width:400px">` : ''}
            <div class="sp-admin__upload-row">
                <label class="sp-btn sp-btn--ghost" style="cursor:pointer">آپلود پوستر
                    <input type="file" accept="image/*" data-upload="poster" hidden></label>
                <label class="sp-btn sp-btn--ghost" style="cursor:pointer">آپلود ویدیو
                    <input type="file" accept="video/*" data-upload="video" hidden></label>
            </div>
            <div class="sp-field"><label>URL ویدیو hero</label>
                <input name="hero_video_url" value="${this._esc(s.hero_video_url)}" dir="ltr"></div>
            <div class="sp-field"><label>URL پوستر</label>
                <input name="hero_poster_url" value="${this._esc(s.hero_poster_url)}" dir="ltr"></div>
            <button class="sp-btn" type="submit" ${this._saving ? 'disabled' : ''}>ذخیره تنظیمات</button>
            <div class="sp-msg" id="sp-admin-msg" hidden></div>
        </form>`;
    }

    _bind() {
        this.root.querySelectorAll('[data-tab]').forEach(btn => {
            btn.addEventListener('click', async () => {
                this.tab = btn.dataset.tab;
                await this._load();
            });
        });
        this.root.querySelectorAll('[data-mkt-status]').forEach(btn => {
            btn.addEventListener('click', async () => {
                const id = btn.getAttribute('data-mkt-status');
                const status = btn.getAttribute('data-status');
                await this._put(`/arag/admin/marketers/${id}/status`, { status });
                await this._load();
            });
        });
        this.root.querySelectorAll('[data-mkt-credit]').forEach(btn => {
            btn.addEventListener('click', async () => {
                const id = btn.getAttribute('data-mkt-credit');
                const amount = prompt('مبلغ شارژ اعتبار (تومان):');
                if (!amount) return;
                await this._post(`/arag/admin/marketers/${id}/credit`, { amount: +amount });
                await this._load();
            });
        });
        this.root.querySelectorAll('[data-mkt-limit]').forEach(btn => {
            btn.addEventListener('click', async () => {
                const id = btn.getAttribute('data-mkt-limit');
                const limit = prompt('سقف اعتبار جدید (تومان):');
                if (!limit) return;
                await this._put(`/arag/admin/marketers/${id}/credit-limit`, { limit: +limit });
                await this._load();
            });
        });
        this.root.querySelectorAll('[data-mkt-pay]').forEach(btn => {
            btn.addEventListener('click', async () => {
                const id = btn.getAttribute('data-mkt-pay');
                const status = btn.getAttribute('data-status');
                await this._put(`/arag/admin/marketer-payouts/${id}`, { status });
                await this._load();
            });
        });
        this.root.querySelectorAll('[data-pid]').forEach(btn => {
            btn.addEventListener('click', async () => {
                this.selectedId = +btn.dataset.pid;
                if (this.tab === 'catalog') await this._loadCatalog();
                this._paint();
            });
        });
        this.root.querySelector('#sp-admin-product-form')?.addEventListener('submit', e => this._saveProduct(e));
        this.root.querySelector('#sp-admin-hero-form')?.addEventListener('submit', e => this._saveHero(e));
        this.root.querySelector('#sp-new-variant-form')?.addEventListener('submit', e => this._addVariant(e));
        this.root.querySelector('#sp-new-coupon-form')?.addEventListener('submit', e => this._addCoupon(e));
        this.root.querySelector('#sp-admin-integrations-form')?.addEventListener('submit', e => this._saveIntegrations(e));
        this.root.querySelectorAll('[data-upload]').forEach(inp => {
            inp.addEventListener('change', () => this._handleUpload(inp));
        });
        this.root.querySelector('#sp-gallery-add')?.addEventListener('click', () => {
            const url = this.root.querySelector('#sp-gallery-url')?.value?.trim();
            if (!url) return;
            const sel = this.products.find(p => p.id === this.selectedId);
            if (!sel) return;
            let gallery = [];
            try { gallery = JSON.parse(sel.gallery_json || '[]'); } catch { gallery = []; }
            gallery.push(url);
            sel.gallery_json = JSON.stringify(gallery);
            this._paint();
        });
        this.root.querySelectorAll('[data-rmg]').forEach(btn => {
            btn.addEventListener('click', () => {
                const sel = this.products.find(p => p.id === this.selectedId);
                if (!sel) return;
                let gallery = [];
                try { gallery = JSON.parse(sel.gallery_json || '[]'); } catch { gallery = []; }
                gallery.splice(+btn.dataset.rmg, 1);
                sel.gallery_json = JSON.stringify(gallery);
                this._paint();
            });
        });
        this.root.querySelectorAll('[data-save-variant]').forEach(btn => {
            btn.addEventListener('click', () => this._saveVariant(+btn.dataset.saveVariant));
        });
        this.root.querySelectorAll('[data-del-variant]').forEach(btn => {
            btn.addEventListener('click', () => this._deleteVariant(+btn.dataset.delVariant));
        });
        this.root.querySelectorAll('[data-add-pkg]').forEach(btn => {
            btn.addEventListener('click', () => this._addPackage(+btn.dataset.addPkg));
        });
        this.root.querySelectorAll('[data-del-pkg]').forEach(btn => {
            btn.addEventListener('click', () => this._deletePackage(+btn.dataset.delPkg));
        });
        this.root.querySelectorAll('[data-del-coupon]').forEach(btn => {
            btn.addEventListener('click', () => this._deleteCoupon(+btn.dataset.delCoupon));
        });
        this.root.querySelectorAll('[data-approve-review]').forEach(btn => {
            btn.addEventListener('click', () => this._moderateReview(+btn.dataset.approveReview, true));
        });
        this.root.querySelectorAll('[data-reject-review]').forEach(btn => {
            btn.addEventListener('click', () => this._moderateReview(+btn.dataset.rejectReview, false));
        });
        this.root.querySelector('#sp-brand-form')?.addEventListener('submit', e => this._saveBranding(e));
        this.root.querySelector('#sp-key-form')?.addEventListener('submit', e => this._createKey(e));
        this.root.querySelector('#sp-wh-form')?.addEventListener('submit', e => this._createWebhook(e));
        this.root.querySelectorAll('[data-revoke-key]').forEach(btn => {
            btn.addEventListener('click', () => this._revokeKey(+btn.dataset.revokeKey));
        });
        this.root.querySelectorAll('[data-test-wh]').forEach(btn => {
            btn.addEventListener('click', () => this._testWebhook(+btn.dataset.testWh));
        });
        this.root.querySelectorAll('[data-del-wh]').forEach(btn => {
            btn.addEventListener('click', () => this._deleteWebhook(+btn.dataset.delWh));
        });
    }

    async _saveVariant(vid) {
        const body = { name: this.root.querySelector(`[data-vfield=name][data-vid="${vid}"]`)?.value };
        await this._put(`/arag/admin/variants/${vid}`, body);
        for (const inp of this.root.querySelectorAll(`[data-pid][data-pfield]`)) {
            const pid = +inp.dataset.pid;
            const field = inp.dataset.pfield;
            await this._put(`/arag/admin/packages/${pid}`, { [field]: inp.value });
        }
        await this._loadCatalog();
        this._paint();
        this._msg('کاتالوگ ذخیره شد');
    }

    async _addVariant(e) {
        e.preventDefault();
        const fd = new FormData(e.target);
        await this._post('/arag/admin/variants', { family_id: this.selectedId, name: fd.get('name') });
        await this._loadCatalog();
        this._paint();
    }

    async _deleteVariant(id) {
        if (!confirm('مدل و بسته‌هایش حذف شوند؟')) return;
        await fetch(this._api() + `/arag/admin/variants/${id}`, {
            method: 'DELETE',
            headers: { Authorization: `Bearer ${this.token}` },
        });
        await this._loadCatalog();
        this._paint();
    }

    async _addPackage(variantId) {
        await this._post('/arag/admin/packages', {
            variant_id: variantId,
            label: 'بسته جدید',
            volume: '250ml',
            price: 0,
        });
        await this._loadCatalog();
        this._paint();
    }

    async _deletePackage(id) {
        await fetch(this._api() + `/arag/admin/packages/${id}`, {
            method: 'DELETE',
            headers: { Authorization: `Bearer ${this.token}` },
        });
        await this._loadCatalog();
        this._paint();
    }

    async _saveIntegrations(e) {
        e.preventDefault();
        const fd = new FormData(e.target);
        const body = {
            otp_demo: !!fd.get('otp_demo'),
            sms_provider: fd.get('sms_provider'),
            sms_api_key: fd.get('sms_api_key'),
            sms_sender: fd.get('sms_sender'),
            sms_otp_template: fd.get('sms_otp_template'),
            zarinpal_sandbox: !!fd.get('zarinpal_sandbox'),
            zarinpal_merchant: fd.get('zarinpal_merchant'),
            ai_enabled: !!fd.get('ai_enabled'),
            ai_api_key: fd.get('ai_api_key'),
            ai_base_url: fd.get('ai_base_url'),
            ai_model: fd.get('ai_model'),
        };
        this._saving = true;
        try {
            const res = await this._put('/arag/admin/integrations', body);
            this.integrations = res.data || body;
            this._msg('تنظیمات یکپارچه‌سازی ذخیره شد');
        } catch (err) {
            this._msg(err.message, false);
        }
        this._saving = false;
    }

    async _addCoupon(e) {
        e.preventDefault();
        const fd = new FormData(e.target);
        await this._post('/arag/admin/coupons', Object.fromEntries(fd.entries()));
        await this._load();
    }

    async _deleteCoupon(id) {
        await fetch(this._api() + `/arag/admin/coupons/${id}`, {
            method: 'DELETE',
            headers: { Authorization: `Bearer ${this.token}` },
        });
        await this._load();
    }

    async _moderateReview(id, approve) {
        await this._post(`/arag/admin/reviews/${id}/moderate`, { approve });
        await this._load();
    }

    _msg(text, ok = true) {
        const msg = this.root.querySelector('#sp-admin-msg');
        if (msg) {
            msg.hidden = false;
            msg.textContent = text;
            msg.className = ok ? 'sp-msg sp-msg--ok' : 'sp-msg sp-msg--err';
        }
    }

    async _handleUpload(input) {
        const file = input.files?.[0];
        if (!file) return;
        const kind = input.dataset.upload;
        try {
            const url = await this._uploadFile(file);
            if (kind === 'bottle') {
                const inp = this.root.querySelector('[name=bottle_image_url]');
                if (inp) inp.value = url;
            } else if (kind === 'gallery') {
                const sel = this.products.find(p => p.id === this.selectedId);
                if (sel) {
                    let gallery = [];
                    try { gallery = JSON.parse(sel.gallery_json || '[]'); } catch { gallery = []; }
                    gallery.push(url);
                    sel.gallery_json = JSON.stringify(gallery);
                    this._paint();
                }
            } else if (kind === 'poster') {
                const inp = this.root.querySelector('[name=hero_poster_url]');
                if (inp) inp.value = url;
            } else if (kind === 'video') {
                const inp = this.root.querySelector('[name=hero_video_url]');
                if (inp) inp.value = url;
            }
            this._msg('فایل آپلود شد');
        } catch (e) {
            this._msg(e.message, false);
        }
        input.value = '';
    }

    async _uploadFile(file) {
        const fd = new FormData();
        fd.append('file', file);
        const headers = {};
        if (this.token) headers.Authorization = `Bearer ${this.token}`;
        const r = await fetch(this._api() + '/arag/admin/upload', { method: 'POST', headers, body: fd });
        const j = await r.json().catch(() => ({}));
        if (!r.ok || !j.success) throw new Error(j.message || 'آپلود ناموفق');
        return j.data?.url || j.url;
    }

    async _saveProduct(e) {
        e.preventDefault();
        const fd = new FormData(e.target);
        const sel = this.products.find(p => p.id === this.selectedId);
        let gallery = [];
        try { gallery = JSON.parse(sel?.gallery_json || '[]'); } catch { gallery = []; }
        this._saving = true;
        try {
            await this._put(`/arag/admin/products/${this.selectedId}`, {
                tagline: fd.get('tagline'),
                description_short: fd.get('description_short'),
                description_long: fd.get('description_long'),
                bottle_image_url: fd.get('bottle_image_url'),
                gallery,
            });
            this._msg('محصول ذخیره شد');
            await this._load();
        } catch (err) {
            this._msg(err.message, false);
        }
        this._saving = false;
    }

    async _saveHero(e) {
        e.preventDefault();
        const fd = new FormData(e.target);
        const body = Object.fromEntries(fd.entries());
        const annText = body.announcements_text || '';
        delete body.announcements_text;
        body.announcements = annText.split('\n').map(s => s.trim()).filter(Boolean);
        body.auto_approve_reviews = !!this.root.querySelector('[name=auto_approve_reviews]')?.checked;
        this._saving = true;
        try {
            const res = await this._put('/arag/admin/settings', body);
            this.settings = res.data || body;
            this._msg('تنظیمات ذخیره شد');
        } catch (err) {
            this._msg(err.message, false);
        }
        this._saving = false;
    }

    async _get(path) {
        const headers = {};
        if (this.token) headers.Authorization = `Bearer ${this.token}`;
        const r = await fetch(this._api() + path, { headers });
        const j = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(j.message || `HTTP ${r.status}`);
        return j;
    }

    async _put(path, data) {
        const headers = { 'Content-Type': 'application/json' };
        if (this.token) headers.Authorization = `Bearer ${this.token}`;
        const r = await fetch(this._api() + path, { method: 'PUT', headers, body: JSON.stringify(data) });
        const j = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(j.message || `HTTP ${r.status}`);
        return j;
    }

    async _post(path, data) {
        const headers = { 'Content-Type': 'application/json' };
        if (this.token) headers.Authorization = `Bearer ${this.token}`;
        const r = await fetch(this._api() + path, { method: 'POST', headers, body: JSON.stringify(data) });
        const j = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(j.message || `HTTP ${r.status}`);
        return j;
    }

    async _delete(path) {
        const headers = {};
        if (this.token) headers.Authorization = `Bearer ${this.token}`;
        const r = await fetch(this._api() + path, { method: 'DELETE', headers });
        const j = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(j.message || `HTTP ${r.status}`);
        return j;
    }

    async _saveBranding(e) {
        e.preventDefault();
        const body = Object.fromEntries(new FormData(e.target).entries());
        try {
            const res = await this._put('/arag/admin/branding', body);
            this.settings = res.data || body;
            this._msg('برند ذخیره شد');
        } catch (err) { this._msg(err.message, false); }
    }

    async _createKey(e) {
        e.preventDefault();
        const label = e.target.label?.value || 'Default';
        try {
            const res = await this._post('/arag/admin/developer/keys', { label });
            const el = this.root.querySelector('#sp-key-once');
            if (el && res.api_key) {
                el.hidden = false;
                el.innerHTML = `<strong>کلید (یک‌بار):</strong> <code dir="ltr">${this._esc(res.api_key)}</code>`;
            }
            this._msg(res.message || 'کلید ایجاد شد');
            this.tab = 'developer';
            await this._load();
        } catch (err) { this._msg(err.message, false); }
    }

    async _revokeKey(id) {
        try {
            await this._delete(`/arag/admin/developer/keys/${id}`);
            this.tab = 'developer';
            await this._load();
        } catch (err) { this._msg(err.message, false); }
    }

    async _createWebhook(e) {
        e.preventDefault();
        const fd = new FormData(e.target);
        const events = [...e.target.querySelectorAll('[name=wh_event]:checked')].map(x => x.value);
        try {
            const res = await this._post('/arag/admin/developer/webhooks', {
                label: fd.get('label'),
                url: fd.get('url'),
                events,
            });
            if (res.secret) alert('Secret: ' + res.secret);
            this.tab = 'developer';
            await this._load();
        } catch (err) { this._msg(err.message, false); }
    }

    async _testWebhook(id) {
        try {
            const res = await this._post(`/arag/admin/developer/webhooks/${id}/test`, {});
            this._msg(res.message || 'تست ارسال شد');
        } catch (err) { this._msg(err.message, false); }
    }

    async _deleteWebhook(id) {
        try {
            await this._delete(`/arag/admin/developer/webhooks/${id}`);
            this.tab = 'developer';
            await this._load();
        } catch (err) { this._msg(err.message, false); }
    }

    _brandingHtml() {
        const s = this.settings;
        return `
        <div class="sp-admin__panel">
            <h3>برند و وایت‌لیبل</h3>
            <p class="sp-note">نام، رنگ و لوگو — بدون تغییر کد، فروشگاه را شخصی‌سازی کنید</p>
            <form id="sp-brand-form" class="sp-admin__form">
                <div class="sp-admin__grid2">
                    <label>نام برند<input name="brand_name" value="${this._esc(s.brand_name || '')}" required></label>
                    <label>شعار<input name="platform_tagline" value="${this._esc(s.platform_tagline || '')}"></label>
                    <label>رنگ اصلی<input name="primary_color" type="color" value="${this._esc(s.primary_color || '#1b4332')}"></label>
                    <label>رنگ accent<input name="accent_color" type="color" value="${this._esc(s.accent_color || '#52b788')}"></label>
                    <label>لوگو URL<input name="logo_url" dir="ltr" value="${this._esc(s.logo_url || '')}"></label>
                    <label>فاویکون URL<input name="favicon_url" dir="ltr" value="${this._esc(s.favicon_url || '')}"></label>
                    <label>تلفن پشتیبانی<input name="support_phone" dir="ltr" value="${this._esc(s.support_phone || '')}"></label>
                    <label>ایمیل<input name="support_email" dir="ltr" value="${this._esc(s.support_email || '')}"></label>
                    <label>پلن پلتفرم
                        <select name="platform_plan">
                            <option value="starter" ${s.platform_plan === 'starter' ? 'selected' : ''}>استارتر</option>
                            <option value="pro" ${s.platform_plan === 'pro' ? 'selected' : ''}>حرفه‌ای</option>
                            <option value="enterprise" ${(s.platform_plan || 'enterprise') === 'enterprise' ? 'selected' : ''}>سازمانی</option>
                        </select>
                    </label>
                </div>
                <button class="sp-btn" type="submit">ذخیره برند</button>
            </form>
            <p style="margin-top:16px"><a href="${this._siteUrl()}platform.php" target="_blank">صفحه فروش پلتفرم →</a></p>
        </div>`;
    }

    _developerHtml() {
        const pi = this.platformInfo;
        const events = pi.webhook_events || {};
        const eventOpts = Object.entries(events).map(([k, v]) =>
            `<label><input type="checkbox" name="wh_event" value="${k}"> ${v}</label>`
        ).join('');
        return `
        <div class="sp-admin__panel">
            <h3>توسعه‌دهنده — پلن: ${this._esc(pi.plan_detail?.name || pi.plan || '—')}</h3>
            <p class="sp-note">${pi.has_api ? '✓ API Key فعال' : '⚠ API Key فقط Enterprise'} · ${pi.has_webhooks ? '✓ Webhook فعال' : '⚠ Webhook فقط Enterprise'}</p>

            <h4 style="margin-top:20px">کلید API</h4>
            <form id="sp-key-form" style="display:flex;gap:8px;margin-bottom:12px">
                <input name="label" placeholder="برچسب کلید" style="flex:1">
                <button class="sp-btn" type="submit">+ ایجاد کلید</button>
            </form>
            <table class="sp-admin__table"><thead><tr><th>برچسب</th><th>پیشوند</th><th>آخرین استفاده</th><th></th></tr></thead>
            <tbody>${this.apiKeys.map(k => `<tr>
                <td>${this._esc(k.label)}</td><td dir="ltr">${this._esc(k.key_prefix)}…</td>
                <td>${this._esc(k.last_used_at || '—')}</td>
                <td><button class="sp-btn sp-btn--xs" data-revoke-key="${k.id}" type="button">لغو</button></td>
            </tr>`).join('') || '<tr><td colspan="4">کلیدی نیست</td></tr>'}</tbody></table>
            <div id="sp-key-once" hidden style="margin:12px 0;padding:12px;background:#ecfdf5;border-radius:8px"></div>

            <h4 style="margin-top:24px">Webhook</h4>
            <form id="sp-wh-form" class="sp-admin__form">
                <label>برچسب<input name="label"></label>
                <label>URL <input name="url" dir="ltr" placeholder="https://..."></label>
                <div>${eventOpts}</div>
                <button class="sp-btn" type="submit">ثبت Webhook</button>
            </form>
            <table class="sp-admin__table" style="margin-top:12px"><thead><tr><th>URL</th><th></th></tr></thead>
            <tbody>${this.webhooks.map(w => `<tr>
                <td dir="ltr">${this._esc(w.url)}</td>
                <td>
                    <button class="sp-btn sp-btn--xs" data-test-wh="${w.id}" type="button">تست</button>
                    <button class="sp-btn sp-btn--xs" data-del-wh="${w.id}" type="button">حذف</button>
                </td>
            </tr>`).join('') || '<tr><td colspan="2">Webhook ثبت نشده</td></tr>'}</tbody></table>

            <h4 style="margin-top:24px">لاگ Webhook</h4>
            <table class="sp-admin__table"><thead><tr><th>رویداد</th><th>HTTP</th><th>زمان</th></tr></thead>
            <tbody>${this.webhookLog.slice(0, 15).map(l => `<tr>
                <td>${this._esc(l.event)}</td><td>${l.http_status}</td><td>${this._esc((l.created_at||'').slice(0,19))}</td>
            </tr>`).join('') || '<tr><td colspan="3">خالی</td></tr>'}</tbody></table>
            <p style="margin-top:16px"><a href="${this._siteUrl()}shop-api-docs.php" target="_blank">مستندات API →</a></p>
        </div>`;
    }

    _esc(s) {
        return String(s ?? '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
    }
}
