/**
 * ACC Chat Widget
 * ویجت چت شناور — تزریق در همه صفحات سایت
 * Long Polling برای real-time بدون WebSocket
 */
;(function () {
    'use strict';

    /* ── تنظیمات از PHP ────────────────────────────────── */
    const CFG = window.ACC_CHAT_CFG || {
        api_base:    '/wp-json/acc/v1',
        site_name:   'پشتیبانی آنلاین',
        welcome_msg: 'سلام! چطور می‌تونم کمکتون کنم؟ 😊',
        phone:       '',
        whatsapp:    '',
        telegram:    '',
        instagram:   '',
        poll_ms:     4000,
        portal:      'default',
        tabs:        [ 'home', 'services', 'track', 'chat', 'tech', 'contact' ],
        launcher_icon: '💬',
    };

    const PORTAL = CFG.portal || CFG.spa_slug || 'default';
    function _storeKey(base) { return `${base}_${PORTAL}`; }

    function _getPortalAI() {
        if (PORTAL === 'wholesale' && window.WholesaleAI) return window.WholesaleAI;
        if (window.ShopAI) return window.ShopAI;
        if (window.WholesaleAI) return window.WholesaleAI;
        return null;
    }

    /* ── State ─────────────────────────────────────────── */
    const SERVICE_TYPES = (PORTAL === 'education' && window.EduWizards?.ROUTES)
        ? window.EduWizards.ROUTES
        : (window.SvcWizards?.ROUTES || [
        { key: 'phone_consult', icon: '📞', title: 'مشاوره فنی' },
        { key: 'repair', icon: '🛠', title: 'تعمیر و سرویس' },
        { key: 'pm', icon: '📅', title: 'نگهداری PM' },
        { key: 'parts_supply', icon: '🔩', title: 'تأمین قطعات' },
        { key: 'equipment_purchase', icon: '🏭', title: 'خرید تجهیزات' },
        { key: 'site_visit', icon: '🔍', title: 'بازدید کارشناس' },
        { key: 'contract_support', icon: '📋', title: 'پشتیبانی قراردادی' },
    ]).map(r => ({ ...r, title: r.title }));

    const state = {
        open:         false,
        tab:          'home',
        sessionKey:   _getOrMakeSession(),
        roomId:       null,
        trackingCode: null,
        activeCase:   null,
        cases:        _loadCasesLocal(),
        lastMsgId:    0,
        polling:      false,
        pollTimer:    null,
        started:      false,
        unread:       0,
        wizardType:   null,
        tech: {
            token:      null,
            user:       null,
            role:       null,
            isTech:     false,
            queue:      [],
            activeJob:  null,
            lastMsgId:  0,
            pollTimer:  null,
            view:       'login', // login | list | chat
        },
    };

    /* ── DOM Build ─────────────────────────────────────── */
    function _buildHTML() {
        const contacts = _buildContacts();

        const el = document.createElement('div');
        el.innerHTML = `
        <!-- Launcher -->
        <div id="acc-chat-launcher" aria-label="چت پشتیبانی">
            <div style="position:relative;">
                <div class="cw-launcher-btn">${_e(CFG.launcher_icon || '💬')}</div>
                <span class="cw-badge" id="cw-badge"></span>
            </div>
            <span class="cw-launcher-label">${_e(CFG.site_name)}</span>
        </div>

        <!-- Chat Window -->
        <div id="acc-chat-window" role="dialog" aria-label="پنجره چت">
            <!-- Header -->
            <div class="cw-header">
                <div class="cw-header-avatar">💬</div>
                <div class="cw-header-info">
                    <div class="cw-header-name">${_e(CFG.site_name)}</div>
                    <div class="cw-header-status">
                        <span class="cw-status-dot"></span> آنلاین
                    </div>
                </div>
                <button class="cw-header-close" id="cw-close" title="بستن">✕</button>
            </div>

            <!-- Loading Bar -->
            <div class="cw-loading-bar" id="cw-loading"></div>

            <!-- Tabs -->
            <div class="cw-tabs">
                <button class="cw-tab active" data-tab="home">
                    <span class="cw-tab-icon">🏠</span>خانه
                </button>
                <button class="cw-tab" data-tab="ai">
                    <span class="cw-tab-icon">🤖</span>مشاور
                </button>
                <button class="cw-tab" data-tab="services">
                    <span class="cw-tab-icon">🔧</span>خدمت
                </button>
                <button class="cw-tab" data-tab="track">
                    <span class="cw-tab-icon">📋</span>پیگیری
                </button>
                <button class="cw-tab" data-tab="chat">
                    <span class="cw-tab-icon">💬</span>گفتگو
                </button>
                <button class="cw-tab" data-tab="tech">
                    <span class="cw-tab-icon">👷</span>کارشناس
                </button>
                <button class="cw-tab" data-tab="contact">
                    <span class="cw-tab-icon">📞</span>تماس
                </button>
            </div>

            <!-- Panel: Home -->
            <div class="cw-panel active" id="cw-panel-home">
                <div class="cw-home">
                    <div class="cw-welcome-card">
                        <div class="cw-welcome-icon">👋</div>
                        <div class="cw-welcome-title">خوش آمدید!</div>
                        <div class="cw-welcome-sub">${_e(CFG.welcome_msg)}</div>
                    </div>
                    <div class="cw-quick-actions">
                        <div class="cw-qa-btn" data-action="go-ai">
                            <span class="cw-qa-icon">🤖</span>مشاور هوشمند
                        </div>
                        <div class="cw-qa-btn" data-action="go-services">
                            <span class="cw-qa-icon">🔧</span>درخواست خدمت
                        </div>
                        <div class="cw-qa-btn" data-action="go-track">
                            <span class="cw-qa-icon">📋</span>پیگیری درخواست
                        </div>
                        <div class="cw-qa-btn" data-action="start-chat">
                            <span class="cw-qa-icon">💬</span>گفتگو
                        </div>
                        <div class="cw-qa-btn" data-action="go-tech">
                            <span class="cw-qa-icon">👷</span>پنل کارشناس
                        </div>
                        ${CFG.whatsapp ? `<a class="cw-qa-btn" href="https://wa.me/${_e(CFG.whatsapp)}" target="_blank">
                            <span class="cw-qa-icon">📱</span>واتساپ
                        </a>` : ''}
                    </div>
                    <div id="cw-recent-cases" class="cw-recent-cases"></div>
                </div>
            </div>

            <!-- Panel: AI Advisor -->
            <div class="cw-panel" id="cw-panel-ai">
                <div id="cw-ai-mount" class="cw-ai-mount"></div>
            </div>

            <!-- Panel: Services -->
            <div class="cw-panel" id="cw-panel-services">
                <div class="cw-home" id="cw-services-list"></div>
                <div class="cw-wizard" id="cw-wizard" style="display:none;"></div>
            </div>

            <!-- Panel: Track -->
            <div class="cw-panel" id="cw-panel-track">
                <div class="cw-home">
                    <div class="cw-track-lookup">
                        <input class="cw-visitor-input" id="cw-track-code" maxlength="6" placeholder="کد پیگیری" dir="ltr" style="letter-spacing:4px;text-transform:uppercase;font-weight:bold;text-align:center;">
                        <button class="cw-start-btn" id="cw-track-btn">🔍 پیگیری</button>
                    </div>
                    <div id="cw-cases-list" class="cw-cases-list"></div>
                    <div id="cw-track-detail" class="cw-track-detail" style="display:none;"></div>
                </div>
            </div>

            <!-- Panel: Chat -->
            <div class="cw-panel" id="cw-panel-chat">
                <div class="cw-case-bar" id="cw-case-bar" style="display:none;"></div>
                <!-- فرم اطلاعات بازدیدکننده -->
                <div class="cw-visitor-form" id="cw-visitor-form">
                    <h4>🙋 برای شروع گفتگو:</h4>
                    <input class="cw-visitor-input" id="cw-vis-name"  type="text"  placeholder="نام شما *" autocomplete="name">
                    <input class="cw-visitor-input" id="cw-vis-phone" type="tel"   placeholder="شماره موبایل *" autocomplete="tel" dir="ltr">
                    <input class="cw-visitor-input" id="cw-vis-email" type="email" placeholder="ایمیل (اختیاری)" autocomplete="email" dir="ltr">
                    <div class="cw-divider" style="display:flex;align-items:center;gap:8px;margin:6px 0;font-size:11px;color:#94a3b8;">
                        <span style="flex:1;height:1px;background:#e2e8f0;"></span>یا با کد پیگیری قبلی<span style="flex:1;height:1px;background:#e2e8f0;"></span>
                    </div>
                    <input class="cw-visitor-input" id="cw-vis-code" type="text" placeholder="کد پیگیری (اختیاری)" maxlength="6" style="letter-spacing:4px;text-transform:uppercase;font-weight:bold;" autocomplete="off">
                    <button class="cw-start-btn" id="cw-start-btn">🚀 شروع گفتگو</button>
                </div>
                <!-- پیام‌ها -->
                <div class="cw-chat-area" id="cw-chat-area"></div>
                <!-- ورودی -->
                <div class="cw-input-area" id="cw-input-area" style="display:none;">
                    <textarea class="cw-input" id="cw-input" placeholder="پیام خود را بنویسید..." rows="1"></textarea>
                    <button class="cw-send-btn" id="cw-send" title="ارسال">➤</button>
                </div>
            </div>

            <!-- Panel: Technician (کارشناس میدانی) -->
            <div class="cw-panel" id="cw-panel-tech">
                <div class="cw-tech-wrap">
                    <div id="cw-tech-login" class="cw-tech-login cw-home">
                        <div class="cw-welcome-card" style="background:linear-gradient(135deg,#eff6ff,#f0fdf4);">
                            <div class="cw-welcome-icon">👷</div>
                            <div class="cw-welcome-title">ورود کارشناس</div>
                            <div class="cw-welcome-sub">با حساب ERP پاسخ دهید — همان thread مشتری</div>
                        </div>
                        <input class="cw-visitor-input" id="cw-tech-user" type="text" placeholder="نام کاربری" dir="ltr" autocomplete="username">
                        <input class="cw-visitor-input" id="cw-tech-pass" type="password" placeholder="رمز عبور" autocomplete="current-password">
                        <button class="cw-start-btn" id="cw-tech-login-btn">🔐 ورود کارشناس</button>
                        <div id="cw-tech-login-err" class="cw-tech-err"></div>
                        <div class="cw-tech-hint">مثال تست: <code dir="ltr">svc_tech1_demo</code> / <code dir="ltr">Demo@2026</code></div>
                    </div>
                    <div id="cw-tech-app" class="cw-tech-app" style="display:none;">
                        <div class="cw-tech-bar" id="cw-tech-bar"></div>
                        <div id="cw-tech-list-view" class="cw-tech-list-view cw-home">
                            <div class="cw-section-title">📋 صف کار من</div>
                            <div id="cw-tech-queue"></div>
                        </div>
                        <div id="cw-tech-chat-view" class="cw-tech-chat-view" style="display:none;">
                            <button type="button" class="cw-back-btn" id="cw-tech-back">◀ بازگشت به لیست</button>
                            <div id="cw-tech-job-info" class="cw-tech-job-info"></div>
                            <div class="cw-chat-area" id="cw-tech-msgs"></div>
                            <div class="cw-input-area" id="cw-tech-input-area">
                                <textarea class="cw-input" id="cw-tech-input" placeholder="پاسخ به مشتری..." rows="1"></textarea>
                                <button class="cw-send-btn" id="cw-tech-send" title="ارسال">➤</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Panel: Contact -->
            <div class="cw-panel" id="cw-panel-contact">
                <div class="cw-contact">
                    <div class="cw-contact-title">📞 راه‌های ارتباطی</div>
                    <div class="cw-contact-list">${contacts}</div>
                </div>
            </div>
        </div>`;

        document.body.appendChild(el.children[0]); // launcher
        document.body.appendChild(el.children[0]); // window
    }

    function _buildContacts() {
        let html = '';
        if (CFG.phone)
            html += `<a class="cw-contact-item" href="tel:${_e(CFG.phone)}">
                <div class="cw-contact-icon" style="background:#dcfce7;">📞</div>
                <div><div>${_e(CFG.phone)}</div><div class="cw-contact-label">تماس تلفنی</div></div>
            </a>`;
        if (CFG.whatsapp)
            html += `<a class="cw-contact-item" href="https://wa.me/${_e(CFG.whatsapp)}" target="_blank">
                <div class="cw-contact-icon" style="background:#dcfce7;">📱</div>
                <div><div>${_e(CFG.whatsapp)}</div><div class="cw-contact-label">واتساپ</div></div>
            </a>`;
        if (CFG.telegram)
            html += `<a class="cw-contact-item" href="https://t.me/${_e(CFG.telegram)}" target="_blank">
                <div class="cw-contact-icon" style="background:#dbeafe;">✈️</div>
                <div><div>@${_e(CFG.telegram)}</div><div class="cw-contact-label">تلگرام</div></div>
            </a>`;
        if (CFG.instagram)
            html += `<a class="cw-contact-item" href="https://instagram.com/${_e(CFG.instagram)}" target="_blank">
                <div class="cw-contact-icon" style="background:#fce7f3;">📸</div>
                <div><div>@${_e(CFG.instagram)}</div><div class="cw-contact-label">اینستاگرام</div></div>
            </a>`;
        if (!html)
            html = `<div style="color:#94a3b8;font-size:13px;text-align:center;padding:20px;">اطلاعات تماس تنظیم نشده است.</div>`;
        return html;
    }

    /* ── Events ────────────────────────────────────────── */
    function _bindEvents() {
        // launcher
        document.getElementById('acc-chat-launcher').addEventListener('click', _toggleOpen);

        // close
        document.getElementById('cw-close').addEventListener('click', _close);

        // tabs
        document.querySelectorAll('.cw-tab[data-tab]').forEach(btn => {
            btn.addEventListener('click', () => _switchTab(btn.dataset.tab));
        });

        // quick actions
        document.querySelectorAll('.cw-qa-btn[data-action]').forEach(btn => {
            btn.addEventListener('click', () => {
                const a = btn.dataset.action;
                if (a === 'start-chat') _switchTab('chat');
                if (a === 'go-ai') _switchTab('ai');
                if (a === 'go-contact') _switchTab('contact');
                if (a === 'go-services') _switchTab('services');
                if (a === 'go-track') { _switchTab('track'); _renderCasesList(); }
                if (a === 'go-tech') _switchTab('tech');
            });
        });

        document.getElementById('cw-tech-login-btn')?.addEventListener('click', _techDoLogin);
        document.getElementById('cw-tech-pass')?.addEventListener('keydown', e => {
            if (e.key === 'Enter') _techDoLogin();
        });
        document.getElementById('cw-tech-back')?.addEventListener('click', _techShowList);
        document.getElementById('cw-tech-send')?.addEventListener('click', _techSendMsg);
        document.getElementById('cw-tech-input')?.addEventListener('keydown', e => {
            if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); _techSendMsg(); }
        });

        document.getElementById('cw-track-btn')?.addEventListener('click', _lookupByCode);
        document.getElementById('cw-track-code')?.addEventListener('keydown', e => {
            if (e.key === 'Enter') _lookupByCode();
        });

        // start chat
        document.getElementById('cw-start-btn').addEventListener('click', _startChat);

        // send
        document.getElementById('cw-send').addEventListener('click', _sendMsg);
        document.getElementById('cw-input').addEventListener('keydown', e => {
            if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); _sendMsg(); }
        });

        // auto resize textarea
        document.getElementById('cw-input').addEventListener('input', function () {
            this.style.height = 'auto';
            this.style.height = Math.min(this.scrollHeight, 80) + 'px';
        });

        // close on outside click
        document.addEventListener('click', e => {
            if (!state.open) return;
            const win = document.getElementById('acc-chat-window');
            const launcher = document.getElementById('acc-chat-launcher');
            if (!win.contains(e.target) && !launcher.contains(e.target)) _close();
        });
    }

    /* ── Open / Close ──────────────────────────────────── */
    function _toggleOpen() {
        state.open ? _close() : _open();
    }

    function _open() {
        state.open = true;
        const win = document.getElementById('acc-chat-window');
        const launcher = document.getElementById('acc-chat-launcher');
        win.classList.add('open');
        document.body.classList.add('cw-open');
        if (launcher) launcher.classList.add('cw-hidden');
        state.unread = 0;
        _updateBadge();
        _renderServicesList();
        _renderRecentCases();
    }

    function _close() {
        state.open = false;
        _techStopPoll();
        const win = document.getElementById('acc-chat-window');
        const launcher = document.getElementById('acc-chat-launcher');
        win.classList.remove('open');
        document.body.classList.remove('cw-open');
        if (launcher) launcher.classList.remove('cw-hidden');
    }

    /* ── Tab Switch ────────────────────────────────────── */
    function _switchTab(tab) {
        state.tab = tab;
        document.querySelectorAll('.cw-tab').forEach(b => b.classList.toggle('active', b.dataset.tab === tab));
        document.querySelectorAll('.cw-panel').forEach(p => p.classList.toggle('active', p.id === `cw-panel-${tab}`));
        if (tab === 'chat' && state.started) _scrollBottom();
        if (tab === 'track') _renderCasesList();
        if (tab === 'services') _renderServicesList();
        if (tab === 'tech') _techOnTabOpen();
        const portalAI = _getPortalAI();
        if (tab === 'ai' && portalAI) {
            portalAI.mount(document.getElementById('cw-ai-mount'));
        }
    }

    /* ── Services Hub ─────────────────────────────────── */
    function _renderServicesList() {
        const el = document.getElementById('cw-services-list');
        const wiz = document.getElementById('cw-wizard');
        if (!el) return;
        if (state.wizardType) {
            _renderActiveWizard();
            return;
        }
        el.style.display = 'flex';
        if (wiz) wiz.style.display = 'none';
        el.innerHTML = `
            <div class="cw-section-title">انتخاب نوع خدمت</div>
            <div class="cw-service-grid">
                ${SERVICE_TYPES.map(s => `
                    <div class="cw-service-card" data-type="${s.key}">
                        <span class="cw-service-icon">${s.icon}</span>
                        <span class="cw-service-label">${s.title}</span>
                    </div>
                `).join('')}
            </div>`;
        el.querySelectorAll('.cw-service-card').forEach(c => {
            c.addEventListener('click', () => _openWizard(c.dataset.type));
        });
    }

    function _renderActiveWizard() {
        const type = state.wizardType;
        if (!type) return;
        const el = document.getElementById('cw-services-list');
        const wiz = document.getElementById('cw-wizard');
        if (!wiz) return;
        el.style.display = 'none';
        wiz.style.display = 'flex';
        const st = SERVICE_TYPES.find(s => s.key === type);

        if (PORTAL === 'education' && window.EduWizards) {
            wiz.innerHTML = '<button class="cw-back-btn" id="cw-wiz-back">◀ بازگشت</button><div id="cw-edu-wiz-body"></div>';
            const body = wiz.querySelector('#cw-edu-wiz-body');
            EduWizards.renderWizard(type, body);
            wiz.querySelector('#cw-wiz-back')?.addEventListener('click', () => {
                state.wizardType = null;
                _renderServicesList();
            });
            return;
        }

        if (window.SvcWizards) {
            wiz.innerHTML = '<div class="cw-empty">در حال بارگذاری فرم...</div>';
            SvcWizards.renderWizard(wiz, type, st?.title || '', st?.icon || '🔧',
                () => { state.wizardType = null; _renderServicesList(); },
                async (payload) => { await _submitServiceRequestPayload(payload); }
            ).catch(() => {
                wiz.innerHTML = `
                    <button class="cw-back-btn" id="cw-wiz-back">◀ بازگشت</button>
                    <div class="cw-empty" style="color:#b91c1c">خطا در بارگذاری فرم. لطفاً دوباره تلاش کنید.</div>`;
                wiz.querySelector('#cw-wiz-back')?.addEventListener('click', () => {
                    state.wizardType = null;
                    _renderServicesList();
                });
            });
            return;
        }

        wiz.innerHTML = `
            <button class="cw-back-btn" id="cw-wiz-back">◀ بازگشت</button>
            <div class="cw-section-title">${st?.icon ?? '🔧'} ${st?.title ?? ''}</div>
            <input class="cw-visitor-input" id="cw-w-name" placeholder="نام *" autocomplete="name">
            <input class="cw-visitor-input" id="cw-w-phone" type="tel" placeholder="موبایل *" dir="ltr" autocomplete="tel">
            <input class="cw-visitor-input" id="cw-w-site" placeholder="موضع / آدرس سایت *">
            <input class="cw-visitor-input" id="cw-w-device" placeholder="نوع دستگاه (چیلر / سردخانه)">
            <input class="cw-visitor-input" id="cw-w-brand" placeholder="برند">
            <textarea class="cw-visitor-input" id="cw-w-complaint" placeholder="شرح مشکل" rows="3"></textarea>
            <button class="cw-start-btn" id="cw-w-submit">✅ ثبت درخواست</button>`;
        wiz.querySelector('#cw-wiz-back')?.addEventListener('click', () => {
            state.wizardType = null;
            _renderServicesList();
        });
        wiz.querySelector('#cw-w-submit')?.addEventListener('click', _submitServiceRequest);
    }

    function _openWizard(type) {
        if (type === 'ai_advisor' && _getPortalAI()) {
            state.wizardType = null;
            _switchTab('ai');
            return;
        }
        state.wizardType = type;
        _renderActiveWizard();
    }

    async function _submitServiceRequestPayload(payload) {
        const portal = PORTAL;
        if (window.SvcWizards?.handleSubmit) {
            const handled = await window.SvcWizards.handleSubmit(payload, {
                setLoading: _setLoading,
                switchTab: _switchTab,
                onDone: () => { state.wizardType = null; _renderServicesList(); },
            });
            if (handled) return;
        }
        if (portal !== 'service') {
            await _submitPortalInquiry(payload);
            return;
        }
        _setLoading(true);
        try {
            const res = await _apiPost('/service/visitor/request', {
                session_key: state.sessionKey,
                ...payload,
                name: payload.name,
            });
            if (!res.success) {
                if (res.need_more_info && res.missing) {
                    alert('اطلاعات ناقص:\n' + (res.missing || []).join('\n'));
                } else {
                    alert(res.message || 'خطا');
                }
                return;
            }
            const d = res.data;
            if (d.consult_result?.tips?.length) {
                const tips = d.consult_result.tips.join('\n• ');
                alert('راهنمای اولیه:\n• ' + tips);
            }
            _saveCaseLocal({
                tracking_code: d.tracking_code,
                room_id: d.room_id,
                service_type_label: d.service_type_label,
                site_label: d.site_label,
                created_at: new Date().toISOString(),
            });
            state.wizardType = null;
            await _openCaseChat(d.tracking_code, d.room_id);
            _switchTab('chat');
            _renderServicesList();
        } catch {
            alert('خطا در ثبت درخواست');
        } finally {
            _setLoading(false);
        }
    }

    async function _submitPortalInquiry(payload) {
        _setLoading(true);
        try {
            const name = payload.name || 'بازدیدکننده';
            const lines = Object.entries(payload)
                .filter(([k, v]) => v && k !== 'service_type')
                .map(([k, v]) => `${k}: ${v}`);
            const msg = `📩 درخواست ${payload.service_type || 'عمومی'}\n` + lines.join('\n');
            const startRes = await _apiPost('/chat/support/start', {
                session_key: state.sessionKey,
                name,
                phone: payload.phone || '',
                page_url: location.href,
                portal: PORTAL,
                source: PORTAL,
            });
            if (!startRes.success) { alert(startRes.message || 'خطا'); return; }
            state.roomId = startRes.data?.room_id;
            state.trackingCode = startRes.data?.tracking_code || null;
            state.started = true;
            localStorage.setItem(_storeKey('acc_chat_room_') + state.sessionKey, state.roomId);
            if (state.trackingCode) localStorage.setItem('acc_chat_code_' + state.roomId, state.trackingCode);
            await _apiPost('/chat/visitor/message', {
                session_key: state.sessionKey,
                room_id: state.roomId,
                message: msg,
            });
            state.wizardType = null;
            document.getElementById('cw-visitor-form').style.display = 'none';
            document.getElementById('cw-input-area').style.display = 'flex';
            _switchTab('chat');
            _startPolling();
        } catch {
            alert('خطا در ارسال درخواست');
        } finally {
            _setLoading(false);
        }
    }

    async function _submitServiceRequest() {
        const name = document.getElementById('cw-w-name')?.value.trim();
        const phone = document.getElementById('cw-w-phone')?.value.trim();
        const site = document.getElementById('cw-w-site')?.value.trim();
        if (!name || !phone || !site) {
            alert('نام، موبایل و موضع الزامی است');
            return;
        }
        await _submitServiceRequestPayload({
            name, phone,
            service_type: state.wizardType,
            site_label: site,
            device_type: document.getElementById('cw-w-device')?.value.trim() || '',
            brand: document.getElementById('cw-w-brand')?.value.trim() || '',
            complaint_text: document.getElementById('cw-w-complaint')?.value.trim() || '',
        });
    }

    /* ── Cases / Track ──────────────────────────────────── */
    function _loadCasesLocal() {
        try {
            return JSON.parse(localStorage.getItem(_storeKey('acc_svc_cases')) || '[]');
        } catch { return []; }
    }

    function _saveCaseLocal(c) {
        state.cases = state.cases.filter(x => x.tracking_code !== c.tracking_code);
        state.cases.unshift(c);
        state.cases = state.cases.slice(0, 20);
        localStorage.setItem(_storeKey('acc_svc_cases'), JSON.stringify(state.cases));
        _renderRecentCases();
    }

    function _renderRecentCases() {
        const el = document.getElementById('cw-recent-cases');
        if (!el || !state.cases.length) { if (el) el.innerHTML = ''; return; }
        el.innerHTML = `
            <div class="cw-section-title">درخواست‌های اخیر</div>
            ${state.cases.slice(0, 3).map(c => _caseCardHtml(c)).join('')}`;
        el.querySelectorAll('[data-case-code]').forEach(btn => {
            btn.addEventListener('click', () => _openCaseChat(btn.dataset.caseCode, +btn.dataset.roomId));
        });
    }

    function _renderCasesList() {
        const el = document.getElementById('cw-cases-list');
        if (!el) return;
        if (!state.cases.length) {
            el.innerHTML = '<div class="cw-empty">هنوز درخواستی ثبت نشده — از تب «خدمت» شروع کنید.</div>';
            return;
        }
        el.innerHTML = state.cases.map(c => _caseCardHtml(c)).join('');
        el.querySelectorAll('.cw-case-card[data-case-code]').forEach(card => {
            card.addEventListener('click', async () => {
                const code = card.dataset.caseCode;
                try {
                    const res = await _apiFetch(`/service/visitor/track/${encodeURIComponent(code)}`);
                    if (res.success) _showTrackDetail(res.data);
                } catch { _showTrackDetail(null, 'خطا در بارگذاری'); }
            });
        });
    }

    function _caseCardHtml(c) {
        return `
            <div class="cw-case-card" data-case-code="${_e(c.tracking_code)}" data-room-id="${c.room_id || ''}" role="button">
                <div class="cw-case-code">${_e(c.tracking_code)}</div>
                <div class="cw-case-meta">${_e(c.service_type_label || '')} · ${_e(c.site_label || '')}</div>
            </div>`;
    }

    async function _lookupByCode() {
        const code = document.getElementById('cw-track-code')?.value.trim().toUpperCase();
        if (!code) return;
        _setLoading(true);
        try {
            const res = await _apiFetch(`/service/visitor/track/${encodeURIComponent(code)}`);
            if (!res.success) { _showTrackDetail(null, res.message); return; }
            const d = res.data;
            _saveCaseLocal({
                tracking_code: d.tracking_code,
                room_id: d.conversation_id,
                service_type_label: d.service_type_label,
                site_label: d.site_label,
            });
            _showTrackDetail(d);
            if (d.conversation_id) {
                document.querySelectorAll('.cw-case-card').forEach(c => {
                    c.addEventListener('click', () => _openCaseChat(c.dataset.caseCode, +c.dataset.roomId));
                });
            }
        } catch (e) {
            _showTrackDetail(null, e.message?.includes('HTTP') ? 'خطا در اتصال — کد را بررسی کنید' : 'کد یافت نشد');
        }
        finally { _setLoading(false); }
    }

    function _showTrackDetail(data, errMsg) {
        const el = document.getElementById('cw-track-detail');
        if (!el) return;
        el.style.display = 'block';
        if (!data) {
            el.innerHTML = `<div class="cw-empty" style="color:#dc2626;">${_e(errMsg || 'خطا')}</div>`;
            return;
        }
        const tl = (data.timeline || []).map(t =>
            `<div class="cw-tl-item"><span class="cw-tl-dot"></span><div><b>${_e(t.label)}</b><br><small>${_e((t.at||'').slice(0,16))}</small></div></div>`
        ).join('');
        const payBlock = data.payment && data.payment.balance > 0 ? `
            <div class="cw-pay-card">
                <div class="cw-pay-label">💳 مانده بدهی گزارش <b>${_e(data.payment.report_no)}</b></div>
                <div class="cw-pay-amount">${Number(data.payment.balance).toLocaleString('fa-IR')} <small>تومان</small></div>
                <button class="cw-start-btn cw-pay-btn" id="cw-pay-btn">پرداخت آنلاین</button>
            </div>` : '';
        const costBlock = data.cost_approval && data.cost_approval.can_approve ? `
            <div class="cw-pay-card" style="background:#fff7ed;border-color:#f59e0b;">
                <div class="cw-pay-label">💰 برآورد هزینه — نیاز به تأیید شما</div>
                <div class="cw-pay-amount">${Number(data.cost_approval.estimate).toLocaleString('fa-IR')} <small>ریال</small></div>
                <div style="display:flex;gap:8px;margin-top:8px;">
                    <button class="cw-start-btn" id="cw-cost-approve" style="flex:1;">✅ تأیید</button>
                    <button class="cw-start-btn" id="cw-cost-reject" style="flex:1;background:#fef2f2;color:#dc2626;">❌ رد</button>
                </div>
            </div>` : (data.cost_approval && data.cost_approval.approved ? `
            <div style="font-size:12px;color:#059669;margin:8px 0;">✅ هزینه تأیید شده</div>` : '');
        const reviewBlock = data.status === 'completed' ? `
            <div class="cw-section-title">ثبت نظر</div>
            <div style="padding:10px;background:#f8fafc;border-radius:8px;">
                <div style="margin-bottom:6px;">امتیاز: <select id="cw-review-rating" class="cw-visitor-input" style="width:auto;">
                    <option value="5">⭐⭐⭐⭐⭐</option><option value="4">⭐⭐⭐⭐</option>
                    <option value="3">⭐⭐⭐</option><option value="2">⭐⭐</option><option value="1">⭐</option>
                </select></div>
                <input id="cw-review-phone" class="cw-visitor-input" placeholder="موبایل شما" dir="ltr">
                <button class="cw-start-btn" id="cw-review-btn" style="margin-top:8px;width:100%;">ثبت نظر + امتیاز پاداش</button>
            </div>` : '';
        el.innerHTML = `
            <div class="cw-case-card" style="cursor:default;">
                <div class="cw-case-code">${_e(data.tracking_code)}</div>
                <div class="cw-case-meta">${_e(data.service_type_label)} · ${_e(data.site_label || '')}</div>
                <div style="margin-top:8px;font-size:12px;"><b>وضعیت:</b> ${_e(data.status_label)}
                    ${data.priority_label === 'فوری' ? ' · <span style="color:#dc2626;">🔴 فوری</span>' : ''}</div>
            </div>
            ${costBlock}
            ${payBlock}
            <div class="cw-section-title">زمان‌بندی</div>
            <div class="cw-timeline">${tl || '<div class="cw-empty">—</div>'}</div>
            ${reviewBlock}
            ${data.conversation_id ? `<button class="cw-start-btn" style="margin-top:12px;" id="cw-track-chat-btn">💬 گفتگوی این پرونده</button>` : ''}`;
        document.getElementById('cw-track-chat-btn')?.addEventListener('click', () =>
            _openCaseChat(data.tracking_code, data.conversation_id)
        );
        document.getElementById('cw-pay-btn')?.addEventListener('click', () => {
            if (data.payment?.pay_url) location.href = data.payment.pay_url;
        });
        document.getElementById('cw-cost-approve')?.addEventListener('click', async () => {
            try {
                await _apiPost('/service/visitor/approve-cost', { tracking_code: data.tracking_code, approved: true });
                alert('هزینه تأیید شد — کار تخصیص می‌شود.');
                const res = await _apiFetch(`/service/visitor/track/${encodeURIComponent(data.tracking_code)}`);
                if (res.success) _showTrackDetail(res.data);
            } catch { alert('خطا در تأیید'); }
        });
        document.getElementById('cw-cost-reject')?.addEventListener('click', async () => {
            if (!confirm('رد هزینه؟')) return;
            try {
                await _apiPost('/service/visitor/approve-cost', { tracking_code: data.tracking_code, approved: false });
                alert('رد شد — با پشتیبانی تماس بگیرید.');
                const res = await _apiFetch(`/service/visitor/track/${encodeURIComponent(data.tracking_code)}`);
                if (res.success) _showTrackDetail(res.data);
            } catch { alert('خطا'); }
        });
        document.getElementById('cw-review-btn')?.addEventListener('click', async () => {
            const phone = document.getElementById('cw-review-phone')?.value.trim();
            const rating = +(document.getElementById('cw-review-rating')?.value || 5);
            if (!phone) { alert('موبایل را وارد کنید'); return; }
            try {
                const res = await _apiPost('/service/visitor/review', {
                    tracking_code: data.tracking_code, phone, rating,
                });
                alert(res.message || 'نظر ثبت شد');
            } catch { alert('خطا در ثبت نظر'); }
        });
    }

    async function _openCaseChat(code, roomId) {
        state.trackingCode = code;
        state.roomId = roomId;
        state.activeCase = code;
        state.started = true;
        state.lastMsgId = 0;

        const bar = document.getElementById('cw-case-bar');
        if (bar) {
            bar.style.display = 'flex';
            bar.innerHTML = `<span>🎫 ${_e(code)}</span><button id="cw-case-switch" style="font-size:11px;background:transparent;border:none;color:#1d4ed8;cursor:pointer;">تغییر</button>`;
            document.getElementById('cw-case-switch')?.addEventListener('click', () => _switchTab('track'));
        }

        document.getElementById('cw-visitor-form').style.display = 'none';
        document.getElementById('cw-input-area').style.display = 'flex';
        document.getElementById('cw-chat-area').innerHTML = '';

        _setLoading(true);
        try {
            await _apiPost('/chat/support/start', {
                session_key: state.sessionKey,
                tracking_code: code,
                name: 'بازدیدکننده',
            });
            await _loadHistory();
            _startPolling();
        } catch { await _loadHistory(); _startPolling(); }
        finally { _setLoading(false); }
        _switchTab('chat');
    }

    /* ── Start Chat ────────────────────────────────────── */
    async function _startChat() {
        const wpUser        = CFG.wp_user;
        const name          = wpUser ? wpUser.name : document.getElementById('cw-vis-name')?.value.trim()  || '';
        const phone         = wpUser ? ''           : document.getElementById('cw-vis-phone')?.value.trim() || '';
        const email         = wpUser ? ''           : document.getElementById('cw-vis-email')?.value.trim() || '';
        const trackingInput = document.getElementById('cw-vis-code')?.value.trim().toUpperCase() || '';

        // اگر کد پیگیری وارد شده → نیازی به نام نیست
        if (!trackingInput && !name) {
            const nameEl = document.getElementById('cw-vis-name');
            if (nameEl) { nameEl.focus(); nameEl.style.borderColor = '#ef4444'; }
            return;
        }
        if (!trackingInput && !phone) {
            const phoneEl = document.getElementById('cw-vis-phone');
            if (phoneEl) { phoneEl.focus(); phoneEl.style.borderColor = '#ef4444'; }
            return;
        }

        _setLoading(true);
        try {
            const payload = { session_key: state.sessionKey, name, phone, email, page_url: location.href, portal: PORTAL, source: PORTAL };
            if (trackingInput) payload.tracking_code = trackingInput;

            const res = await _apiPost('/chat/support/start', payload);

            if (!res.success) {
                _appendSystemMsg('❌ ' + (res.message || 'خطا در شروع گفتگو'));
                return;
            }

            state.roomId       = res.data?.room_id;
            state.trackingCode = res.data?.tracking_code || null;
            state.started      = true;

            localStorage.setItem(_storeKey('acc_chat_room_') + state.sessionKey, state.roomId);
            if (state.trackingCode)
                localStorage.setItem('acc_chat_code_' + state.roomId, state.trackingCode);

            document.getElementById('cw-visitor-form').style.display = 'none';
            document.getElementById('cw-input-area').style.display = 'flex';

            if (res.data?.resumed) {
                await _loadHistory();
                _appendSystemMsg('📂 ادامه گفتگوی قبلی — کد: ' + state.trackingCode);
            } else {
                _showTrackingCode(state.trackingCode);
            }
            _startPolling();
        } catch (e) {
            _appendSystemMsg('❌ خطا در شروع گفتگو. لطفاً دوباره امتحان کنید.');
        } finally {
            _setLoading(false);
        }
    }

    /* ── نمایش کد پیگیری ──────────────────────────────── */
    function _showTrackingCode(code) {
        if (!code) return;
        const area = document.getElementById('cw-chat-area');
        const div  = document.createElement('div');
        div.className = 'cw-msg cw-msg--system';
        div.innerHTML = `
        <div class="cw-tracking-card">
            <div class="cw-tracking-label">🎫 کد پیگیری شما</div>
            <div class="cw-tracking-code" id="cw-tc-${code}">${code}</div>
            <div class="cw-tracking-hint">این کد را ذخیره کنید. از هر دستگاهی می‌توانید با این کد ادامه گفتگو را داشته باشید.</div>
            <button class="cw-copy-btn" onclick="navigator.clipboard?.writeText('${code}').then(()=>{this.textContent='✅ کپی شد!'});setTimeout(()=>{this.textContent='📋 کپی کد'},2000)">📋 کپی کد</button>
        </div>`;
        area.appendChild(div);
        _scrollBottom();
    }

    /* ── Send Message ──────────────────────────────────── */
    async function _sendMsg() {
        if (!state.roomId) return;
        const inp = document.getElementById('cw-input');
        const body = inp.value.trim();
        if (!body) return;

        inp.value = '';
        inp.style.height = 'auto';

        // نمایش فوری در UI
        _appendMsg({ body, sender_type: 'visitor', created_at: new Date().toISOString() });

        try {
            await _apiPost(`/chat/visitor/message`, {
                session_key: state.sessionKey,
                room_id: state.roomId,
                body,
            });
        } catch { /* پیام ارسال نشد */ }
    }

    /* ── Polling ───────────────────────────────────────── */
    function _startPolling() {
        if (state.polling) return;
        state.polling = true;
        _poll();
    }

    /* لود تاریخچه کامل (برای resume با کد پیگیری) */
    async function _loadHistory() {
        try {
            const res = await _apiFetch(
                `/chat/visitor/poll?session_key=${encodeURIComponent(state.sessionKey)}&room_id=${state.roomId}&last_id=0`
            );
            const msgs = res?.data?.messages ?? [];
            msgs.forEach(m => {
                _appendMsg(m);
                if (+m.id > state.lastMsgId) state.lastMsgId = +m.id;
            });
            _scrollBottom();
        } catch { /* ignore */ }
    }

    async function _poll() {
        if (!state.polling || !state.roomId) return;
        try {
            const res = await _apiFetch(
                `/chat/visitor/poll?session_key=${encodeURIComponent(state.sessionKey)}&room_id=${state.roomId}&last_id=${state.lastMsgId}`
            );
            const msgs = res?.data?.messages ?? [];
            msgs.forEach(m => {
                if (+m.id > state.lastMsgId) {
                    state.lastMsgId = +m.id;
                    // پیام‌های اپراتور و سیستم را نشان بده (پیام visitor قبلاً نمایش داده شده)
                    if (m.sender_type === 'agent' || m.sender_type === 'system') {
                        _appendMsg(m);
                        if (!state.open) {
                            state.unread++;
                            _updateBadge();
                            _notifySound();
                        }
                    }
                }
            });
        } catch { /* ignore */ }
        state.pollTimer = setTimeout(_poll, CFG.poll_ms);
    }

    /* ── Render Messages ───────────────────────────────── */
    function _appendMsg(m) {
        const area = document.getElementById('cw-chat-area');
        const time = _formatTime(m.created_at);
        const div  = document.createElement('div');
        const body = m.body || m.message || '';

        if (m.sender_type === 'system') {
            div.className = 'cw-msg cw-msg--system';
            div.innerHTML = `<div class="cw-msg-bubble" style="background:#f1f5f9;color:#475569;font-size:11px;text-align:center;">${_e(body)}</div>`;
        } else if (m.sender_type === 'visitor') {
            div.className = 'cw-msg cw-msg--out';
            div.innerHTML = `<div class="cw-msg-bubble">${_e(body)}<span class="cw-msg-time">${time}</span></div>`;
        } else {
            // agent
            div.className = 'cw-msg cw-msg--in';
            div.innerHTML = `<div class="cw-msg-avatar">🎧</div>
                             <div class="cw-msg-bubble">${_e(body)}<span class="cw-msg-time">${time}</span></div>`;
        }
        area.appendChild(div);
        _scrollBottom();
    }

    function _appendSystemMsg(text) {
        const area = document.getElementById('cw-chat-area');
        const div = document.createElement('div');
        div.className = 'cw-msg cw-msg--system';
        div.innerHTML = `<div class="cw-msg-bubble">${_e(text)}</div>`;
        area.appendChild(div);
        _scrollBottom();
    }

    /* ── Helpers ───────────────────────────────────────── */
    function _scrollBottom() {
        const area = document.getElementById('cw-chat-area');
        if (area) area.scrollTop = area.scrollHeight;
    }

    function _setLoading(on) {
        document.getElementById('cw-loading').classList.toggle('active', on);
    }

    function _updateBadge() {
        const badge = document.getElementById('cw-badge');
        if (!badge) return;
        if (state.unread > 0) {
            badge.textContent = state.unread > 9 ? '9+' : state.unread;
            badge.classList.add('show');
        } else {
            badge.classList.remove('show');
        }
    }

    function _notifySound() {
        try {
            const ctx = new (window.AudioContext || window.webkitAudioContext)();
            const o = ctx.createOscillator();
            const g = ctx.createGain();
            o.connect(g); g.connect(ctx.destination);
            o.frequency.value = 880;
            g.gain.setValueAtTime(0.1, ctx.currentTime);
            g.gain.exponentialRampToValueAtTime(0.0001, ctx.currentTime + 0.3);
            o.start(ctx.currentTime);
            o.stop(ctx.currentTime + 0.3);
        } catch { /* ignore */ }
    }

    function _formatTime(iso) {
        try {
            const d = new Date(iso);
            return d.toLocaleTimeString('fa-IR', { hour: '2-digit', minute: '2-digit' });
        } catch { return ''; }
    }

    function _getOrMakeSession() {
        const sk = _storeKey('acc_chat_session');
        let key = localStorage.getItem(sk);
        if (!key) {
            key = 'vis_' + PORTAL + '_' + Math.random().toString(36).slice(2) + Date.now().toString(36);
            localStorage.setItem(sk, key);
        }
        return key;
    }

    function _e(str) {
        return String(str ?? '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
    }

    /* ── Technician Panel (ویجت کارشناس) ─────────────── */
    const TECH_STORE_KEY = 'acc_tech_widget_session';

    function _techSaveSession() {
        if (!state.tech.token) {
            localStorage.removeItem(TECH_STORE_KEY);
            return;
        }
        localStorage.setItem(TECH_STORE_KEY, JSON.stringify({
            token: state.tech.token,
            user:  state.tech.user,
            role:  state.tech.role,
            isTech: state.tech.isTech,
        }));
    }

    function _techLoadSession() {
        try {
            const raw = localStorage.getItem(TECH_STORE_KEY);
            if (!raw) return false;
            const s = JSON.parse(raw);
            if (!s?.token) return false;
            state.tech.token  = s.token;
            state.tech.user   = s.user;
            state.tech.role   = s.role;
            state.tech.isTech = !!s.isTech;
            return true;
        } catch { return false; }
    }

    function _techGetToken() {
        return state.tech.token
            || sessionStorage.getItem('acc_token')
            || null;
    }

    async function _apiAuth(method, path, data) {
        const token = _techGetToken();
        if (!token) throw new Error('ورود کارشناس لازم است');
        const opts = {
            method,
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + token,
            },
        };
        if (data != null) opts.body = JSON.stringify(data);
        const r = await fetch(CFG.api_base + path, opts);
        let json = {};
        try { json = await r.json(); } catch { /* */ }
        if (!r.ok) {
            const msg = json.message || json.data?.message || (typeof json.code === 'string' ? json.code : '') || `HTTP ${r.status}`;
            throw new Error(msg);
        }
        return json;
    }

    async function _techOnTabOpen() {
        if (state.tech.isTech && state.tech.token) {
            _techShowApp();
            await _techLoadQueue();
            return;
        }
        if (_techLoadSession()) {
            try {
                await _techVerifyRole();
                _techShowApp();
                await _techLoadQueue();
                return;
            } catch {
                _techLogout(false);
            }
        }
        const erpToken = sessionStorage.getItem('acc_token');
        if (erpToken && !state.tech.token) {
            state.tech.token = erpToken;
            try {
                await _techVerifyRole();
                if (state.tech.isTech) {
                    _techShowApp();
                    await _techLoadQueue();
                    return;
                }
            } catch { /* */ }
            state.tech.token = null;
        }
        _techShowLogin();
    }

    async function _techDoLogin() {
        const user = document.getElementById('cw-tech-user')?.value?.trim();
        const pass = document.getElementById('cw-tech-pass')?.value || '';
        const errEl = document.getElementById('cw-tech-login-err');
        if (errEl) errEl.textContent = '';
        if (!user || !pass) {
            if (errEl) errEl.textContent = 'نام کاربری و رمز الزامی است';
            return;
        }
        _setLoading(true);
        try {
            const r = await fetch(CFG.api_base + '/public/auth/login', {
                method: 'POST',
                headers: _baseHeaders(),
                body: JSON.stringify({ username: user, password: pass }),
            });
            const res = await r.json().catch(() => ({}));
            if (!r.ok || !res.success || !res.token) {
                throw new Error(res.message || 'نام کاربری یا رمز اشتباه است');
            }
            state.tech.token = res.token;
            state.tech.user  = res.user;
            await _techVerifyRole();
            if (!state.tech.isTech) {
                state.tech.token = null;
                throw new Error('این حساب کارشناس میدانی نیست. از ERP برای کارشناس ارشد استفاده کنید.');
            }
            _techSaveSession();
            _techShowApp();
            await _techLoadQueue();
            document.getElementById('cw-tech-pass').value = '';
        } catch (e) {
            if (errEl) errEl.textContent = e.message || 'خطا در ورود';
        } finally {
            _setLoading(false);
        }
    }

    async function _techVerifyRole() {
        const res = await _apiAuth('GET', '/service/me/role');
        const d = res?.data || {};
        state.tech.role   = d.role || '';
        state.tech.isTech = !!(d.is_technician || d.role === 'technician');
        if (d.user_id && !state.tech.user) {
            state.tech.user = { id: d.user_id, name: 'کارشناس' };
        }
        if (!state.tech.isTech) {
            throw new Error('not technician');
        }
    }

    function _techShowLogin() {
        state.tech.view = 'login';
        document.getElementById('cw-tech-login').style.display = 'block';
        document.getElementById('cw-tech-app').style.display = 'none';
        _techStopPoll();
    }

    function _techShowApp() {
        state.tech.view = 'list';
        document.getElementById('cw-tech-login').style.display = 'none';
        document.getElementById('cw-tech-app').style.display = 'flex';
        _techRenderBar();
        _techShowList();
    }

    function _techRenderBar() {
        const bar = document.getElementById('cw-tech-bar');
        if (!bar) return;
        const name = state.tech.user?.name || state.tech.user?.username || 'کارشناس';
        bar.innerHTML = `
            <span>👷 <strong>${_e(name)}</strong></span>
            <button type="button" class="cw-tech-logout-btn" id="cw-tech-logout">خروج</button>`;
        document.getElementById('cw-tech-logout')?.addEventListener('click', () => _techLogout(true));
    }

    function _techLogout(clearForm) {
        state.tech.token = null;
        state.tech.user = null;
        state.tech.role = null;
        state.tech.isTech = false;
        state.tech.queue = [];
        state.tech.activeJob = null;
        localStorage.removeItem(TECH_STORE_KEY);
        _techStopPoll();
        _techShowLogin();
        if (clearForm) {
            const p = document.getElementById('cw-tech-pass');
            if (p) p.value = '';
        }
    }

    function _techShowList() {
        state.tech.view = 'list';
        state.tech.activeJob = null;
        state.tech.lastMsgId = 0;
        _techStopPoll();
        document.getElementById('cw-tech-list-view').style.display = 'block';
        document.getElementById('cw-tech-chat-view').style.display = 'none';
    }

    async function _techLoadQueue() {
        const el = document.getElementById('cw-tech-queue');
        if (!el) return;
        el.innerHTML = '<div class="cw-empty">⏳ بارگذاری...</div>';
        try {
            const res = await _apiAuth('GET', '/service/technician/my-queue');
            state.tech.queue = res?.data || [];
            _techRenderQueue();
        } catch (e) {
            if ((e.message || '').includes('401') || (e.message || '').includes('403')) {
                _techLogout(false);
                return;
            }
            el.innerHTML = `<div class="cw-empty" style="color:#dc2626;">❌ ${_e(e.message)}</div>`;
        }
    }

    function _techRenderQueue() {
        const el = document.getElementById('cw-tech-queue');
        if (!el) return;
        if (!state.tech.queue.length) {
            el.innerHTML = '<div class="cw-empty">📭 درخواست تخصیص‌یافته‌ای ندارید.<br><small>پس از Dispatch توسط ارشد اینجا ظاهر می‌شود.</small></div>';
            return;
        }
        const statusLbl = { submitted: 'ثبت', assigned: 'تخصیص', in_progress: 'در حال انجام' };
        el.innerHTML = state.tech.queue.map(j => `
            <div class="cw-case-card cw-tech-job-card" data-job-id="${j.id}">
                <div class="cw-case-code">${_e(j.tracking_code)} ${j.priority === 'urgent' ? '🔴' : ''}</div>
                <div style="font-size:13px;font-weight:600;margin-top:4px;">${_e(j.customer_name)}</div>
                <div class="cw-case-meta">${_e(j.service_type_label || j.service_type)} · ${_e(j.site_label || '—')}</div>
                ${j.dispatch_notes ? `<div style="font-size:10px;background:#fff7ed;color:#c2410c;padding:6px;border-radius:6px;margin-top:6px;">📋 ${_e(j.dispatch_notes)}</div>` : ''}
                ${j.phone ? `<div class="cw-case-meta" dir="ltr">📱 ${_e(j.phone)}</div>` : ''}
                <span class="cw-tech-status-pill">${_e(statusLbl[j.status] || j.status)}</span>
            </div>`).join('');
        el.querySelectorAll('.cw-tech-job-card').forEach(card => {
            card.addEventListener('click', () => {
                const job = state.tech.queue.find(x => x.id == card.dataset.jobId);
                if (job) _techOpenJob(job);
            });
        });
    }

    async function _techOpenJob(job) {
        state.tech.activeJob = job;
        state.tech.lastMsgId = 0;
        state.tech.view = 'chat';
        document.getElementById('cw-tech-list-view').style.display = 'none';
        document.getElementById('cw-tech-chat-view').style.display = 'flex';

        const info = document.getElementById('cw-tech-job-info');
        const stLbl = { submitted: 'ثبت شده', assigned: 'تخصیص', in_progress: 'در حال انجام' };
        info.innerHTML = `
            <div style="font-weight:700;">${_e(job.customer_name)}</div>
            <div style="font-family:monospace;color:#1d4ed8;font-weight:800;">${_e(job.tracking_code)}</div>
            <div style="font-size:11px;color:#64748b;">${_e(stLbl[job.status] || job.status)}</div>
            ${job.dispatch_notes ? `<div style="background:#fff7ed;padding:8px;border-radius:8px;font-size:11px;color:#c2410c;margin-top:6px;">👨‍💼 ${_e(job.dispatch_notes)}</div>` : ''}
            <div style="margin-top:8px;font-size:11px;color:#64748b;">برای SRD کامل از پورتال <a href="/acc-engine/service.php" target="_blank">service.php</a> استفاده کنید.</div>
            ${job.status !== 'in_progress' ? '<button type="button" class="cw-start-btn cw-tech-start-btn" id="cw-tech-start">▶ شروع کار میدانی</button>' : ''}`;

        document.getElementById('cw-tech-start')?.addEventListener('click', async () => {
            try {
                await _apiAuth('PUT', '/service/requests/' + job.id, { status: 'in_progress' });
                job.status = 'in_progress';
                await _techLoadQueue();
                _techOpenJob(state.tech.queue.find(x => x.id == job.id) || job);
            } catch (e) { alert(e.message); }
        });

        const msgs = document.getElementById('cw-tech-msgs');
        msgs.innerHTML = '';
        if (!job.conversation_id) {
            msgs.innerHTML = '<div class="cw-empty">گفتگوی چت برای این پرونده وجود ندارد</div>';
            return;
        }
        await _techLoadMessages(true);
        _techStartPoll();
    }

    async function _techLoadMessages(full) {
        const job = state.tech.activeJob;
        if (!job?.conversation_id) return;
        try {
            const res = await _apiAuth('GET', `/chat/support/rooms/${job.conversation_id}?last_id=${full ? 0 : state.tech.lastMsgId}`);
            const msgs = res?.data?.messages || [];
            const area = document.getElementById('cw-tech-msgs');
            if (full) {
                area.innerHTML = '';
                state.tech.lastMsgId = 0;
            }
            msgs.forEach(m => {
                if (+m.id > state.tech.lastMsgId) {
                    state.tech.lastMsgId = +m.id;
                    _techAppendMsg(m);
                }
            });
            area.scrollTop = area.scrollHeight;
        } catch (e) {
            if ((e.message || '').includes('مجاز نیست')) {
                document.getElementById('cw-tech-msgs').innerHTML = `<div class="cw-empty" style="color:#dc2626;">${_e(e.message)}</div>`;
            }
        }
    }

    function _techAppendMsg(m) {
        const area = document.getElementById('cw-tech-msgs');
        if (!area) return;
        const time = _formatTime(m.created_at);
        const body = m.body || m.message || '';
        const div = document.createElement('div');
        if (m.sender_type === 'system') {
            div.className = 'cw-msg cw-msg--system';
            div.innerHTML = `<div class="cw-msg-bubble" style="background:#f1f5f9;color:#475569;font-size:11px;text-align:center;">${_e(body)}</div>`;
        } else if (m.sender_type === 'agent' || m.sender_type === 'user') {
            div.className = 'cw-msg cw-msg--out';
            div.innerHTML = `<div class="cw-msg-bubble">${_e(body)}<span class="cw-msg-time">${time}</span></div>`;
        } else {
            div.className = 'cw-msg cw-msg--in';
            div.innerHTML = `<div class="cw-msg-avatar">🙋</div>
                <div class="cw-msg-bubble">${_e(body)}<span class="cw-msg-time">${time}</span></div>`;
        }
        area.appendChild(div);
    }

    async function _techSendMsg() {
        const job = state.tech.activeJob;
        const inp = document.getElementById('cw-tech-input');
        const body = inp?.value?.trim();
        if (!body || !job?.conversation_id) return;
        inp.value = '';
        try {
            await _apiAuth('POST', `/chat/support/rooms/${job.conversation_id}/reply`, { body });
            await _techLoadMessages(false);
        } catch (e) { alert(e.message); }
    }

    function _techStartPoll() {
        _techStopPoll();
        const tick = async () => {
            if (state.tech.view === 'chat' && state.tech.activeJob) {
                await _techLoadMessages(false);
            }
            state.tech.pollTimer = setTimeout(tick, CFG.poll_ms);
        };
        state.tech.pollTimer = setTimeout(tick, CFG.poll_ms);
    }

    function _techStopPoll() {
        if (state.tech.pollTimer) {
            clearTimeout(state.tech.pollTimer);
            state.tech.pollTimer = null;
        }
    }

    /* ── API helpers ───────────────────────────────────── */
    function _baseHeaders() {
        const h = { 'Content-Type': 'application/json' };
        if (CFG.nonce) h['X-WP-Nonce'] = CFG.nonce;
        return h;
    }

    async function _apiFetch(path) {
        const r = await fetch(CFG.api_base + path, {
            headers: _baseHeaders()
        });
        if (!r.ok) throw new Error(`HTTP ${r.status}`);
        return r.json();
    }

    async function _apiPost(path, data) {
        const r = await fetch(CFG.api_base + path, {
            method: 'POST',
            headers: _baseHeaders(),
            body: JSON.stringify(data),
        });
        if (!r.ok) throw new Error(`HTTP ${r.status}`);
        return r.json();
    }

    /* ── بازگردانی session — با تأیید از سرور ─────────── */
    async function _restoreSession(savedRoomId) {
        try {
            const res = await _apiFetch(
                `/chat/visitor/poll?session_key=${encodeURIComponent(state.sessionKey)}&room_id=${savedRoomId}&last_id=0`
            );
            state.roomId      = savedRoomId;
            state.started     = true;
            state.trackingCode = localStorage.getItem('acc_chat_code_' + savedRoomId) || null;

            document.getElementById('cw-visitor-form').style.display = 'none';
            document.getElementById('cw-input-area').style.display = 'flex';

            const msgs = res?.data?.messages ?? [];
            msgs.forEach(m => {
                _appendMsg(m);
                if (+m.id > state.lastMsgId) state.lastMsgId = +m.id;
            });
            if (!msgs.length) _appendSystemMsg('به گفتگو برگشتید.');
            _startPolling();
        } catch {
            localStorage.removeItem(_storeKey('acc_chat_room_') + state.sessionKey);
            state.roomId  = null;
            state.started = false;
        }
    }

    /* ── Init ──────────────────────────────────────────── */
    function init() {
        _buildHTML();
        _bindEvents();

        // اگر کاربر وردپرس لاگین است → فرم نام را مخفی کن
        if (CFG.wp_user) {
            const form = document.getElementById('cw-visitor-form');
            if (form) {
                form.innerHTML = `
                    <div style="padding:10px 14px;display:flex;align-items:center;gap:8px;background:#f0fdf4;border-radius:8px;font-size:12px;color:#166534;">
                        👤 <strong>${_e(CFG.wp_user.name)}</strong>
                        <button class="cw-start-btn" id="cw-start-btn" style="margin-right:auto;width:auto;padding:5px 14px;">🚀 شروع گفتگو</button>
                    </div>`;
                document.getElementById('cw-start-btn')?.addEventListener('click', _startChat);
            }
        }

        _renderRecentCases();
        _renderServicesList();
        _techLoadSession();

        // مخفی کردن تب‌های غیرفعال برای هر پورتال
        const allowedTabs = CFG.tabs || [ 'home', 'services', 'track', 'chat', 'tech', 'contact' ];
        document.querySelectorAll('.cw-tab').forEach(tab => {
            const t = tab.dataset.tab;
            tab.style.display = allowedTabs.includes(t) ? '' : 'none';
        });
        const qaTabMap = { 'go-ai': 'ai', 'go-services': 'services', 'go-track': 'track', 'start-chat': 'chat', 'go-tech': 'tech' };
        document.querySelectorAll('.cw-qa-btn[data-action]').forEach(btn => {
            const need = qaTabMap[btn.dataset.action];
            if (need && !allowedTabs.includes(need)) btn.style.display = 'none';
        });
        if (CFG.theme_color) {
            const launcher = document.querySelector('.cw-launcher-btn');
            if (launcher) launcher.style.background = CFG.theme_color;
        }
    }

    // ─── آیا روی صفحه SPA هستیم؟ ──────────────────────────
    // فقط ERP اصلی — نه پورتال‌های مستقل (shop/melk/…) که نامشان در URL است
    function _isOnSpaPage() {
        try {
            const path = (window.location.pathname || '').toLowerCase();
            if (/(?:^|\/)(?:shop|melk|service|education|election|wholesale|growth|dev)\.php\b/.test(path)) {
                return false;
            }
            if (path.includes('spa.php')) return true;
            if (/\/acc-engine\/?(?:index\.php)?$/.test(path)) return true;
            return false;
        } catch { return false; }
    }

    // ─── مخفی/نمایش لانچر ──────────────────────────────
    function _hideLauncher() {
        const btn = document.getElementById('acc-chat-launcher');
        const win = document.getElementById('acc-chat-window');
        if (btn) btn.style.display = 'none';
        if (win) win.style.display = 'none';
    }

    function _showLauncher() {
        const btn = document.getElementById('acc-chat-launcher');
        if (btn) btn.style.display = '';
    }

    // ─── گوش دادن به رویدادهای ERP login/logout ────────
    // AuthService بعد از login/logout این رویدادها را emit می‌کند
    window.addEventListener('erp:login', () => {
        if (_isOnSpaPage()) _hideLauncher();
    });

    window.addEventListener('erp:logout', () => {
        _showLauncher();
    });

    // ─── راه‌اندازی اولیه ──────────────────────────────
    // ویجت همیشه init می‌شود؛ اگر داخل ERP و لاگین → لانچر پنهان
    function _start() {
        init();
        // بررسی وضعیت اولیه (مثلاً refresh صفحه در حالت لاگین)
        if (_isOnSpaPage() && !! sessionStorage.getItem('acc_token')) {
            _hideLauncher();
        }
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', _start);
    } else {
        _start();
    }

})();
