/**
 * MelkAppView.js — پورتال مستقل اقتصاد ملک (مثل service.php)
 * کارت نقش برای همه افراد مرتبط — ورود یکپارچه ERP
 *
 * Perf: MelkWorkspace (+ panels ~270KB) is dynamically imported only after login.
 * Landing paints from this file alone (~32KB).
 */
const TOKEN_KEY = 'acc_token';
const ROLE_KEY = 'melk_selected_role';
const TAB_KEY = 'melk_initial_tab';

/** نقش‌های سازمانی و مشارکت‌کننده پرونده */
const MELK_ROLES = [
    { id: 'sysadmin',             icon: '🖥️', title: 'مدیر سیستم',       desc: 'دسترسی کامل — ERP Admin', accent: 'sysadmin', isAdmin: true },
    { id: 'district_lead',        icon: '🗺️', title: 'سرگروه منطقه',     desc: 'مدیریت ۱۱ منطقه شیراز', accent: 'lead' },
    { id: 'neighborhood_manager', icon: '🏘️', title: 'مدیر محله',        desc: 'بلوک، ملک، پرونده محله', accent: 'mgr' },
    { id: 'melk_coordinator',     icon: '📊', title: 'هماهنگ‌کننده',      desc: 'نظارت شبکه و هماهنگی', accent: 'coord' },
    { id: 'melk_specialist',      icon: '👥', title: 'کارشناس مشترک',    desc: 'حقوقی · شهرداری · ثبت', accent: 'spec' },
    { id: 'agent',                icon: '🏠', title: 'مشاور املاک',      desc: 'بنگاه و معاملات', accent: 'agent' },
    { id: 'melk_investor',        icon: '💎', title: 'سرمایه‌گذار',       desc: 'معیار خرید · هشدار آگهی · کارشناسی', accent: 'investor' },
    { id: 'melk_tax_legal',       icon: '📑', title: 'مالیات و حقوق',    desc: 'قوانین مالیاتی · مشاور AI · حقوق ملک', accent: 'advisory' },
    { id: 'legal',                icon: '⚖️', title: 'وکیل حقوقی',       desc: 'بررسی و قرارداد', accent: 'legal' },
    { id: 'municipality',         icon: '🏛️', title: 'کارشناس شهرداری', desc: 'مجوز و بلامانع', accent: 'mun' },
    { id: 'registry',             icon: '📜', title: 'کارشناس ثبت',      desc: 'سند و انتقال', accent: 'reg' },
    { id: 'appraisal',            icon: '📐', title: 'کارشناس رسمی',     desc: 'کارشناسی و قیمت', accent: 'appr' },
    { id: 'contractor',           icon: '🔨', title: 'پیمانکار',         desc: 'ساخت و نوسازی', accent: 'contr' },
    { id: 'finance',              icon: '💰', title: 'کارشناس مالی',     desc: 'تسهیلات و محاسبات', accent: 'fin' },
    { id: 'county_agency',        icon: '🏘️', title: 'بنگاه شهرستان',    desc: 'تقاضا و درخواست‌های شهرستان', accent: 'county' },
    { id: 'specialist_arch',      icon: '📐', title: 'معمار',            desc: 'ثبت‌نام متخصص ساختمان', accent: 'arch' },
    { id: 'specialist_struct',    icon: '🏗️', title: 'کارشناس سازه',     desc: 'طراحی و سازه', accent: 'struct' },
    { id: 'specialist_mep',       icon: '⚙️', title: 'کارشناس تاسیسات',  desc: 'MEP و تاسیسات', accent: 'mep' },
    { id: 'specialist_pending',   icon: '⏳', title: 'متخصص (در انتظار)', desc: 'نمونه تأیید توسط مدیر', accent: 'pend' },
];

/** کاربران آزمایشی — فقط username (رمز هرگز در فرانت‌اند نیست؛ فقط وقتی ACC_ENABLE_DEMO) */
const DEMO_USERS = (typeof window !== 'undefined' && window.ACC_ENABLE_DEMO) ? {
    sysadmin:             { u: 'ostadowner', label: 'مدیر سیستم' },
    district_lead:        { u: 'melk_lead_d1', label: 'سرگروه منطقه' },
    neighborhood_manager: { u: 'melk_mgr_007', label: 'مدیر محله' },
    melk_coordinator:     { u: 'melk_coord', label: 'هماهنگ‌کننده' },
    melk_specialist:      { u: 'melk_specialist', label: 'کارشناس مشترک' },
    agent:                { u: 'melk_agent', label: 'مشاور املاک' },
    melk_investor:        { u: 'melk_investor_demo', label: 'سرمایه‌گذار — دکتر احمدی' },
    melk_tax_legal:       { u: 'melk_advisory_demo', label: 'مالیات و حقوق — دکتر رضایی' },
    legal:                { u: 'melk_legal', label: 'وکیل حقوقی' },
    municipality:         { u: 'melk_shahrdari', label: 'کارشناس شهرداری' },
    registry:             { u: 'melk_registry', label: 'کارشناس ثبت' },
    appraisal:            { u: 'melk_appraisal', label: 'کارشناس رسمی' },
    contractor:           { u: 'melk_contractor', label: 'پیمانکار' },
    finance:              { u: 'melk_finance', label: 'کارشناس مالی' },
    county_agency:        { u: 'melk_county_agency', label: 'بنگاه شهرستان' },
    specialist_arch:      { u: 'melk_specialist_arch', label: 'معمار' },
    specialist_struct:    { u: 'melk_specialist_struct', label: 'کارشناس سازه' },
    specialist_mep:       { u: 'melk_specialist_mep', label: 'کارشناس تاسیسات' },
    specialist_pending:   { u: 'melk_specialist_pending', label: 'متخصص در انتظار' },
} : {};

/** نقش → تب پیش‌فرض پس از ورود آزمایشی */
const ROLE_TAB_MAP = {
    melk_investor:      'investor',
    melk_tax_legal:     'advisory',
    county_agency:      'county',
    specialist_arch:    'specialists',
    specialist_struct:  'specialists',
    specialist_mep:     'specialists',
    specialist_pending: 'specialists',
    finance:            'accounting',
    contractor:         'construction',
    agent:              'listings',
};

export default class MelkAppView {

    constructor() {
        this.root = null;
        this.token = sessionStorage.getItem(TOKEN_KEY) || '';
        this.user = null;
        this.perms = new Set();
        this.screen = 'landing';
        this.selectedRole = sessionStorage.getItem(ROLE_KEY) || '';
        this.workspace = null;
    }

    _roleById(id) {
        return MELK_ROLES.find(r => r.id === id) || null;
    }

    async render(root) {
        this.root = root;
        // Paint immediately — never blank-wait on acl/me or workspace modules
        if (this.token) {
            this.root.innerHTML = `<div class="melk-app ma-applied" dir="rtl"><div class="ma-boot">در حال بارگذاری Workspace…</div></div>`;
            try {
                await this._loadMe();
                this.screen = 'app';
            } catch {
                this.token = '';
                sessionStorage.removeItem(TOKEN_KEY);
                this.screen = 'landing';
            }
        }
        await this._paint();
    }

    _ensureCss(href) {
        if (document.querySelector(`link[data-melk-css="${href}"]`) || document.querySelector(`link[href="${href}"]`)) {
            return Promise.resolve();
        }
        return new Promise((resolve) => {
            const link = document.createElement('link');
            link.rel = 'stylesheet';
            link.href = href;
            link.dataset.melkCss = href;
            link.onload = () => resolve();
            link.onerror = () => resolve();
            document.head.appendChild(link);
        });
    }

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

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

    can(key) {
        if (this.perms.has('*')) return true;
        return this.perms.has(key);
    }

    async _loadMe() {
        const me = await this._request('GET', 'acl/me');
        const u = me?.user || me?.data?.user || null;
        if (u) {
            this.user = {
                display_name: u.display_name || u.name || u.user_login || '',
                user_login: u.user_login || u.username || '',
            };
        }
        const roles = me?.roles || me?.data?.roles || [];
        const plist = me?.permissions || me?.data?.permissions || [];
        this.perms = new Set();
        if (roles.some(r => (r.slug || r) === 'super_admin')) {
            this.perms.add('*');
        }
        if (Array.isArray(plist)) {
            plist.forEach(p => {
                const k = typeof p === 'string' ? p : (p.key || p.permission_key);
                if (k) this.perms.add(k);
            });
        }
        if (!this.can('melk.view')) {
            throw new Error('دسترسی به پورتال اقتصاد ملک ندارید');
        }
    }

    async _request(method, path, body) {
        const url = `${this._apiBase()}/${path.replace(/^\//, '')}`;
        const opts = {
            method,
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
            },
        };
        if (this.token) opts.headers.Authorization = `Bearer ${this.token}`;
        if (body && method !== 'GET') opts.body = JSON.stringify(body);
        const r = await fetch(url, opts);
        const json = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(json.message || `HTTP ${r.status}`);
        return json;
    }

    async _paint() {
        if (this.screen === 'app') {
            await this._renderApp();
            return;
        }
        if (this.screen === 'login') {
            this.root.innerHTML = this._loginHtml();
            this._bindLogin();
            return;
        }
        this.root.innerHTML = this._landingHtml();
        this._bindLanding();
    }

    _landingHtml() {
        const site = this._siteUrl();
        const featured = [
            { id: 'agent', tag: 'Brokerage', cls: '' },
            { id: 'melk_investor', tag: 'Capital', cls: 'ma-portal--investor' },
            { id: 'melk_tax_legal', tag: 'Advisory', cls: 'ma-portal--advisory' },
            { id: 'contractor', tag: 'Build', cls: '' },
            { id: 'district_lead', tag: 'Network', cls: '' },
            { id: 'finance', tag: 'Finance', cls: '' },
        ].map(f => {
            const r = MELK_ROLES.find(x => x.id === f.id);
            if (!r) return '';
            return `<button type="button" class="ma-portal ${f.cls}" data-role="${r.id}">
                <span class="ma-portal__tag">${f.tag}</span>
                <strong>${this._esc(r.title)}</strong>
                <small>${this._esc(r.desc)}</small>
                <span class="ma-portal__go">ورود نقش ←</span>
            </button>`;
        }).join('');

        const adminRole = MELK_ROLES.find(r => r.isAdmin);
        const adminPortal = adminRole ? `
            <button type="button" class="ma-portal ma-portal--admin" data-role="${adminRole.id}">
                <span class="ma-portal__tag">Admin</span>
                <strong>${this._esc(adminRole.title)}</strong>
                <small>${this._esc(adminRole.desc)} — ostadowner</small>
                <span class="ma-portal__go">ورود مدیریت ←</span>
            </button>` : '';

        const allPortals = MELK_ROLES.filter(r => !r.isAdmin && !['agent','melk_investor','melk_tax_legal','contractor','district_lead','finance'].includes(r.id))
            .map(r => `<button type="button" class="ma-portal" data-role="${r.id}">
                <span class="ma-portal__tag">Role</span>
                <strong>${this._esc(r.title)}</strong>
                <small>${this._esc(r.desc)}</small>
                <span class="ma-portal__go">ورود ←</span>
            </button>`).join('');

        const demoRows = MELK_ROLES.map(r => {
            const demo = DEMO_USERS[r.id];
            if (!demo) return '';
            const adminCls = r.isAdmin ? ' melk-demo-row--admin' : '';
            return `
            <button type="button" class="melk-demo-row${adminCls}" data-demo-role="${r.id}" data-demo-u="${demo.u}" title="${this._esc(r.title)} — ${demo.u}">
                <span class="melk-demo-row__icon">${r.icon}</span>
                <span class="melk-demo-row__name">${this._esc(r.title)}</span>
                <code class="melk-demo-row__user">${demo.u}</code>
                <span class="melk-demo-row__badge">انتخاب کاربر</span>
            </button>`;
        }).join('');

        const demoToggle = demoRows
            ? `<button type="button" id="melk-demo-btn">ورود آزمایشی</button>`
            : '';
        const demoPanel = demoRows ? `
            <div class="melk-demo-panel" id="melk-demo-panel" style="display:none;">
                <div class="melk-demo-panel__inner">
                    <div class="melk-demo-panel__head">
                        <span class="melk-demo-panel__head-icon">🧪</span>
                        <span class="melk-demo-panel__head-title">ورود آزمایشی (فقط لوکال) — نام کاربری پر می‌شود؛ رمز را وارد کنید</span>
                        <button type="button" class="melk-demo-close" id="melk-demo-close">✕</button>
                    </div>
                    <div class="melk-demo-panel__note">
                        <span>رمز در مرورگر نمایش داده نمی‌شود.</span>
                    </div>
                    <div class="melk-demo-list">${demoRows}</div>
                </div>
            </div>` : '';

        return `
        <div class="melk-app melk-app--landing lp-wrap ma-applied" dir="rtl">
            <div class="ma-util">
                <a href="${site}">ACC Engine</a>
                <a href="${site}shop.php">فروشگاه</a>
                <a href="${site}service.php">خدمات HVAC</a>
                <a href="#ma-accounting" class="ma-util__gold">حسابداری مشارکت</a>
            </div>

            <header class="ma-header" id="ma-header">
                <a href="${site}melk.php" class="ma-brand">
                    <span class="ma-brand__mark">م</span>
                    <span class="ma-brand__text">
                        <span class="ma-brand__name">اقتصاد ملک <em>Applied</em></span>
                        <span class="ma-brand__sub">Shiraz Property Network</span>
                    </span>
                </a>
                <nav class="ma-nav">
                    <a href="#ma-pillars">اکوسیستم</a>
                    <a href="#ma-portals">ورود نقش‌ها</a>
                    <a href="#ma-story">شبکه شیراز</a>
                    <a href="#ma-accounting">حسابداری</a>
                    ${demoToggle}
                </nav>
                <button type="button" class="ma-header__cta ma-header__cta--gold" data-role="agent">ورود مشاور</button>
            </header>

            ${demoPanel}

            <section class="ma-hero">
                <div class="ma-hero__media" aria-hidden="true"></div>
                <div class="ma-hero__grain" aria-hidden="true"></div>
                <div class="ma-hero__content">
                    <p class="ma-hero__brand">Melk <span>Applied</span></p>
                    <h1>اقتصاد ملک شیراز<br><em>از محله تا مشارکت سرمایه</em></h1>
                    <p class="ma-hero__lead">پلتفرم همکاری بنگاه‌ها، سرمایه‌گذاران و پیمانکاران — پرونده، بازار و شفافیت سهم هر شریک.</p>
                    <div class="ma-hero__actions">
                        <a href="#ma-portals" class="ma-btn ma-btn--gold">ورود به شبکه</a>
                        <a href="#ma-story" class="ma-btn ma-btn--ghost">کشف اکوسیستم</a>
                    </div>
                </div>
            </section>

            <section class="ma-section" id="ma-pillars">
                <div class="ma-section__head ma-reveal">
                    <span class="ma-kicker">Ecosystem</span>
                    <h2>چهار ستون شبکه اقتصاد ملک</h2>
                    <p>طراحی‌شده برای همکاری حرفه‌ای در مقیاس شهر — نه فقط آگهی، بلکه حاکمیت پرونده و سرمایه.</p>
                </div>
                <div class="ma-pillars ma-reveal">
                    <article class="ma-pillar"><span class="ma-pillar__num">01</span><strong>شبکه جغرافیایی</strong><span>منطقه، محله، بلوک و ملک — سلسله‌مراتب شفاف برای بنگاه‌های شیراز</span></article>
                    <article class="ma-pillar"><span class="ma-pillar__num">02</span><strong>بازار و سرمایه</strong><span>آگهی، معیار سرمایه‌گذار، هشدار تطبیق و درخواست کارشناسی</span></article>
                    <article class="ma-pillar"><span class="ma-pillar__num">03</span><strong>مشارکت ساخت</strong><span>پروژه، سهم شرکا، قرارداد مشارکت و کنترل کیفیت اجرا</span></article>
                    <article class="ma-pillar"><span class="ma-pillar__num">04</span><strong>حقوق و شفافیت</strong><span>مشاوره مالیاتی، کد نوسازی، GIS و حسابداری سهم فعالیت‌ها</span></article>
                </div>
            </section>

            <section class="ma-section ma-section--navy ma-reveal">
                <div class="ma-stats">
                    <div class="ma-stat"><strong>۱۱</strong><span>منطقه شهری</span></div>
                    <div class="ma-stat"><strong>۱</strong><span>پورتال یکپارچه</span></div>
                    <div class="ma-stat"><strong>∞</strong><span>پرونده همکاری</span></div>
                    <div class="ma-stat"><strong>ABC</strong><span>گراف سهم شرکا</span></div>
                </div>
            </section>

            <section class="ma-section ma-section--mist" id="ma-portals">
                <div class="ma-section__head ma-reveal">
                    <span class="ma-kicker">Access</span>
                    <h2>ورود به پورتال نقش شما</h2>
                    <p>هر نقش فضای کاری اختصاصی دارد — از مشاور و سرمایه‌گذار تا مدیریت شبکه.</p>
                </div>
                <div class="ma-portals ma-reveal">
                    ${featured}
                    ${adminPortal}
                    ${allPortals}
                </div>
            </section>

            <section class="ma-section" id="ma-story">
                <div class="ma-story ma-reveal">
                    <div class="ma-story__media" role="img" aria-label="معماری و املاک شهری"></div>
                    <div class="ma-story__body">
                        <span class="ma-kicker">Shiraz Network</span>
                        <h3>همکاری بنگاه‌ها روی نقشه واقعی شهر</h3>
                        <p>از سرگروه منطقه تا مدیر محله، وکیل، شهرداری، ثبت و پیمانکار — همه روی یک پرونده مشترک کار می‌کنند. بازار ملک، سرمایه‌گذاری و ساخت‌وساز در یک زبان بصری بین‌المللی.</p>
                        <div style="display:flex;flex-wrap:wrap;gap:10px">
                            <button type="button" class="ma-btn ma-btn--dark" data-section="listings">بازار ملک</button>
                            <button type="button" class="ma-btn ma-btn--outline" data-section="investor">سرمایه‌گذار</button>
                            <button type="button" class="ma-btn ma-btn--outline" data-section="construction">ساخت‌وساز</button>
                        </div>
                    </div>
                </div>
            </section>

            <section class="ma-section ma-section--mist" id="ma-accounting">
                <div class="ma-section__head ma-reveal">
                    <span class="ma-kicker">Cost Graph</span>
                    <h2>حسابداری صنعتی مشارکت ملک</h2>
                    <p>بهای تمام‌شده فعالیت‌های پروژه ساخت — سهم هر شریک (مالک، پیمانکار، ناظر، سرمایه‌گذار) روی گراف سفارش‌مانند پروژه.</p>
                </div>
                <div class="ma-reveal" style="max-width:720px">
                    <button type="button" class="ma-btn ma-btn--dark" data-section="accounting">ورود به گراف حسابداری ←</button>
                    <p style="margin-top:14px;color:var(--ma-muted);font-size:.92rem">پس از ورود، تب «حسابداری مشارکت» را باز کنید یا از ورود آزمایشی نقش مالی استفاده کنید.</p>
                </div>
            </section>

            <section class="ma-help">
                <div class="ma-help__inner">
                    <div>
                        <h2>چطور کمک کنیم؟</h2>
                        <p>بازار، سرمایه، ساخت، مالیات یا پشتیبانی آنلاین — مسیر درست را انتخاب کنید.</p>
                    </div>
                    <div class="ma-help__actions">
                        <button type="button" class="ma-btn ma-btn--solid" data-role="agent">مشاور املاک</button>
                        <button type="button" class="ma-btn" data-role="melk_investor">سرمایه‌گذار</button>
                        <button type="button" class="ma-btn" data-section="advisory">مالیات و حقوق</button>
                        <button type="button" class="ma-btn" data-section="accounting">حسابداری</button>
                    </div>
                </div>
            </section>

            <footer class="ma-footer">
                <span>© Melk Applied — اقتصاد ملک شیراز</span>
                <span>
                    <a href="${site}">ACC Engine</a> ·
                    <a href="${site}shop.php">فروشگاه</a> ·
                    <a href="${site}service.php">خدمات</a>
                </span>
            </footer>
        </div>`;
    }

    _loginHtml() {
        const site = this._siteUrl();
        const role = this._roleById(this.selectedRole);
        const roleBadge = role
            ? `<div class="ma-login__role"><span>${role.icon}</span> ورود به عنوان <strong>${this._esc(role.title)}</strong></div>`
            : '';

        return `
        <div class="melk-app lp-wrap ma-applied ma-login-screen" dir="rtl">
            <div class="ma-util">
                <a href="${site}">ACC Engine</a>
                <a href="${site}melk.php" id="melk-back-landing">بازگشت به لندینگ</a>
            </div>
            <div class="ma-login">
                <div class="ma-login__card">
                    <p class="ma-login__brand">Melk <em>Applied</em></p>
                    ${roleBadge}
                    <h3>ورود به شبکه اقتصاد ملک</h3>
                    <p class="ma-login__hint">با حساب ERP وارد شوید — همان توکن برای همه پورتال‌ها.</p>
                    <form id="melk-login-form">
                        <div class="lp-field"><label>نام کاربری یا ایمیل</label><input name="username" required autocomplete="username"></div>
                        <div class="lp-field"><label>رمز عبور</label><input name="password" type="password" required autocomplete="current-password"></div>
                        <button type="submit" class="ma-btn ma-btn--dark" style="width:100%;justify-content:center">ورود</button>
                        <div class="lp-msg" id="melk-login-msg"></div>
                    </form>
                </div>
            </div>
        </div>`;
    }

    async _renderApp() {
        const site = this._siteUrl();
        const name = this.user?.display_name || this.user?.user_login || 'کاربر';
        const role = this._roleById(this.selectedRole);
        const roleLabel = role ? `${role.icon} ${role.title}` : '';

        this.root.innerHTML = `
        <div class="melk-app melk-app--workspace ma-applied" dir="rtl">
            <header class="melk-header melk-header--app ma-ws-header">
                <a href="${site}melk.php" class="ma-brand ma-brand--ws">
                    <span class="ma-brand__mark">م</span>
                    <span class="ma-brand__text">
                        <span class="ma-brand__name">اقتصاد ملک <em>Applied</em></span>
                        <span class="ma-brand__sub">Workspace</span>
                    </span>
                </a>
                <span class="melk-header__user ma-ws-user">${this._esc(name)}${roleLabel ? ` · ${this._esc(roleLabel)}` : ''}</span>
                <nav class="melk-header__nav ma-ws-nav">
                    <a href="${site}index.php" target="_blank" rel="noopener">ERP / GIS</a>
                </nav>
                <button type="button" class="ma-btn ma-btn--ghost-light" id="melk-logout">خروج</button>
            </header>
            <main class="melk-main" id="melk-workspace-root"><div class="ma-boot">بارگذاری پنل‌ها…</div></main>
        </div>`;

        this.root.querySelector('#melk-logout')?.addEventListener('click', () => {
            this.token = '';
            sessionStorage.removeItem(TOKEN_KEY);
            this.screen = 'landing';
            this._paint();
        });

        const wsRoot = this.root.querySelector('#melk-workspace-root');
        // Workspace CSS + module graph only after shell is visible
        const [{ default: MelkWorkspace }] = await Promise.all([
            import('./melk/MelkWorkspace.js'),
            this._ensureCss('/acc-engine/assets/css/base/eqtesad-melk.css?v=18'),
            this._ensureCss('/acc-engine/assets/css/base/gis.css'),
        ]);

        this.workspace = new MelkWorkspace({
            root: wsRoot,
            request: (m, p, b) => this._request(m, p, b),
            can: (k) => this.can(k),
            erpUrl: site,
            onReady: (ws) => {
                const caseId = new URLSearchParams(window.location.search).get('case');
                if (caseId) ws._openCase(parseInt(caseId, 10));
                const tab = sessionStorage.getItem(TAB_KEY)
                    || new URLSearchParams(window.location.search).get('tab');
                if (tab) {
                    sessionStorage.removeItem(TAB_KEY);
                    ws._switchMainTab(tab);
                }
            },
        });
        await this.workspace.init();
    }

    _bindLanding() {
        this.root.querySelectorAll('[data-role]').forEach(btn => {
            btn.addEventListener('click', () => {
                this.selectedRole = btn.dataset.role || '';
                sessionStorage.setItem(ROLE_KEY, this.selectedRole);
                this.screen = 'login';
                this._paint();
            });
        });
        this.root.querySelectorAll('[data-section]').forEach(btn => {
            btn.addEventListener('click', () => this._goToSection(btn.dataset.section));
        });

        const demoBtn   = this.root.querySelector('#melk-demo-btn');
        const demoPanel = this.root.querySelector('#melk-demo-panel');
        const demoClose = this.root.querySelector('#melk-demo-close');
        demoBtn?.addEventListener('click', () => {
            const isOpen = demoPanel.style.display !== 'none';
            demoPanel.style.display = isOpen ? 'none' : 'block';
            demoBtn.classList.toggle('melk-demo-toggle--active', !isOpen);
        });
        demoClose?.addEventListener('click', () => {
            demoPanel.style.display = 'none';
            demoBtn?.classList.remove('melk-demo-toggle--active');
        });

        this.root.querySelectorAll('[data-demo-role]').forEach(row => {
            row.addEventListener('click', () => {
                // فقط نقش/یوزرنیم را ست می‌کند — لاگین با رمز واقعی از فرم نقش
                const roleId = row.dataset.demoRole || '';
                const username = row.dataset.demoU || '';
                this.selectedRole = roleId;
                sessionStorage.setItem(ROLE_KEY, roleId);
                const tab = ROLE_TAB_MAP[roleId];
                if (tab) sessionStorage.setItem(TAB_KEY, tab);
                row.querySelector('.melk-demo-row__badge').textContent = '✓ ' + username;
                this.root.querySelector('#melk-demo-panel')?.style && (this.root.querySelector('#melk-demo-panel').style.display = 'none');
                // هدایت به ورود نقش (بدون autofill رمز)
                const portalBtn = this.root.querySelector(`[data-role="${roleId}"]`);
                if (portalBtn) portalBtn.click();
                else this._toast?.('کاربر انتخاب شد: ' + username + ' — از ورود نقش رمز را وارد کنید');
            });
        });

        const hdr = this.root.querySelector('#ma-header');
        const onScroll = () => hdr?.classList.toggle('ma-header--scrolled', window.scrollY > 12);
        window.addEventListener('scroll', onScroll, { passive: true });
        onScroll();

        if ('IntersectionObserver' in window) {
            const io = new IntersectionObserver((entries) => {
                entries.forEach(en => { if (en.isIntersecting) en.target.classList.add('is-in'); });
            }, { threshold: 0.12, rootMargin: '0px 0px -40px 0px' });
            this.root.querySelectorAll('.ma-reveal').forEach(el => io.observe(el));
        } else {
            this.root.querySelectorAll('.ma-reveal').forEach(el => el.classList.add('is-in'));
        }
    }

    async _demoLogin(roleId, username, password, rowEl) {
        // نشانه‌گذاری بصری
        rowEl.classList.add('melk-demo-row--loading');
        rowEl.querySelector('.melk-demo-row__badge').textContent = '⏳ در حال ورود…';

        try {
            this.selectedRole = roleId;
            sessionStorage.setItem(ROLE_KEY, roleId);
            const tab = ROLE_TAB_MAP[roleId];
            if (tab) sessionStorage.setItem(TAB_KEY, tab);

            const res = await this._request('POST', 'public/auth/login', { username, password });
            if (!res.success || !res.token) throw new Error(res.message || 'ورود ناموفق');

            this.token = res.token;
            sessionStorage.setItem(TOKEN_KEY, res.token);
            if (res.user) {
                this.user = {
                    display_name: res.user.name || res.user.display_name || res.user.username,
                    user_login: res.user.username || res.user.user_login || '',
                };
            }
            await this._loadMe();
            this.screen = 'app';
            await this._paint();
        } catch (err) {
            rowEl.classList.remove('melk-demo-row--loading');
            rowEl.querySelector('.melk-demo-row__badge').textContent = '❌ ' + (err.message || 'خطا');
            setTimeout(() => {
                rowEl.querySelector('.melk-demo-row__badge').textContent = 'ورود خودکار ↗';
            }, 2500);
        }
    }

    _goToSection(section) {
        sessionStorage.setItem(TAB_KEY, section);
        if (this.token) {
            this.screen = 'app';
            this._paint();
            return;
        }
        this.screen = 'login';
        this._paint();
    }

    _bindLogin() {
        this.root.querySelector('#melk-back-landing')?.addEventListener('click', () => {
            this.screen = 'landing';
            this._paint();
        });
        this.root.querySelector('#melk-login-form')?.addEventListener('submit', async (e) => {
            e.preventDefault();
            const msg = this.root.querySelector('#melk-login-msg');
            const fd = new FormData(e.target);
            msg.textContent = '';
            try {
                const res = await this._request('POST', 'public/auth/login', {
                    username: fd.get('username'),
                    password: fd.get('password'),
                });
                if (res.success && res.token) {
                    this.token = res.token;
                    sessionStorage.setItem(TOKEN_KEY, res.token);
                    if (res.user) {
                        this.user = {
                            display_name: res.user.name || res.user.display_name || res.user.username,
                            user_login: res.user.username || res.user.user_login || '',
                        };
                    }
                    await this._loadMe();
                    this.screen = 'app';
                    await this._paint();
                } else {
                    msg.textContent = res.message || 'ورود ناموفق';
                    msg.className = 'lp-msg lp-msg--error';
                }
            } catch (err) {
                msg.textContent = err.message || 'خطا';
                msg.className = 'lp-msg lp-msg--error';
            }
        });
    }

    _esc(t) {
        return String(t ?? '').replace(/&/g, '&amp;').replace(/</g, '&lt;');
    }
}
