<?php   ?>
<style>
#tpsup, #tpsup * { box-sizing: border-box; }
#tpsup-bubble {
    position: fixed; right: 22px; bottom: 22px; z-index: 99980;
    display: inline-flex; align-items: center; gap: 9px;
    padding: 12px 18px 12px 15px; border: none; cursor: pointer;
    background: #2563eb; color: #fff; border-radius: 999px;
    font: 600 14px/1 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif;
    box-shadow: 0 10px 25px -5px rgba(37,99,235,.5), 0 4px 10px rgba(0,0,0,.12);
    transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
#tpsup-bubble:hover { background: #1d4ed8; transform: translateY(-2px); box-shadow: 0 14px 30px -6px rgba(37,99,235,.55); }
#tpsup-bubble i { font-size: 16px; }
#tpsup-bubble .tpsup-dot { position: absolute; top: -3px; right: -3px; min-width: 19px; height: 19px; padding: 0 5px; background: #ef4444; color: #fff; border-radius: 999px; font-size: 11px; font-weight: 700; display: none; align-items: center; justify-content: center; border: 2px solid #fff; }
#tpsup-panel {
    position: fixed; right: 22px; bottom: 22px; z-index: 99981;
    width: 390px; max-width: calc(100vw - 28px);
    height: 640px; max-height: calc(100vh - 100px);
    background: #fff; border-radius: 18px; overflow: hidden;
    display: none; flex-direction: column;
    box-shadow: 0 24px 60px -12px rgba(15,23,42,.32), 0 0 0 1px rgba(15,23,42,.05);
    font: 14px/1.5 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #0f172a;
}
#tpsup.open #tpsup-panel { display: flex; animation: tpsup-in .18s ease; }
#tpsup.open #tpsup-bubble { display: none; }
@keyframes tpsup-in { from { opacity: 0; transform: translateY(12px) scale(.98); } to { opacity: 1; transform: none; } }
.tpsup-head { background: linear-gradient(135deg,#2563eb,#1d4ed8); color: #fff; padding: 16px 16px 15px; display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.tpsup-head .tpsup-back { background: rgba(255,255,255,.15); border: none; color: #fff; width: 30px; height: 30px; border-radius: 8px; cursor: pointer; display: none; align-items: center; justify-content: center; flex-shrink: 0; }
.tpsup-head .tpsup-back:hover { background: rgba(255,255,255,.28); }
.tpsup-head .tpsup-htxt { flex: 1; min-width: 0; }
.tpsup-head h3 { margin: 0; font-size: 15.5px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tpsup-head p { margin: 2px 0 0; font-size: 12px; opacity: .85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tpsup-head .tpsup-x { background: rgba(255,255,255,.15); border: none; color: #fff; width: 30px; height: 30px; border-radius: 8px; cursor: pointer; flex-shrink: 0; }
.tpsup-head .tpsup-menu { background: rgba(255,255,255,.15); border: none; color: #fff; width: 30px; height: 30px; border-radius: 8px; cursor: pointer; flex-shrink: 0; display: none; align-items: center; justify-content: center; }
.tpsup-head .tpsup-menu:hover { background: rgba(255,255,255,.28); }
.tpsup-menuwrap { position: relative; flex-shrink: 0; }
.tpsup-dd { position: absolute; top: 38px; right: 0; z-index: 5; min-width: 178px; background: #fff; border: 1px solid #e7ecf3; border-radius: 12px; box-shadow: 0 16px 40px -8px rgba(15,23,42,.28); overflow: hidden; display: none; }
.tpsup-dd.open { display: block; animation: tpsup-dd-in .12s ease; }
@keyframes tpsup-dd-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.tpsup-dd button { display: flex; align-items: center; gap: 9px; width: 100%; padding: 10px 13px; border: none; background: #fff; color: #334155; font: inherit; font-size: 13px; text-align: left; cursor: pointer; }
.tpsup-dd button:hover { background: #f4f7fb; }
.tpsup-dd button i { width: 15px; text-align: center; color: #64748b; }
.tpsup-dd .tpsup-dd-danger, .tpsup-dd .tpsup-dd-danger i { color: #dc2626; }
.tpsup-dd hr { margin: 0; border: none; border-top: 1px solid #eef2f7; }
.tpsup-ddconfirm { padding: 12px 13px; }
.tpsup-ddconfirm p { margin: 0 0 10px; font-size: 12.5px; color: #334155; line-height: 1.45; }
.tpsup-ddconfirm .row { display: flex; gap: 7px; }
.tpsup-ddconfirm .row button { flex: 1; padding: 8px 10px; border-radius: 8px; font-size: 12.5px; font-weight: 600; cursor: pointer; border: 1px solid transparent; width: auto; }
.tpsup-ddconfirm .cancel { background: #eef2f7; color: #334155; }
.tpsup-ddconfirm .cancel:hover { background: #e2e8f0; }
.tpsup-ddconfirm .del { background: #dc2626; color: #fff; }
.tpsup-ddconfirm .del:hover { background: #b91c1c; }
.tpsup-ddconfirm .del:disabled { opacity: .6; cursor: default; }
.tpsup-head .tpsup-x:hover { background: rgba(255,255,255,.28); }
.tpsup-body { flex: 1; overflow-y: auto; background: #f8fafc; }
.tpsup-foot { flex-shrink: 0; border-top: 1px solid #e7ecf3; background: #fff; padding: 12px; }
.tpsup-btn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; width: 100%; padding: 11px 14px; border: none; border-radius: 10px; background: #2563eb; color: #fff; font-size: 14px; font-weight: 600; cursor: pointer; transition: background .15s; }
.tpsup-btn:hover { background: #1d4ed8; }
.tpsup-btn:disabled { opacity: .6; cursor: default; }
.tpsup-btn-ghost { background: #eef2f7; color: #334155; }
.tpsup-btn-ghost:hover { background: #e2e8f0; }
.tpsup-list { padding: 10px; display: flex; flex-direction: column; gap: 8px; }
.tpsup-card { background: #fff; border: 1px solid #e7ecf3; border-radius: 12px; padding: 12px 13px; cursor: pointer; transition: border-color .15s, box-shadow .15s; }
.tpsup-card:hover { border-color: #bfd3f3; box-shadow: 0 4px 14px -6px rgba(37,99,235,.25); }
.tpsup-card h4 { margin: 0 0 4px; font-size: 13.5px; font-weight: 600; color: #0f172a; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tpsup-card .tpsup-meta { font-size: 11.5px; color: #94a3b8; display: flex; align-items: center; gap: 6px; }
.tpsup-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; }
.tpsup-chip-blue { background: #eff6ff; color: #2563eb; }
.tpsup-chip-amber { background: #fffbeb; color: #b45309; }
.tpsup-chip-green { background: #ecfdf5; color: #059669; }
.tpsup-chip-gray { background: #f1f5f9; color: #64748b; }
.tpsup-empty { text-align: center; padding: 44px 24px; color: #94a3b8; }
.tpsup-empty i { font-size: 30px; margin-bottom: 12px; color: #cbd5e1; }
.tpsup-empty p { margin: 0; font-size: 13px; }
.tpsup-form { padding: 14px; display: flex; flex-direction: column; gap: 13px; }
.tpsup-field label { display: block; font-size: 12.5px; font-weight: 600; color: #334155; margin-bottom: 5px; }
.tpsup-field .req { color: #ef4444; }
.tpsup-input, .tpsup-textarea, .tpsup-select { width: 100%; padding: 9px 11px; border: 1px solid #d8e0ea; border-radius: 9px; font: inherit; font-size: 13.5px; color: #0f172a; background: #fff; }
.tpsup-input:focus, .tpsup-textarea:focus, .tpsup-select:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37,99,235,.12); }
.tpsup-input[readonly] { background: #f1f5f9; color: #64748b; }
.tpsup-textarea { resize: vertical; min-height: 92px; }
.tpsup-row { display: flex; gap: 10px; }
.tpsup-row > * { flex: 1; min-width: 0; }
.tpsup-acc { border: 1px solid #e7ecf3; border-radius: 11px; overflow: hidden; background: #fff; }
.tpsup-acc > summary { list-style: none; cursor: pointer; padding: 11px 13px; font-size: 12.8px; font-weight: 600; color: #334155; display: flex; align-items: center; gap: 8px; }
.tpsup-acc > summary::-webkit-details-marker { display: none; }
.tpsup-acc > summary .chev { margin-left: auto; transition: transform .15s; color: #94a3b8; font-size: 12px; }
.tpsup-acc[open] > summary .chev { transform: rotate(180deg); }
.tpsup-acc-body { padding: 4px 13px 14px; display: flex; flex-direction: column; gap: 11px; }
.tpsup-reqbox { border: 1px solid #fcd9a8; background: #fffdf7; border-radius: 11px; padding: 12px 13px; display: flex; flex-direction: column; gap: 11px; }
.tpsup-reqbox-h { font-size: 12.8px; font-weight: 700; color: #92400e; display: flex; align-items: center; gap: 8px; }
.tpsup-reqbox-h .tpsup-reqtag { margin-left: auto; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: #b45309; background: #fef3c7; padding: 2px 7px; border-radius: 999px; }
.tpsup-note { font-size: 11.5px; color: #64748b; background: #f8fafc; border: 1px solid #e7ecf3; border-radius: 8px; padding: 8px 10px; display: flex; gap: 7px; }
.tpsup-note.warn { background: #fffbeb; border-color: #fde68a; color: #92400e; }
.tpsup-note i { margin-top: 1px; }
.tpsup-drop { border: 1.5px dashed #cbd5e1; border-radius: 10px; padding: 14px; text-align: center; color: #64748b; font-size: 12.5px; cursor: pointer; background: #fff; }
.tpsup-drop:hover { border-color: #2563eb; color: #2563eb; }
.tpsup-thumbs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 9px; }
.tpsup-thumb { position: relative; width: 58px; height: 58px; border-radius: 8px; overflow: hidden; border: 1px solid #e2e8f0; }
.tpsup-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tpsup-thumb button { position: absolute; top: -6px; right: -6px; width: 18px; height: 18px; border-radius: 50%; background: #ef4444; color: #fff; border: 2px solid #fff; font-size: 9px; cursor: pointer; line-height: 1; padding: 0; }
.tpsup-thread { padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.tpsup-msg { max-width: 86%; }
.tpsup-msg.staff { align-self: flex-start; }
.tpsup-msg.client { align-self: flex-end; }
.tpsup-bubble2 { padding: 9px 12px; border-radius: 13px; font-size: 13.3px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
.tpsup-msg.staff .tpsup-bubble2 { background: #fff; border: 1px solid #e7ecf3; color: #1e293b; border-bottom-left-radius: 4px; }
.tpsup-msg.client .tpsup-bubble2 { background: #2563eb; color: #fff; border-bottom-right-radius: 4px; }
.tpsup-msg .tpsup-msg-h { font-size: 11px; color: #94a3b8; margin-bottom: 3px; display: flex; align-items: center; gap: 5px; }
.tpsup-msg.client .tpsup-msg-h { justify-content: flex-end; }
.tpsup-att { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.tpsup-att a { display: block; width: 64px; height: 50px; border-radius: 7px; overflow: hidden; border: 1px solid rgba(0,0,0,.1); }
.tpsup-att img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tpsup-reply { display: flex; gap: 8px; align-items: flex-end; }
.tpsup-reply textarea { flex: 1; min-height: 42px; max-height: 120px; resize: none; }
.tpsup-icon-btn { width: 40px; height: 40px; border-radius: 10px; border: 1px solid #d8e0ea; background: #fff; color: #475569; cursor: pointer; flex-shrink: 0; }
.tpsup-icon-btn:hover { background: #f1f5f9; }
.tpsup-send { width: 40px; height: 40px; border-radius: 10px; border: none; background: #2563eb; color: #fff; cursor: pointer; flex-shrink: 0; }
.tpsup-send:hover { background: #1d4ed8; }
.tpsup-spin { display: inline-block; animation: tpsup-rot 1s linear infinite; }
@keyframes tpsup-rot { to { transform: rotate(360deg); } }
.tpsup-connect { padding: 30px 22px; text-align: center; }
.tpsup-connect .tpsup-cmark { width: 64px; height: 64px; margin: 6px auto 16px; border-radius: 18px; background: linear-gradient(135deg,#2563eb,#1d4ed8); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 26px; box-shadow: 0 12px 24px -8px rgba(37,99,235,.6); }
.tpsup-connect h4 { margin: 0 0 8px; font-size: 17px; font-weight: 700; color: #0f172a; }
.tpsup-connect p { margin: 0 auto 18px; font-size: 13px; color: #64748b; max-width: 280px; }
.tpsup-connect .tpsup-manual { margin-top: 14px; }
.tpsup-connect .tpsup-manual summary { cursor: pointer; font-size: 12px; color: #2563eb; list-style: none; }
.tpsup-connect .tpsup-manual summary::-webkit-details-marker { display: none; }
.tpsup-connect .tpsup-manual .tpsup-field { text-align: left; margin-top: 10px; }
 
.tpsup-card.tpsup-unseen { border-color: #93b8f0; box-shadow: inset 3px 0 0 #2563eb, 0 4px 14px -8px rgba(37,99,235,.35); }
.tpsup-card.tpsup-unseen h4 { font-weight: 700; }
.tpsup-card.tpsup-unseen h4::before { content: ''; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #2563eb; margin-right: 6px; }
#tpsup-bubble.tpsup-alert { animation: tpsup-ring 1.8s ease-in-out infinite; }
@keyframes tpsup-ring {
    0%, 100% { box-shadow: 0 10px 25px -5px rgba(37,99,235,.5), 0 4px 10px rgba(0,0,0,.12), 0 0 0 0 rgba(239,68,68,.55); }
    50% { box-shadow: 0 10px 25px -5px rgba(37,99,235,.5), 0 4px 10px rgba(0,0,0,.12), 0 0 0 10px rgba(239,68,68,0); }
}
 
#tpsidebar-chat { position: relative; background: #2563eb; box-shadow: 0 2px 8px -2px rgba(37,99,235,.55); }
#tpsidebar-chat:hover { background: #1d4ed8; }
#tpsidebar-chat .tpsidebar-chat-chip { display: none; position: absolute; top: -5px; right: -5px; min-width: 17px; height: 17px; padding: 0 4px; align-items: center; justify-content: center; background: #ef4444; color: #fff; border-radius: 999px; font-size: 10px; font-weight: 800; line-height: 1; border: 2px solid #111827; }
#tpsidebar-chat.tpsup-alert .tpsidebar-chat-chip { display: inline-flex; }
#tpsidebar-chat.tpsup-alert { animation: tpsup-sidebar-ring 1.8s ease-in-out infinite; }
#tpsidebar-chat.tpsup-alert svg { animation: tpsup-bell 1.8s ease-in-out infinite; transform-origin: 50% 50%; }
@keyframes tpsup-sidebar-ring {
    0%, 100% { box-shadow: 0 0 0 0 rgba(239,68,68,.65); transform: scale(1); }
    50% { box-shadow: 0 0 0 9px rgba(239,68,68,0); transform: scale(1.03); }
}
@keyframes tpsup-bell {
    0%, 60%, 100% { transform: rotate(0); }
    8% { transform: rotate(12deg); } 16% { transform: rotate(-10deg); } 24% { transform: rotate(7deg); } 32% { transform: rotate(-5deg); } 40% { transform: rotate(0); }
}
.tpsup-toast { position: fixed; right: 22px; bottom: 92px; z-index: 99990; background: #0f172a; color: #fff; padding: 10px 15px; border-radius: 10px; font-size: 13px; box-shadow: 0 10px 30px rgba(0,0,0,.25); display: none; max-width: 320px; }
@media (max-width: 480px) {
    #tpsup-panel { right: 8px; left: 8px; bottom: 8px; width: auto; max-height: calc(100vh - 16px); height: auto; }
    #tpsup-bubble { right: 14px; bottom: 14px; }
}
</style>

<div id="tpsup">
    <button id="tpsup-bubble" type="button" aria-label="Open support">
        <i class="fa-solid fa-headset"></i><span>Support</span>
        <span class="tpsup-dot" id="tpsup-dot">0</span>
    </button>
    <div id="tpsup-panel" role="dialog" aria-label="Support">
        <div class="tpsup-head">
            <button class="tpsup-back" id="tpsup-back" type="button" aria-label="Back"><i class="fa-solid fa-arrow-left"></i></button>
            <div class="tpsup-htxt">
                <h3 id="tpsup-title">Support</h3>
                <p id="tpsup-sub">How can we help?</p>
            </div>
            <div class="tpsup-menuwrap">
                <button class="tpsup-menu" id="tpsup-menu" type="button" aria-label="Ticket actions" aria-haspopup="true"><i class="fa-solid fa-ellipsis-vertical"></i></button>
                <div class="tpsup-dd" id="tpsup-dd"></div>
            </div>
            <button class="tpsup-x" id="tpsup-close" type="button" aria-label="Close"><i class="fa-solid fa-xmark"></i></button>
        </div>
        <div class="tpsup-body" id="tpsup-body"></div>
        <div class="tpsup-foot" id="tpsup-foot" style="display:none"></div>
    </div>
</div>
<div class="tpsup-toast" id="tpsup-toast"></div>

<script>
(function () {
    if (window.__tpSupportInit) return; window.__tpSupportInit = true;

    var CSRF = '<?= Router::csrfToken() ?>';
    var ctx = null, currentTicket = null, files = [], replyFiles = [], view = 'home', connecting = false, pollTimer = null;
    var lastTickets = null, unseen = [];
    var ackNext = false; 

    var root = document.getElementById('tpsup');
    var body = document.getElementById('tpsup-body');
    var foot = document.getElementById('tpsup-foot');
    var titleEl = document.getElementById('tpsup-title');
    var subEl = document.getElementById('tpsup-sub');
    var backBtn = document.getElementById('tpsup-back');

    function esc(s) { var d = document.createElement('div'); d.textContent = s == null ? '' : String(s); return d.innerHTML; }
    function toast(msg) { var t = document.getElementById('tpsup-toast'); t.textContent = msg; t.style.display = 'block'; clearTimeout(t._t); t._t = setTimeout(function () { t.style.display = 'none'; }, 3200); }
    function relTime(s) { if (!s) return ''; var d = new Date(String(s).replace(' ', 'T')); var diff = (Date.now() - d.getTime()) / 1000; if (isNaN(diff)) return ''; if (diff < 60) return 'just now'; if (diff < 3600) return Math.floor(diff / 60) + 'm ago'; if (diff < 86400) return Math.floor(diff / 3600) + 'h ago'; if (diff < 604800) return Math.floor(diff / 86400) + 'd ago'; return d.toLocaleDateString(); }

    function statusChip(t) {
        if (t.status === 'resolved') return '<span class="tpsup-chip tpsup-chip-green"><i class="fa-solid fa-circle-check"></i> Resolved</span>';
        if (t.status === 'closed') return '<span class="tpsup-chip tpsup-chip-gray"><i class="fa-solid fa-lock"></i> Closed</span>';
        if (t.awaiting === 'you') return '<span class="tpsup-chip tpsup-chip-amber"><i class="fa-solid fa-reply"></i> Reply needed</span>';
        return '<span class="tpsup-chip tpsup-chip-blue"><i class="fa-solid fa-spinner"></i> In progress</span>';
    }

    function api(path, opts) {
        opts = opts || {}; opts.credentials = 'same-origin';
        opts.headers = opts.headers || {}; opts.headers['X-CSRF-TOKEN'] = CSRF;
        return fetch(path, opts).then(function (r) { return r.json().then(function (j) { return { ok: r.ok, j: j }; }).catch(function () { return { ok: r.ok, j: {} }; }); });
    }
    function loadContext() { return api('/admin/support/context').then(function (res) { ctx = res.j || {}; return ctx; }); }
    function ensureCtx() { return ctx ? Promise.resolve(ctx) : loadContext(); }

    
    var STATE_KEY = 'tpsup_state_v1', SEEN_KEY = 'tpsup_seen_v1';
    function lsGet(k) { try { return localStorage.getItem(k); } catch (e) { return null; } }
    function lsSet(k, v) { try { localStorage.setItem(k, v); } catch (e) {} }
    function lsDel(k) { try { localStorage.removeItem(k); } catch (e) {} }
    function persist(v, t) { lsSet(STATE_KEY, JSON.stringify({ o: 1, v: v, t: t || null })); }
    function persistClosed() { lsSet(STATE_KEY, JSON.stringify({ o: 0 })); }
    function seenMap() { var raw = lsGet(SEEN_KEY); if (!raw) return null; try { return JSON.parse(raw) || {}; } catch (e) { return {}; } }
    function saveSeen(m) { lsSet(SEEN_KEY, JSON.stringify(m)); }
    function isUnseen(t, m) { return t.awaiting === 'you' && t.status !== 'closed' && String((m || {})[String(t.id)] || '') < String(t.last_message_at || t.updated_at || '0'); }
    function markSeen(t) {
        if (!t || !t.id) return;
        var m = seenMap() || {};
        var last = String(t.last_message_at || t.updated_at || '');
        var msgs = t.messages || [];
        if (msgs.length) { var lm = msgs[msgs.length - 1]; if (lm && lm.created_at && String(lm.created_at) > last) last = String(lm.created_at); }
        m[String(t.id)] = last || '1';
        saveSeen(m);
        if (lastTickets) {
            lastTickets.forEach(function (x) {
                if (String(x.id) !== String(t.id)) return;
                x.status = t.status;
                x.last_message_at = t.last_message_at || x.last_message_at;
                if (msgs.length) x.awaiting = (msgs[msgs.length - 1].role === 'staff') ? 'you' : 'support';
            });
        }
        computeIndicators();
    }
    function ingestTickets(tickets) {
        lastTickets = tickets || [];
        if (seenMap() === null) {
            
            
            
            var m = {};
            lastTickets.forEach(function (t) {
                if (!(t.awaiting === 'you' && (t.status === 'open' || t.status === 'pending'))) {
                    m[String(t.id)] = String(t.last_message_at || t.updated_at || '1');
                }
            });
            saveSeen(m);
        }
        computeIndicators();
    }
    function computeIndicators() {
        var m = seenMap() || {};
        var list = lastTickets || [];
        
        unseen = list.filter(function (t) { return isUnseen(t, m); })
                     .sort(function (a, b) { return String(b.last_message_at || b.updated_at || '').localeCompare(String(a.last_message_at || a.updated_at || '')); });
        updateBadge(list.filter(function (t) { return t.awaiting === 'you' && t.status !== 'closed'; }).length);
        var bub = document.getElementById('tpsup-bubble');
        if (bub) bub.classList.toggle('tpsup-alert', unseen.length > 0);
        var sb = document.getElementById('tpsidebar-chat');
        if (sb) {
            sb.classList.toggle('tpsup-alert', unseen.length > 0);
            sb.title = unseen.length === 1 ? 'New support reply — click to read it' : (unseen.length > 1 ? unseen.length + ' new replies — click to open the latest' : 'Support — open your tickets');
            var chip = document.getElementById('tpsidebar-chat-chip');
            if (chip) chip.textContent = unseen.length > 9 ? '9+' : String(unseen.length);
        }
    }
    function setHeader(t, s, showBack) { titleEl.textContent = t; subEl.textContent = s || ''; backBtn.style.display = showBack ? 'flex' : 'none'; closeTicketMenu(); var mb = document.getElementById('tpsup-menu'); if (mb) mb.style.display = 'none'; }

    
    var ddOpen = false;
    function closeTicketMenu() { var dd = document.getElementById('tpsup-dd'); if (dd) { dd.classList.remove('open'); dd.innerHTML = ''; } ddOpen = false; }
    function renderTicketMenu(t) {
        var dd = document.getElementById('tpsup-dd'); if (!dd) return;
        var closeRow = (t.status === 'closed') ? '' : '<button type="button" data-act="close"><i class="fa-solid fa-circle-check"></i> Close ticket</button><hr>';
        dd.innerHTML = closeRow + '<button type="button" class="tpsup-dd-danger" data-act="del"><i class="fa-solid fa-trash-can"></i> Delete ticket</button>';
        dd.querySelectorAll('button').forEach(function (b) {
            b.addEventListener('click', function (e) {
                e.stopPropagation();
                if (b.getAttribute('data-act') === 'close') { closeTicket(t); } else { confirmDeleteTicket(t); }
            });
        });
    }
    function toggleTicketMenu(t) {
        var dd = document.getElementById('tpsup-dd'); if (!dd) return;
        if (ddOpen) { closeTicketMenu(); return; }
        renderTicketMenu(t); dd.classList.add('open'); ddOpen = true;
    }
    function confirmDeleteTicket(t) {
        var dd = document.getElementById('tpsup-dd'); if (!dd) return;
        dd.innerHTML = '<div class="tpsup-ddconfirm"><p>Delete this ticket and its whole conversation? This cannot be undone.</p><div class="row"><button type="button" class="cancel">Cancel</button><button type="button" class="del">Delete</button></div></div>';
        dd.querySelector('.cancel').addEventListener('click', function (e) { e.stopPropagation(); renderTicketMenu(t); });
        dd.querySelector('.del').addEventListener('click', function (e) { e.stopPropagation(); deleteTicket(t, e.currentTarget); });
    }
    function closeTicket(t) {
        closeTicketMenu();
        api('/admin/support/tickets/' + t.id + '/close', { method: 'POST' }).then(function (res) {
            if (res.ok && res.j.success && res.j.ticket) {
                toast('Ticket closed.');
                forgetSeen(t.id);
                if (lastTickets) { lastTickets.forEach(function (x) { if (String(x.id) === String(t.id)) { x.status = 'closed'; x.awaiting = 'support'; } }); }
                computeIndicators();
                renderThread(res.j.ticket);
            } else { toast(res.j.error || 'Could not close the ticket.'); }
        }).catch(function () { toast('Network error.'); });
    }
    function deleteTicket(t, btn) {
        if (btn) { btn.disabled = true; btn.textContent = 'Deleting…'; }
        api('/admin/support/tickets/' + t.id + '/delete', { method: 'POST' }).then(function (res) {
            if (res.ok && res.j.success) {
                closeTicketMenu();
                toast('Ticket deleted.');
                if (lastTickets) { lastTickets = lastTickets.filter(function (x) { return String(x.id) !== String(t.id); }); }
                forgetSeen(t.id);
                var st = lsGet(STATE_KEY);
                if (st) { try { var o = JSON.parse(st); if (o && String(o.t) === String(t.id)) persist('home'); } catch (e) {} }
                lsDel('tpsup_draft_' + t.id);
                computeIndicators();
                showHome();
            } else {
                if (btn) { btn.disabled = false; btn.textContent = 'Delete'; }
                toast(res.j.error || 'Could not delete the ticket.');
            }
        }).catch(function () { if (btn) { btn.disabled = false; btn.textContent = 'Delete'; } toast('Network error.'); });
    }
    function forgetSeen(id) { var m = seenMap(); if (m && m[String(id)] !== undefined) { delete m[String(id)]; saveSeen(m); } }

    
    function showConnect() {
        view = 'connect'; foot.style.display = 'none';
        persist('connect');
        setHeader('Support', 'Connect to get started', false);
        body.innerHTML = '<div class="tpsup-connect">'
            + '<div class="tpsup-cmark"><i class="fa-solid fa-headset"></i></div>'
            + '<h4>Connect to TubePress</h4>'
            + '<p>Link your TubePress account to open and track support tickets — the same connection used for the catalogue.</p>'
            + '<button class="tpsup-btn" id="tpsup-connectbtn"><i class="fa-solid fa-plug"></i> Connect TubePress account</button>'
            + '<details class="tpsup-manual"><summary>Enter API keys manually</summary>'
            +   '<div class="tpsup-field"><label>API key</label><input class="tpsup-input" id="tpsup-mkey" placeholder="tp_…" autocomplete="off"></div>'
            +   '<div class="tpsup-field"><label>API secret</label><input class="tpsup-input" id="tpsup-msecret" type="password" placeholder="••••••••" autocomplete="off"></div>'
            +   '<button class="tpsup-btn tpsup-btn-ghost" id="tpsup-savekeys" style="margin-top:6px"><i class="fa-solid fa-floppy-disk"></i> Save &amp; connect</button>'
            + '</details>'
            + '</div>';
        document.getElementById('tpsup-connectbtn').addEventListener('click', startConnect);
        document.getElementById('tpsup-savekeys').addEventListener('click', saveKeysManual);
    }

    function startConnect() {
        connecting = true;
        var w = 480, h = 550, left = (screen.width - w) / 2, top = (screen.height - h) / 2;
        var popup = window.open(
            'https://tubepress.io/connect?origin=' + encodeURIComponent(window.location.origin),
            'tubepress_connect',
            'width=' + w + ',height=' + h + ',left=' + left + ',top=' + top + ',resizable=no,scrollbars=no'
        );
        if (!popup) { connecting = false; toast('Please allow popups to connect, or enter your API keys manually.'); }
    }

    function persistConnection(apiKey, apiSecret, after) {
        return fetch('/admin/catalogue/save-config', {
            method: 'POST', credentials: 'same-origin',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': CSRF },
            body: JSON.stringify({ catalogue_api_key: apiKey, catalogue_api_secret: apiSecret, catalogue_api_url: 'https://tubepress.io/v1' })
        }).then(function (r) { return r.json(); }).then(function (d) {
            if (d && d.configured) { ctx = ctx || {}; ctx.connected = true; toast('Connected to TubePress.'); refreshBadge(); if (after) after(); else showHome(); }
            else { toast((d && d.error) || 'Could not verify the connection.'); }
        }).catch(function () { toast('Network error while saving the connection.'); });
    }

    function saveKeysManual() {
        var k = (document.getElementById('tpsup-mkey').value || '').trim();
        var s = (document.getElementById('tpsup-msecret').value || '').trim();
        if (!k || !s) { toast('Enter both the API key and secret.'); return; }
        var btn = document.getElementById('tpsup-savekeys'); btn.disabled = true; btn.innerHTML = '<i class="fa-solid fa-spinner tpsup-spin"></i> Connecting…';
        persistConnection(k, s).then(function () { btn.disabled = false; btn.innerHTML = '<i class="fa-solid fa-floppy-disk"></i> Save &amp; connect'; });
    }

    
    window.addEventListener('message', function (e) {
        if (e.origin !== 'https://tubepress.io') return;
        if (!e.data || e.data.type !== 'tubepress-connect') return;
        if (!connecting) return; 
        connecting = false;
        if (e.data.api_key && e.data.api_secret) { persistConnection(e.data.api_key, e.data.api_secret); }
    });

    
    function showHome() {
        stopPoll();
        view = 'home'; currentTicket = null; foot.style.display = 'block';
        ackNext = false;
        persist('home');
        setHeader('Support', 'Connected to TubePress', false);
        foot.innerHTML = '<button class="tpsup-btn" id="tpsup-new"><i class="fa-solid fa-plus"></i> New ticket</button>';
        document.getElementById('tpsup-new').addEventListener('click', showNew);
        body.innerHTML = '<div class="tpsup-empty"><i class="fa-solid fa-spinner tpsup-spin"></i><p>Loading your tickets…</p></div>';
        api('/admin/support/tickets').then(function (res) {
            if (res.j && res.j.connected === false) { showConnect(); return; }
            if (res.ok && res.j && !res.j.error) { ingestTickets(res.j.tickets || []); }
            renderList((res.j && res.j.tickets) || [], res.j && res.j.error);
        });
    }

    function renderList(tickets, err) {
        if (err) { body.innerHTML = '<div class="tpsup-empty"><i class="fa-solid fa-plug-circle-xmark"></i><p>Support is unreachable right now. Please try again shortly.</p></div>'; return; }
        if (!tickets.length) {
            body.innerHTML = '<div class="tpsup-empty"><i class="fa-regular fa-comments"></i><p>No tickets yet.<br>Hit “New ticket” if you need a hand — bug, question, anything.</p></div>';
            return;
        }
        var seen = seenMap() || {};
        var html = '<div class="tpsup-list">';
        tickets.forEach(function (t) {
            html += '<div class="tpsup-card' + (isUnseen(t, seen) ? ' tpsup-unseen' : '') + '" data-id="' + t.id + '">'
                + '<h4>' + esc(t.subject) + '</h4>'
                + '<div class="tpsup-meta">' + statusChip(t)
                + '<span>#' + esc(t.reference) + '</span><span>·</span><span>' + esc(relTime(t.last_message_at || t.updated_at)) + '</span></div>'
                + '</div>';
        });
        html += '</div>';
        body.innerHTML = html;
        Array.prototype.forEach.call(body.querySelectorAll('.tpsup-card'), function (c) {
            c.addEventListener('click', function () { ackNext = true; openTicket(c.getAttribute('data-id')); });
        });
    }

    function fieldOptions(sel, list) { return list.map(function (o) { return '<option value="' + o[0] + '"' + (o[0] === sel ? ' selected' : '') + '>' + o[1] + '</option>'; }).join(''); }

    function showNew() {
        view = 'new'; files = []; foot.style.display = 'none';
        persist('new');
        setHeader('New ticket', 'We usually reply within a day', true);
        var adminUrl = (location.origin + '/admin');
        var cats = [['bug', '🐞 Bug / something broken'], ['question', '❓ Question'], ['billing', '💳 Billing'], ['account', '👤 Account'], ['feature', '💡 Feature request'], ['other', '💬 Other']];
        var prios = [['low', 'Low'], ['normal', 'Normal'], ['high', 'High'], ['urgent', 'Urgent']];
        body.innerHTML = '<form class="tpsup-form" id="tpsup-newform">'
            + '<div class="tpsup-field"><label>Subject <span class="req">*</span></label><input class="tpsup-input" id="f-subject" maxlength="200" placeholder="Short summary of the issue"></div>'
            + '<div class="tpsup-row">'
            +   '<div class="tpsup-field"><label>Category</label><select class="tpsup-select" id="f-category">' + fieldOptions('bug', cats) + '</select></div>'
            +   '<div class="tpsup-field"><label>Priority</label><select class="tpsup-select" id="f-priority">' + fieldOptions('normal', prios) + '</select></div>'
            + '</div>'
            + '<div class="tpsup-field"><label>Message <span class="req">*</span></label><textarea class="tpsup-textarea" id="f-message" placeholder="What happened? What did you expect? Steps to reproduce help a lot."></textarea></div>'
            + '<div class="tpsup-field"><label>Screenshots <span style="font-weight:400;color:#94a3b8">(optional)</span></label>'
            +   '<div class="tpsup-drop" id="f-drop"><i class="fa-solid fa-image"></i> Click to add images (PNG/JPG, up to 6)</div>'
            +   '<input type="file" id="f-files" accept="image/png,image/jpeg,image/webp,image/gif" multiple style="display:none">'
            +   '<div class="tpsup-thumbs" id="f-thumbs"></div>'
            + '</div>'
            + '<details class="tpsup-acc"><summary><i class="fa-solid fa-key" style="color:#2563eb"></i> Admin access <span style="font-weight:400;color:#94a3b8">(optional)</span><i class="fa-solid fa-chevron-down chev"></i></summary>'
            +   '<div class="tpsup-acc-body">'
            +     '<div class="tpsup-note warn" style="margin:0"><i class="fa-solid fa-shield-halved"></i> Optional &mdash; add this only if you want us to sign in, reproduce and fix the issue for you. Encrypted, support-only, and auto-deleted the moment your ticket is resolved.</div>'
            +     '<div class="tpsup-field"><label>Admin URL</label><input class="tpsup-input" id="f-adminurl" value="' + esc(adminUrl) + '"></div>'
            +     '<div class="tpsup-field"><label>Admin login</label><input class="tpsup-input" id="f-adminlogin" autocomplete="off" placeholder="admin username or e-mail"></div>'
            +     '<div class="tpsup-field"><label>Admin password</label><input class="tpsup-input" id="f-adminpass" type="password" autocomplete="new-password" placeholder="••••••••"></div>'
            +   '</div>'
            + '</details>'
            + '<details class="tpsup-acc"><summary><i class="fa-solid fa-wrench" style="color:#2563eb"></i> Technical details <span style="font-weight:400;color:#94a3b8">(auto-filled)</span><i class="fa-solid fa-chevron-down chev"></i></summary>'
            +   '<div class="tpsup-acc-body">'
            +     '<div class="tpsup-note"><i class="fa-solid fa-circle-info"></i> Sent automatically so we can debug faster.</div>'
            +     '<div class="tpsup-field"><label>Domain</label><input class="tpsup-input" id="f-domain" readonly value="' + esc((ctx && ctx.domain) || location.hostname) + '"></div>'
            +     '<div class="tpsup-row">'
            +       '<div class="tpsup-field"><label>CMS</label><input class="tpsup-input" readonly value="' + esc((ctx && ctx.cms_version) || '—') + '"></div>'
            +       '<div class="tpsup-field"><label>PHP</label><input class="tpsup-input" readonly value="' + esc((ctx && ctx.php_version) || '—') + '"></div>'
            +     '</div>'
            +   '</div>'
            + '</details>'
            + '<details class="tpsup-acc"><summary><i class="fa-solid fa-server" style="color:#64748b"></i> Server / SSH access <span style="font-weight:400;color:#94a3b8">(optional)</span><i class="fa-solid fa-chevron-down chev"></i></summary>'
            +   '<div class="tpsup-acc-body">'
            +     '<div class="tpsup-note warn" style="margin:0"><i class="fa-solid fa-lock"></i> Only if your issue needs server access. Same protection: encrypted &amp; auto-deleted on resolve.</div>'
            +     '<div class="tpsup-row">'
            +       '<div class="tpsup-field"><label>Server IP</label><input class="tpsup-input" id="f-serverip" autocomplete="off" placeholder="203.0.113.4"></div>'
            +       '<div class="tpsup-field"><label>SSH user</label><input class="tpsup-input" id="f-serveruser" autocomplete="off" placeholder="root"></div>'
            +     '</div>'
            +     '<div class="tpsup-field"><label>SSH password</label><input class="tpsup-input" id="f-serverpass" type="password" autocomplete="new-password" placeholder="••••••••"></div>'
            +   '</div>'
            + '</details>'
            + '<button type="submit" class="tpsup-btn" id="f-submit"><i class="fa-solid fa-paper-plane"></i> Send ticket</button>'
            + '</form>';
        var fileInput = document.getElementById('f-files');
        document.getElementById('f-drop').addEventListener('click', function () { fileInput.click(); });
        fileInput.addEventListener('change', function () { addFiles(this.files, files, 'f-thumbs'); this.value = ''; });
        document.getElementById('tpsup-newform').addEventListener('submit', submitNew);
    }

    function addFiles(fileList, store, thumbsId) {
        Array.prototype.forEach.call(fileList, function (f) {
            if (store.length >= 6) return;
            if (!/^image\//.test(f.type)) return;
            if (f.size > 5242880) { toast(f.name + ' is over 5 MB and was skipped.'); return; }
            store.push(f);
        });
        renderThumbs(store, thumbsId);
    }
    function renderThumbs(store, thumbsId) {
        var box = document.getElementById(thumbsId); if (!box) return;
        box.innerHTML = '';
        store.forEach(function (f, i) {
            var url = URL.createObjectURL(f);
            var d = document.createElement('div'); d.className = 'tpsup-thumb';
            d.innerHTML = '<img src="' + url + '"><button type="button" title="Remove">✕</button>';
            d.querySelector('button').addEventListener('click', function () { store.splice(i, 1); renderThumbs(store, thumbsId); });
            box.appendChild(d);
        });
    }

    function submitNew(e) {
        e.preventDefault();
        function val(id) { var el = document.getElementById(id); return el ? el.value.trim() : ''; }
        var subject = val('f-subject'), message = val('f-message');
        var adminLogin = val('f-adminlogin'), adminPass = val('f-adminpass');
        if (!subject) { toast('Please add a subject.'); return; }
        if (!message) { toast('Please describe the issue.'); return; }
        var fd = new FormData();
        fd.append('csrf_token', CSRF);
        fd.append('subject', subject);
        fd.append('message', message);
        fd.append('category', val('f-category'));
        fd.append('priority', val('f-priority'));
        fd.append('domain', val('f-domain'));
        if (adminLogin) { fd.append('admin_login', adminLogin); }
        if (adminPass) { fd.append('admin_pass', adminPass); }
        if (adminLogin || adminPass) { fd.append('admin_url', val('f-adminurl')); }
        ['serverip:server_ip', 'serveruser:server_user', 'serverpass:server_pass'].forEach(function (m) {
            var p = m.split(':'); var v = val('f-' + p[0]); if (v) fd.append(p[1], v);
        });
        files.forEach(function (f) { fd.append('screenshots[]', f); });

        var btn = document.getElementById('f-submit'); btn.disabled = true; btn.innerHTML = '<i class="fa-solid fa-spinner tpsup-spin"></i> Sending…';
        api('/admin/support/tickets', { method: 'POST', body: fd }).then(function (res) {
            if (res.ok && res.j.success) { toast('Ticket sent — we’re on it.'); ackNext = true; renderThread(res.j.ticket); }
            else { btn.disabled = false; btn.innerHTML = '<i class="fa-solid fa-paper-plane"></i> Send ticket'; toast(res.j.error || 'Could not send the ticket.'); }
        }).catch(function () { btn.disabled = false; btn.innerHTML = '<i class="fa-solid fa-paper-plane"></i> Send ticket'; toast('Network error.'); });
    }

    function openTicket(id) {
        foot.style.display = 'none';
        persist('thread', id);
        setHeader('Loading…', '', true);
        body.innerHTML = '<div class="tpsup-empty"><i class="fa-solid fa-spinner tpsup-spin"></i><p>Loading conversation…</p></div>';
        api('/admin/support/tickets/' + id).then(function (res) {
            if (res.j && res.j.ticket) { renderThread(res.j.ticket); }
            else { toast('Could not open the ticket.'); showHome(); }
        });
    }

    function renderThread(t) {
        view = 'thread'; currentTicket = t; replyFiles = []; foot.style.display = 'none';
        persist('thread', t.id);
        
        
        
        if (ackNext) { ackNext = false; markSeen(t); }
        setHeader(t.subject, '#' + t.reference + ' · ' + (t.status === 'resolved' ? 'Resolved' : t.status === 'closed' ? 'Closed' : (t.awaiting === 'you' ? 'Your reply needed' : 'In progress')), true);
        var menuBtn = document.getElementById('tpsup-menu');
        if (menuBtn) { menuBtn.style.display = 'flex'; menuBtn.onclick = function (ev) { ev.stopPropagation(); toggleTicketMenu(t); }; }
        var html = '<div class="tpsup-thread">';
        (t.messages || []).forEach(function (m) {
            var who = m.role === 'staff' ? 'staff' : 'client';
            html += '<div class="tpsup-msg ' + who + '">'
                + '<div class="tpsup-msg-h">' + (m.role === 'staff' ? '<i class="fa-solid fa-headset"></i> ' : '') + esc(m.author) + ' · ' + esc(relTime(m.created_at)) + '</div>'
                + '<div class="tpsup-bubble2">' + esc(m.body) + '</div>';
            if (m.attachments && m.attachments.length) {
                html += '<div class="tpsup-att">';
                m.attachments.forEach(function (a) {
                    var au = '/admin/support/attachment/' + a.id;
                    html += '<a href="' + au + '" target="_blank" rel="noopener" title="' + esc(a.name) + '"><img src="' + au + '" alt=""></a>';
                });
                html += '</div>';
            }
            html += '</div>';
        });
        html += '</div>';
        body.innerHTML = html;
        body.scrollTop = body.scrollHeight;
        foot.style.display = 'block';
        if (t.status === 'closed') {
            foot.innerHTML = '<div style="text-align:center;color:#94a3b8;font-size:12.5px"><i class="fa-solid fa-lock"></i> This ticket is closed. Reply to reopen it.</div>'
                + '<div class="tpsup-reply" style="margin-top:8px"><textarea class="tpsup-textarea" id="r-msg" placeholder="Reply to reopen…"></textarea><button class="tpsup-send" id="r-send"><i class="fa-solid fa-paper-plane"></i></button></div>';
        } else {
            foot.innerHTML = '<div class="tpsup-thumbs" id="r-thumbs" style="margin:0 0 8px"></div>'
                + '<div class="tpsup-reply">'
                + '<textarea class="tpsup-textarea" id="r-msg" placeholder="Write a reply…"></textarea>'
                + '<button class="tpsup-icon-btn" id="r-attach" title="Attach"><i class="fa-solid fa-paperclip"></i></button>'
                + '<button class="tpsup-send" id="r-send" title="Send"><i class="fa-solid fa-paper-plane"></i></button>'
                + '<input type="file" id="r-files" accept="image/png,image/jpeg,image/webp,image/gif" multiple style="display:none"></div>';
            var rf = document.getElementById('r-files');
            document.getElementById('r-attach').addEventListener('click', function () { rf.click(); });
            rf.addEventListener('change', function () { addFiles(this.files, replyFiles, 'r-thumbs'); this.value = ''; });
        }
        
        var draftKey = 'tpsup_draft_' + t.id;
        var rmsg = document.getElementById('r-msg');
        if (rmsg) {
            var savedDraft = lsGet(draftKey);
            if (savedDraft && !rmsg.value) rmsg.value = savedDraft;
            rmsg.addEventListener('input', function () {
                if (this.value && this.value.length <= 20000) { lsSet(draftKey, this.value); } else if (!this.value) { lsDel(draftKey); }
            });
        }
        if (rmsg) { rmsg.addEventListener('focus', function () { if (view === 'thread' && currentTicket) markSeen(currentTicket); }, { once: true }); }
        document.getElementById('r-send').addEventListener('click', function () { submitReply(t); });
        startThreadPoll(t.id);
    }

    
    
    function stopPoll() { if (pollTimer) { clearInterval(pollTimer); pollTimer = null; } }
    function startThreadPoll(id) {
        stopPoll();
        pollTimer = setInterval(function () {
            if (view !== 'thread' || !currentTicket || String(currentTicket.id) !== String(id)) { stopPoll(); return; }
            api('/admin/support/tickets/' + id).then(function (res) {
                var t = res.j && res.j.ticket;
                if (!t || view !== 'thread' || !currentTicket || String(currentTicket.id) !== String(id)) return;
                var oldN = (currentTicket.messages || []).length, newN = (t.messages || []).length;
                if (newN === oldN && t.status === currentTicket.status) return;
                var ta = document.getElementById('r-msg'); var draft = ta ? ta.value : '';
                var atBottom = (body.scrollHeight - body.scrollTop - body.clientHeight) < 60;
                renderThread(t);
                var nta = document.getElementById('r-msg'); if (nta && draft) { nta.value = draft; nta.focus(); }
                if (atBottom) body.scrollTop = body.scrollHeight;
                if (newN > oldN) toast('New reply received');
            }).catch(function () {});
        }, 5000);
    }

    function submitReply(t) {
        var ta = document.getElementById('r-msg'); var msg = ta.value.trim();
        if (!msg && !replyFiles.length) { toast('Write a message first.'); return; }
        var fd = new FormData();
        fd.append('csrf_token', CSRF);
        fd.append('message', msg);
        replyFiles.forEach(function (f) { fd.append('screenshots[]', f); });
        var btn = document.getElementById('r-send'); btn.disabled = true; btn.innerHTML = '<i class="fa-solid fa-spinner tpsup-spin"></i>';
        api('/admin/support/tickets/' + t.id + '/reply', { method: 'POST', body: fd }).then(function (res) {
            if (res.ok && res.j.success && res.j.ticket) { lsDel('tpsup_draft_' + t.id); ackNext = true; renderThread(res.j.ticket); }
            else { btn.disabled = false; btn.innerHTML = '<i class="fa-solid fa-paper-plane"></i>'; toast(res.j.error || 'Could not send.'); }
        }).catch(function () { btn.disabled = false; btn.innerHTML = '<i class="fa-solid fa-paper-plane"></i>'; toast('Network error.'); });
    }

    function hideHelp() { var h = document.getElementById('tphelp'); if (h) h.classList.remove('open'); }
    function open() { hideHelp(); root.classList.add('open'); if (!ctx) { loadContext().then(route); } else { route(); } }
    function route() { if (ctx && ctx.connected) showHome(); else showConnect(); }
    function close() { stopPoll(); closeTicketMenu(); root.classList.remove('open'); persistClosed(); }
    body.addEventListener('click', function () { if (view === 'thread' && currentTicket) markSeen(currentTicket); });
    document.addEventListener('click', function (e) { if (ddOpen && !e.target.closest('.tpsup-menuwrap')) closeTicketMenu(); });
    document.getElementById('tpsup-bubble').addEventListener('click', open);
    document.getElementById('tpsup-close').addEventListener('click', close);
    backBtn.addEventListener('click', function () { if (view === 'thread' || view === 'new') showHome(); });

    
    function openTo(id) {
        hideHelp();
        root.classList.add('open');
        body.innerHTML = '<div class="tpsup-empty"><i class="fa-solid fa-spinner tpsup-spin"></i><p>Loading conversation…</p></div>';
        ensureCtx().then(function () { if (ctx && ctx.connected) { ackNext = true; openTicket(id); } else { showConnect(); } });
    }
    function openList() { hideHelp(); root.classList.add('open'); ensureCtx().then(route); }
    window.tpSupport = { open: openList, openTicket: openTo, unseenCount: function () { return unseen.length; } };

    
    
    
    var chatBtn = document.getElementById('tpsidebar-chat');
    if (chatBtn) {
        chatBtn.onclick = function (ev) {
            ev.preventDefault();
            if (unseen.length) { openTo(unseen[0].id); } else { openList(); }  
            return false;
        };
    }

    
    function refreshBadge() {
        return ensureCtx().then(function (c) {
            if (!c || !c.connected) { lastTickets = []; computeIndicators(); return; }
            return api('/admin/support/tickets').then(function (res) {
                if (res.j && res.j.connected === false) { ctx.connected = false; lastTickets = []; computeIndicators(); return; }
                if (!res.ok || !res.j || res.j.error) return; 
                ingestTickets(res.j.tickets || []);
                if (view === 'home' && root.classList.contains('open')) renderList(lastTickets); 
            });
        }).catch(function () {});
    }
    function updateBadge(n) { var d = document.getElementById('tpsup-dot'); if (n > 0) { d.textContent = n > 9 ? '9+' : n; d.style.display = 'flex'; } else { d.style.display = 'none'; } }

    
    
    (function restoreState() {
        var raw = lsGet(STATE_KEY); if (!raw) return;
        var st; try { st = JSON.parse(raw); } catch (e) { return; }
        if (!st || !st.o) return;
        root.classList.add('open');
        body.innerHTML = '<div class="tpsup-empty"><i class="fa-solid fa-spinner tpsup-spin"></i><p>Loading…</p></div>';
        loadContext().then(function () {
            if (!ctx || !ctx.connected) { showConnect(); return; }
            if (st.v === 'thread' && st.t) { openTicket(st.t); }
            else if (st.v === 'new') { showNew(); }
            else { showHome(); }
        });
    })();

    setTimeout(refreshBadge, 1500);
    setInterval(function () { if (document.visibilityState === 'visible') refreshBadge(); }, 60000);
    document.addEventListener('visibilitychange', function () { if (document.visibilityState === 'visible') refreshBadge(); });
    window.addEventListener('storage', function (e) { if (e.key === SEEN_KEY) computeIndicators(); });
})();
</script>
