// =============================================================================
// app.js — shared frontend helpers for the Master Panel
// =============================================================================

(function () {
    'use strict';

    const csrfMeta = document.querySelector('meta[name="csrf-token"]');
    const CSRF = csrfMeta ? csrfMeta.getAttribute('content') : '';

    // ------------------------------------------------------------------
    // fetch helpers
    // ------------------------------------------------------------------
    async function apiCall(url, opts) {
        opts = opts || {};
        const headers = Object.assign({
            'X-Requested-With': 'XMLHttpRequest',
            'X-CSRF-Token': CSRF,
            'Accept': 'application/json'
        }, opts.headers || {});
        if (opts.body && typeof opts.body !== 'string' && !(opts.body instanceof FormData)) {
            headers['Content-Type'] = 'application/json';
            opts.body = JSON.stringify(opts.body);
        }
        const res = await fetch(url, Object.assign({ method: 'GET', credentials: 'same-origin' }, opts, { headers }));
        const ctype = res.headers.get('content-type') || '';
        const data = ctype.indexOf('application/json') >= 0 ? await res.json() : await res.text();
        if (!res.ok) {
            const msg = (data && data.error) ? data.error : ('HTTP ' + res.status);
            const err = new Error(msg);
            err.status = res.status;
            err.body = data;
            throw err;
        }
        return data;
    }

    window.api = {
        get: (url) => apiCall(url, { method: 'GET' }),
        post: (url, body) => apiCall(url, { method: 'POST', body: body || {} }),
        put: (url, body) => apiCall(url, { method: 'PUT', body: body || {} }),
        del: (url, body) => apiCall(url, { method: 'DELETE', body: body || {} }),
    };

    // ------------------------------------------------------------------
    // Toasts
    // ------------------------------------------------------------------
    window.toast = function (message, kind) {
        kind = kind || 'info';
        const host = document.getElementById('toast-host');
        if (!host) return;
        const colors = {
            info:    { bg: 'bg-blue-500/10',    border: 'border-blue-500/40',    text: 'text-blue-300',    icon: 'ph-info' },
            success: { bg: 'bg-emerald-500/10', border: 'border-emerald-500/40', text: 'text-emerald-300', icon: 'ph-check-circle' },
            error:   { bg: 'bg-red-500/10',     border: 'border-red-500/40',     text: 'text-red-300',     icon: 'ph-warning-circle' },
            warn:    { bg: 'bg-amber-500/10',   border: 'border-amber-500/40',   text: 'text-amber-300',   icon: 'ph-warning' }
        };
        const c = colors[kind] || colors.info;
        const el = document.createElement('div');
        el.className = `flex items-center gap-2 px-4 py-3 rounded-lg border ${c.bg} ${c.border} ${c.text} text-sm shadow-2xl backdrop-blur-sm`;
        el.style.minWidth = '260px';
        el.innerHTML = `<i class="ph ${c.icon} text-lg"></i><span class="flex-1">${escapeHtml(message)}</span><button class="text-current opacity-60 hover:opacity-100"><i class="ph ph-x"></i></button>`;
        host.appendChild(el);
        el.querySelector('button').addEventListener('click', () => el.remove());
        setTimeout(() => { el.style.transition = 'opacity .3s'; el.style.opacity = '0'; setTimeout(() => el.remove(), 300); }, 4000);
    };

    // ------------------------------------------------------------------
    // Modal helper — generic open/close
    // ------------------------------------------------------------------
    window.openModal = function (id) {
        const el = document.getElementById(id);
        if (el) { el.style.display = 'flex'; }
    };
    window.closeModal = function (id) {
        const el = document.getElementById(id);
        if (el) { el.style.display = 'none'; }
    };
    document.addEventListener('keydown', function (e) {
        if (e.key === 'Escape') {
            document.querySelectorAll('.panel-modal[style*="flex"]').forEach((m) => { m.style.display = 'none'; });
        }
    });

    // ------------------------------------------------------------------
    // Form helpers
    // ------------------------------------------------------------------
    window.formObject = function (form) {
        const out = {};
        new FormData(form).forEach((v, k) => {
            if (k.endsWith('[]')) {
                const key = k.slice(0, -2);
                (out[key] = out[key] || []).push(v);
            } else {
                out[k] = v;
            }
        });
        return out;
    };

    window.escapeHtml = function (s) {
        return String(s == null ? '' : s)
            .replace(/&/g, '&amp;').replace(/</g, '&lt;')
            .replace(/>/g, '&gt;').replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;');
    };

    // ------------------------------------------------------------------
    // Fullscreen iframe modal — used by every WebView preview's
    // "View Fullscreen" link (sports, slideshow, frameview, tmdb).
    // Press Esc to exit.
    // ------------------------------------------------------------------
    window.wvFullscreen = function (url) {
        if (!url) { window.toast('No URL set', 'warn'); return; }
        let host = document.getElementById('wv-fs-host');
        if (!host) {
            host = document.createElement('div');
            host.id = 'wv-fs-host';
            host.innerHTML =
                '<button id="wv-fs-close" title="Close (Esc)" ' +
                'style="position:absolute;top:14px;right:14px;z-index:10000;' +
                'width:40px;height:40px;border-radius:50%;border:0;' +
                'background:rgba(0,0,0,.7);color:#fff;display:flex;' +
                'align-items:center;justify-content:center;cursor:pointer;font-size:18px;' +
                'backdrop-filter:blur(4px)"><i class="ph ph-x"></i></button>' +
                '<iframe id="wv-fs-iframe" allow="fullscreen" ' +
                'style="width:100%;height:100%;border:0;display:block"></iframe>';
            host.style.cssText = 'display:none;position:fixed;inset:0;z-index:9999;background:#000;';
            document.body.appendChild(host);
            host.querySelector('#wv-fs-close').addEventListener('click', closeWvFullscreen);
            document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeWvFullscreen(); });
        }
        host.querySelector('#wv-fs-iframe').src = url;
        host.style.display = 'block';
        if (host.requestFullscreen) host.requestFullscreen().catch(() => {});
    };
    function closeWvFullscreen() {
        const host = document.getElementById('wv-fs-host');
        if (!host) return;
        host.style.display = 'none';
        host.querySelector('iframe').src = '';
        if (document.fullscreenElement) document.exitFullscreen().catch(() => {});
    }

    // ------------------------------------------------------------------
    // Confirm dialog (replaces window.confirm)
    // ------------------------------------------------------------------
    window.confirmDanger = function (message) {
        return new Promise((resolve) => {
            // Build inline if not present
            let host = document.getElementById('confirm-danger');
            if (!host) {
                host = document.createElement('div');
                host.id = 'confirm-danger';
                host.className = 'panel-modal fixed inset-0 z-[9998] items-center justify-center p-4';
                host.style.cssText = 'display:none;background:rgba(0,0,0,.7)';
                host.innerHTML = `
                  <div class="bg-dark-800 border border-dark-600 rounded-xl w-full max-w-md shadow-2xl">
                    <div class="flex items-center justify-between px-5 py-4 border-b border-dark-700">
                      <h3 class="text-sm font-semibold text-dark-200 uppercase tracking-wider">
                        <i class="ph ph-warning text-red-400 mr-1"></i> Confirm
                      </h3>
                    </div>
                    <div class="p-5 text-sm text-dark-200" data-msg>Are you sure?</div>
                    <div class="flex justify-end gap-2 px-5 pb-5">
                      <button data-cancel class="px-4 py-2 text-xs text-dark-400 hover:text-dark-200">Cancel</button>
                      <button data-ok class="btn-danger text-xs">Yes, continue</button>
                    </div>
                  </div>`;
                document.body.appendChild(host);
            }
            host.querySelector('[data-msg]').textContent = message;
            host.style.display = 'flex';
            const close = (val) => { host.style.display = 'none'; resolve(val); };
            host.querySelector('[data-ok]').onclick = () => close(true);
            host.querySelector('[data-cancel]').onclick = () => close(false);
            host.onclick = (e) => { if (e.target === host) close(false); };
        });
    };
})();
