/**
 * ElectionCandidateWidget.js — ویجت هوشمند کاندید برای پورتال هوادران
 */
export default class ElectionCandidateWidget {
    constructor(opts = {}) {
        this.api = (opts.api || window.ACC_ELECTION_CFG?.api || '/acc-engine/api.php/acc/v1').replace(/\/$/, '');
        this.token = opts.token || sessionStorage.getItem('acc_token') || '';
        this.hub = opts.hub || null;
        this.section = 'intro';
        this.open = false;
        this.chatHistory = [];
        this.loading = false;
        this.root = null;
    }

    setToken(t) { this.token = t || ''; }

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

    mdLite(text) {
        return this.esc(text)
            .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
            .replace(/_(.+?)_/g, '<em>$1</em>')
            .replace(/`([^`]+)`/g, '<code>$1</code>')
            .replace(/\n/g, '<br>');
    }

    async _req(method, path, body) {
        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(`${this.api}/${path.replace(/^\//, '')}`, opts);
        const j = await r.json().catch(() => ({}));
        if (!r.ok) throw new Error(j.message || `HTTP ${r.status}`);
        return j;
    }

    async loadHub() {
        if (this.hub) return this.hub;
        const r = await this._req('GET', 'public/election/candidate-hub');
        this.hub = r.data || {};
        return this.hub;
    }

    mount(container = document.body) {
        if (document.getElementById('el-candidate-widget')) return;
        const wrap = document.createElement('div');
        wrap.id = 'el-candidate-widget';
        wrap.innerHTML = `
            <button type="button" class="el-cw-launcher" id="el-cw-launcher" aria-label="راهنمای هوشمند کاندید">
                <span class="el-cw-launcher__icon">🗳️</span>
                <span class="el-cw-launcher__label">راهنمای کاندید</span>
            </button>
            <div class="el-cw-panel is-closed" id="el-cw-panel" hidden>
                <header class="el-cw-head">
                    <div class="el-cw-head__avatar" id="el-cw-avatar">🗳️</div>
                    <div class="el-cw-head__text">
                        <strong id="el-cw-name">راهنمای هوشمند</strong>
                        <small id="el-cw-sub">ستاد انتخابات</small>
                    </div>
                    <button type="button" class="el-cw-close" id="el-cw-close" aria-label="بستن">✕</button>
                </header>
                <nav class="el-cw-tabs" id="el-cw-tabs"></nav>
                <div class="el-cw-body" id="el-cw-body"></div>
            </div>`;
        container.appendChild(wrap);
        this.root = wrap;
        wrap.querySelector('#el-cw-launcher')?.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            this.toggle(true);
        });
        wrap.querySelector('#el-cw-close')?.addEventListener('click', (e) => {
            e.preventDefault();
            e.stopPropagation();
            this.toggle(false);
        });
        this.loadHub().then(() => this._paint()).catch(() => this._paintError());
    }

    toggle(on) {
        this.open = on ?? !this.open;
        const panel = this.root?.querySelector('#el-cw-panel');
        if (!panel) return;
        panel.hidden = !this.open;
        panel.classList.toggle('is-closed', !this.open);
        panel.setAttribute('aria-hidden', this.open ? 'false' : 'true');
    }

    _paintError() {
        const body = this.root?.querySelector('#el-cw-body');
        if (body) body.innerHTML = '<p class="el-empty">بارگذاری راهنما ناموفق بود</p>';
    }

    async _paint() {
        const hub = await this.loadHub();
        const p = hub.profile || {};
        const nameEl = this.root?.querySelector('#el-cw-name');
        const subEl = this.root?.querySelector('#el-cw-sub');
        const avEl = this.root?.querySelector('#el-cw-avatar');
        if (nameEl) nameEl.textContent = p.name || 'کاندید';
        if (subEl) subEl.textContent = p.title || '';
        if (avEl) {
            const photo = p.photo_url || '';
            avEl.innerHTML = photo
                ? `<img src="${this.esc(photo)}" alt="${this.esc(p.name || 'کاندید')}" width="44" height="44">`
                : (p.photo_emoji || '🗳️');
        }

        const tabs = this.root?.querySelector('#el-cw-tabs');
        if (tabs) {
            const sections = hub.sections || { intro: 'معرفی', slogans: 'شعار', programs: 'برنامه', suggest: 'پیشنهاد', chat: 'چت' };
            tabs.innerHTML = Object.entries(sections).map(([k, label]) =>
                `<button type="button" class="el-cw-tab ${k === this.section ? 'el-cw-tab--on' : ''}" data-sec="${k}">${this.esc(label.split(' ')[0])}</button>`
            ).join('');
            tabs.querySelectorAll('[data-sec]').forEach(btn => {
                btn.addEventListener('click', () => {
                    this.section = btn.dataset.sec;
                    this._paint();
                });
            });
        }

        const body = this.root?.querySelector('#el-cw-body');
        if (!body) return;
        switch (this.section) {
            case 'intro': body.innerHTML = this._introHtml(p); break;
            case 'slogans': body.innerHTML = this._slogansHtml(p); break;
            case 'programs': body.innerHTML = this._programsHtml(p); break;
            case 'standards':
                body.innerHTML = '<p class="el-cw-hint">⏳ بارگذاری گواهی OSCE…</p>';
                try {
                    const ir = await this._req('GET', 'public/election/integrity');
                    body.innerHTML = this._standardsHtml(ir.data);
                } catch { body.innerHTML = '<p class="el-empty">خطا در بارگذاری</p>'; }
                break;
            case 'sectors':
                body.innerHTML = '<p class="el-cw-hint">⏳ بارگذاری ماتریس اقشار…</p>';
                try {
                    const sr = this.token
                        ? await this._req('GET', 'election/sectors')
                        : await this._req('GET', 'public/election/integrity');
                    body.innerHTML = this.token ? this._sectorsHtml(sr.data) : this._sectorsPreviewHtml();
                    if (this.token) this._bindSectorEngage(body);
                } catch { body.innerHTML = this._sectorsPreviewHtml(); }
                break;
            case 'suggest': body.innerHTML = this._suggestHtml(p); this._bindSuggest(body); break;
            default: body.innerHTML = this._chatHtml(p); this._bindChat(body); break;
        }
        this._bindChips(body);
    }

    _chipsHtml(chips, prefix = '') {
        if (!chips?.length) return '';
        return `<div class="el-cw-chips">${chips.map(c =>
            `<button type="button" class="el-cw-chip" data-q="${this.esc(c)}" data-sec="${this.section}">${this.esc(c)}</button>`
        ).join('')}</div>`;
    }

    _bindChips(body) {
        body.querySelectorAll('.el-cw-chip[data-q]').forEach(btn => {
            btn.addEventListener('click', () => {
                const q = btn.dataset.q;
                if (this.section === 'suggest') {
                    const ta = body.querySelector('#el-cw-suggest-body');
                    if (ta) ta.value = (ta.value ? ta.value + '\n' : '') + q;
                    return;
                }
                this.section = 'chat';
                this.chatHistory.push({ role: 'user', content: q });
                this._paint().then(() => this._sendChat(q));
            });
        });
    }

    _introHtml(p) {
        const i = p.intro || {};
        const photo = p.photo_url
            ? `<figure class="el-cw-portrait">
                <img src="${this.esc(p.photo_url)}" alt="${this.esc(p.name || '')}" width="120" height="120">
                <figcaption>${this.esc(p.name || '')}<br><small>${this.esc(p.title || '')}</small></figcaption>
               </figure>`
            : '';
        return `<article class="el-cw-section">
            ${photo}
            <h3>${this.esc(i.headline)}</h3>
            <p>${this.esc(i.summary)}</p>
            <ul class="el-cw-list">${(i.highlights || []).map(h => `<li>${this.esc(h)}</li>`).join('')}</ul>
            ${this._chipsHtml(i.chips)}
            <p class="el-cw-hint">💡 روی هر پیشنهاد کلیک کنید یا به تب «چت» بروید</p>
        </article>`;
    }

    _slogansHtml(p) {
        const s = p.slogans || {};
        return `<article class="el-cw-section">
            <h3>شعارهای رسمی</h3>
            <div class="el-cw-slogans">${(s.items || []).map(it => `
                <blockquote class="el-cw-slogan">
                    <p>«${this.esc(it.text)}»</p>
                    <footer>${this.esc(it.context)}</footer>
                </blockquote>`).join('')}</div>
            ${this._chipsHtml(s.chips)}
        </article>`;
    }

    _programsHtml(p) {
        const pr = p.programs || {};
        return `<article class="el-cw-section">
            <h3>برنامه‌های کاندید</h3>
            ${(pr.pillars || []).map(pl => `
                <div class="el-cw-pillar">
                    <h4>${pl.icon || '📌'} ${this.esc(pl.title)}</h4>
                    <p>${this.esc(pl.body)}</p>
                    ${this._chipsHtml(pl.chips || [])}
                </div>`).join('')}
            ${this._chipsHtml(pr.chips)}
        </article>`;
    }

    _standardsHtml(d) {
        const c = d?.certificate || {};
        const pillars = d?.pillars || [];
        return `<article class="el-cw-section el-cw-standards">
            <div class="el-osce-cert">
                <span class="el-osce-cert__badge">${c.badge || '🏆'}</span>
                <div>
                    <strong>${this.esc(c.title || 'گواهی ACC-OSCE')}</strong>
                    <p>${this.esc(c.subtitle || '')} — <b>${d?.average ?? 0}/100</b></p>
                </div>
            </div>
            <p class="el-cw-hint">${this.esc(d?.framework || 'OSCE/ODIHR')}</p>
            ${pillars.map(p => `
                <div class="el-osce-pillar">
                    <div class="el-osce-pillar__head">
                        <code>${this.esc(p.code)}</code> ${this.esc(p.title)}
                        <span>${p.score}%</span>
                    </div>
                    <div class="el-segment-progress__bar"><span style="width:${Math.min(100, p.score)}%"></span></div>
                </div>`).join('')}
            ${this._chipsHtml(['کدام محور ضعیف است؟', 'برنامه اصناف', 'شفافیت مالی OSCE'])}
        </article>`;
    }

    _sectorsHtml(d) {
        const groups = d?.by_group || {};
        const labels = d?.group_labels || {};
        let html = `<article class="el-cw-section"><h3>👥 ماتریس اقشار (${this.esc(String(d?.total_engagements || 0))} تعامل)</h3>`;
        for (const [gk, items] of Object.entries(groups)) {
            html += `<h4 class="el-cw-group">${this.esc(labels[gk] || gk)}</h4><div class="el-cw-sector-grid">`;
            html += items.map(s => `
                <button type="button" class="el-cw-sector-card" data-sector="${s.slug}">
                    <span>${s.icon}</span><strong>${this.esc(s.title)}</strong>
                    <small>${this.esc(s.message?.slice(0, 50) || '')}…</small>
                    <em>${s.engagements || 0} رویداد</em>
                </button>`).join('');
            html += '</div>';
        }
        html += `<form class="el-cw-sector-form" id="el-cw-sector-form">
            <h4>ثبت تعامل میدانی</h4>
            <select name="sector_slug" required>${Object.entries(d?.sectors || {}).map(([k,v]) =>
                `<option value="${k}">${this.esc(v.title)}</option>`).join('')}</select>
            <input name="title" placeholder="عنوان جلسه" required>
            <input name="location" placeholder="محل">
            <input name="attendees" type="number" placeholder="تعداد" min="0">
            <button type="submit" class="el-btn el-btn--primary el-btn--sm">ثبت ✓</button>
            <div id="el-cw-sector-msg" class="el-msg"></div>
        </form></article>`;
        return html;
    }

    _sectorsPreviewHtml() {
        return `<article class="el-cw-section">
            <p>برای ماتریس کامل اقشار و ثبت تعامل، <strong>وارد شوید</strong>.</p>
            ${this._chipsHtml(['برنامه اصناف', 'جوانان دانشگاه', 'بانوان', 'OSCE یکپارچگی'])}
        </article>`;
    }

    _bindSectorEngage(body) {
        body.querySelectorAll('[data-sector]').forEach(btn => {
            btn.addEventListener('click', () => {
                this.section = 'chat';
                this._sendChat(`برنامه ${btn.dataset.sector}`);
            });
        });
        body.querySelector('#el-cw-sector-form')?.addEventListener('submit', async e => {
            e.preventDefault();
            const msg = body.querySelector('#el-cw-sector-msg');
            try {
                const r = await this._req('POST', 'election/sectors/engage', Object.fromEntries(new FormData(e.target)));
                msg.textContent = '✅ ' + (r.message || 'ثبت شد');
                msg.className = 'el-msg el-msg--ok';
                e.target.reset();
            } catch (err) {
                msg.textContent = err.message;
                msg.className = 'el-msg el-msg--err';
            }
        });
    }

    _suggestHtml(p) {
        const s = p.suggest || {};
        return `<article class="el-cw-section">
            <h3>📝 پیشنهاد برای کاندید</h3>
            <p>${this.esc(s.intro)}</p>
            ${this._chipsHtml(s.chips)}
            <form class="el-cw-suggest-form" id="el-cw-suggest-form">
                <label>نام<input name="author_name" placeholder="اختیاری"></label>
                <label>موبایل<input name="phone" dir="ltr" placeholder="0912..."></label>
                <label>بخش<select name="section">
                    <option value="intro">معرفی</option>
                    <option value="slogans">شعار</option>
                    <option value="programs">برنامه</option>
                    <option value="general">عمومی</option>
                </select></label>
                <label>متن پیشنهاد<textarea name="body" id="el-cw-suggest-body" rows="4" required placeholder="حداقل ۱۰ کاراکتر…"></textarea></label>
                <button type="submit" class="el-btn el-btn--primary el-btn--sm">ارسال پیشنهاد ✓</button>
                <div id="el-cw-suggest-msg" class="el-msg"></div>
            </form>
        </article>`;
    }

    _bindSuggest(body) {
        body.querySelector('#el-cw-suggest-form')?.addEventListener('submit', async e => {
            e.preventDefault();
            const msg = body.querySelector('#el-cw-suggest-msg');
            const fd = Object.fromEntries(new FormData(e.target));
            try {
                const path = this.token ? 'election/candidate/suggestions' : 'public/election/candidate/suggestions';
                const r = await this._req('POST', path, fd);
                msg.textContent = '✅ ' + (r.message || 'ثبت شد');
                msg.className = 'el-msg el-msg--ok';
                e.target.reset();
            } catch (err) {
                msg.textContent = err.message;
                msg.className = 'el-msg el-msg--err';
            }
        });
    }

    _chatHtml() {
        return `<article class="el-cw-section el-cw-chat">
            <div class="el-cw-msgs" id="el-cw-msgs"></div>
            <div class="el-cw-typing" id="el-cw-typing" hidden>در حال پاسخ…</div>
            <div class="el-cw-chips" id="el-cw-chat-chips"></div>
            <div class="el-cw-input-row">
                <textarea id="el-cw-input" rows="1" placeholder="سؤال درباره کاندید…"></textarea>
                <button type="button" id="el-cw-send">➤</button>
            </div>
        </article>`;
    }

    _bindChat(body) {
        const box = body.querySelector('#el-cw-msgs');
        if (box) {
            if (!this.chatHistory.length) {
                this.chatHistory.push({
                    role: 'assistant',
                    content: 'سلام! 🗳️ درباره معرفی، شعار، برنامه یا ثبت پیشنهاد کمکتان می‌کنم.',
                });
            }
            box.innerHTML = this.chatHistory.map(h => `
                <div class="el-cw-msg el-cw-msg--${h.role === 'user' ? 'user' : 'bot'}">
                    <div class="el-cw-msg__bubble">${this.mdLite(h.content)}</div>
                </div>`).join('');
            box.scrollTop = box.scrollHeight;
        }
        const send = () => {
            const inp = body.querySelector('#el-cw-input');
            const t = inp?.value?.trim();
            if (t) this._sendChat(t).then(() => { if (inp) inp.value = ''; });
        };
        body.querySelector('#el-cw-send')?.addEventListener('click', send);
        body.querySelector('#el-cw-input')?.addEventListener('keydown', e => {
            if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); }
        });
    }

    async _sendChat(text) {
        if (this.loading) return;
        this.loading = true;
        this.chatHistory.push({ role: 'user', content: text });
        const body = this.root?.querySelector('#el-cw-body');
        this._bindChat(body);
        const typing = body?.querySelector('#el-cw-typing');
        if (typing) typing.hidden = false;
        try {
            const r = await this._req('POST', 'public/election/candidate-hub/chat', {
                message: text,
                section: this.section === 'chat' ? 'chat' : this.section,
                history: this.chatHistory.slice(-8),
            });
            this.chatHistory.push({ role: 'assistant', content: r.reply || '' });
            const chips = body?.querySelector('#el-cw-chat-chips');
            if (chips && r.suggestions?.length) {
                chips.innerHTML = r.suggestions.map(c =>
                    `<button type="button" class="el-cw-chip" data-q="${this.esc(c)}">${this.esc(c)}</button>`
                ).join('');
                this._bindChips(body);
            }
        } catch (e) {
            this.chatHistory.push({ role: 'assistant', content: 'خطا در پاسخ — دوباره تلاش کنید.' });
        } finally {
            this.loading = false;
            if (typing) typing.hidden = true;
            this._bindChat(body);
        }
    }

    destroy() {
        this.root?.remove();
        this.root = null;
    }
}
