/* ===================================================
   JAESWIFT.XYZ — Scan The Visitor
   Typewriter-animated visitor recon overlay.
   =================================================== */
(function () {
    'use strict';

    const DISMISS_KEY = 'scanDismissed';
    const DISMISS_DAYS = 7;
    const BADGE_HIDE_KEY = 'scanBadgeHidden';
    const TYPE_SPEED = 22; // ms per char
    const LINE_PAUSE = 120;

    // ─── Check if dismissed recently ────────────────
    function isDismissed() {
        try {
            const raw = localStorage.getItem(DISMISS_KEY);
            if (!raw) return false;
            const ts = parseInt(raw, 10);
            if (!ts) return false;
            const ageDays = (Date.now() - ts) / (1000 * 60 * 60 * 24);
            return ageDays < DISMISS_DAYS;
        } catch (e) { return false; }
    }

    function setDismissed() {
        try { localStorage.setItem(DISMISS_KEY, Date.now().toString()); } catch (e) {}
    }

    function isBadgeHidden() {
        try { return localStorage.getItem(BADGE_HIDE_KEY) === '1'; } catch (e) { return false; }
    }

    // ─── Gather local client info ───────────────────
    function localInfo() {
        const scr = `${screen.width}x${screen.height}`;
        const dpr = (window.devicePixelRatio || 1);
        let conn = 'Unknown';
        try {
            const c = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
            if (c) {
                const t = c.effectiveType || c.type || '';
                conn = t ? t.toUpperCase() : 'Unknown';
                if (c.downlink) conn += `, ${c.downlink}Mbps`;
                if (c.rtt) conn += `, ${c.rtt}ms`;
            }
        } catch (e) {}
        return {
            screen: `${scr} @ ${dpr}x`,
            connection: conn,
            tz: Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC',
            lang: navigator.language || 'en',
        };
    }

    // ─── Build scan lines list ──────────────────────
    function buildLines(data, local) {
        const locStr = data.city ? `${data.city}, ${data.country}` : data.country;
        const browser = data.browser + (data.browser_version ? ' ' + data.browser_version : '');
        const osStr = data.os + (data.os_version ? ' ' + data.os_version : '');
        const flag = data.country_flag || '';
        const threatColor = data.threat_level === 'GREEN' ? 'green'
                           : data.threat_level === 'AMBER' ? 'amber'
                           : 'red';
        const bar = (() => {
            if (data.threat_level === 'GREEN') return '[█░░░░] GREEN — TRUSTED';
            if (data.threat_level === 'AMBER') return '[███░░] AMBER — MONITORED';
            if (data.threat_level === 'RED')   return '[█████] RED — BLOCKED';
            return '[░░░░░] UNKNOWN';
        })();

        return [
            { cls: 'green', text: '>>> ESTABLISHING SECURE CONNECTION...' },
            { cls: 'green', text: '>>> HANDSHAKE OK · TLS 1.3 · AES-256-GCM' },
            { cls: 'green', text: '>>> SCANNING OPERATOR...' },
            { cls: 'dim',   text: '' },
            { cls: 'green', text: `>>> IP ADDRESS....... ${data.ip_masked}` },
            { cls: 'green', text: `>>> GEOLOCATION...... ${locStr} ${flag}` },
            { cls: 'green', text: `>>> NETWORK.......... ${data.isp}` },
            data.hostname ? { cls: 'dim', text: `>>> HOSTNAME......... ${data.hostname}` } : null,
            { cls: 'green', text: `>>> BROWSER.......... ${browser}` },
            { cls: 'green', text: `>>> OS............... ${osStr}` },
            { cls: 'green', text: `>>> DEVICE........... ${data.device}` },
            { cls: 'green', text: `>>> SCREEN........... ${local.screen}` },
            { cls: 'green', text: `>>> LANGUAGE......... ${local.lang}` },
            { cls: 'green', text: `>>> TIMEZONE......... ${local.tz}` },
            { cls: 'green', text: `>>> CONNECTION....... ${local.connection}` },
            { cls: 'dim',   text: '' },
            { cls: threatColor, text: `>>> THREAT LEVEL..... ${bar}` },
            { cls: threatColor, text: `>>> STATUS........... ${data.threat_reason}` },
            { cls: 'dim',   text: '' },
            { cls: 'green', text: '>>> ACCESS GRANTED — WELCOME, OPERATOR' },
        ].filter(Boolean);
    }

    // ─── Typewriter: types text into element ─────────
    function typeInto(el, text, speed) {
        return new Promise(function (resolve) {
            let i = 0;
            function tick() {
                if (i < text.length) {
                    el.textContent += text.charAt(i);
                    i++;
                    setTimeout(tick, speed);
                } else {
                    resolve();
                }
            }
            if (!text.length) { resolve(); return; }
            tick();
        });
    }

    // ─── Build overlay DOM ───────────────────────────
    function buildOverlay() {
        const overlay = document.createElement('div');
        overlay.className = 'scan-overlay';
        overlay.id = 'scanOverlay';
        overlay.innerHTML = `
            <div class="scan-panel" role="dialog" aria-label="Visitor Scan">
                <div class="scan-panel-header">
                    <span class="scan-panel-title">◉ VISITOR RECONNAISSANCE // SCAN IN PROGRESS</span>
                    <div style="display:flex;align-items:center;gap:8px;">
                        <span class="scan-panel-status" id="scanStatus">● ACTIVE</span>
                        <button class="scan-close" id="scanClose" aria-label="Close">X CLOSE</button>
                    </div>
                </div>
                <div class="scan-body" id="scanBody"></div>
                <div class="scan-footer">
                    <span id="scanFooterInfo">JAESWIFT // COMMAND OPS · SCAN v1.0</span>
                    <div style="display:flex;gap:8px;">
                        <button class="scan-footer-action scan-footer-action-dismiss" id="scanDismissBtn">DISMISS 7D</button>
                        <button class="scan-footer-action" id="scanAcceptBtn" disabled style="opacity:0.5;cursor:wait;">ACKNOWLEDGE</button>
                    </div>
                </div>
            </div>
        `;
        return overlay;
    }

    // ─── Build badge (collapsed state) ───────────────
    function buildBadge(data) {
        const flag = data.country_flag || '🌐';
        const cc = data.country_code || 'XX';
        const locShort = data.city ? `${data.city}, ${cc}` : (data.country || cc);
        const badge = document.createElement('div');
        badge.className = 'scan-badge';
        badge.id = 'scanBadge';
        badge.title = 'Click to re-run scan';
        badge.innerHTML = `
            <span class="scan-badge-flag">${flag}</span>
            <div style="display:flex;flex-direction:column;line-height:1.2;">
                <span class="scan-badge-label">OPERATOR</span>
                <span class="scan-badge-val">${locShort}</span>
            </div>
            <button class="scan-badge-close" id="scanBadgeClose" aria-label="Hide badge" title="Hide">×</button>
        `;
        badge.addEventListener('click', function (e) {
            if (e.target && e.target.id === 'scanBadgeClose') return;
            // Re-run scan on click
            try { localStorage.removeItem(DISMISS_KEY); } catch (err) {}
            badge.remove();
            runScan();
        });
        badge.querySelector('#scanBadgeClose').addEventListener('click', function (e) {
            e.stopPropagation();
            try { localStorage.setItem(BADGE_HIDE_KEY, '1'); } catch (err) {}
            badge.classList.add('scan-closing');
            setTimeout(() => badge.remove(), 220);
        });
        document.body.appendChild(badge);
    }

    // ─── Render scan lines one-by-one ────────────────
    async function renderLines(body, lines) {
        for (let i = 0; i < lines.length; i++) {
            const item = lines[i];
            const span = document.createElement('span');
            span.className = `scan-line scan-line-${item.cls}`;
            body.appendChild(span);
            if (item.text) {
                await typeInto(span, item.text, TYPE_SPEED);
                body.scrollTop = body.scrollHeight;
            } else {
                span.textContent = '\u00A0';
            }
            await new Promise(r => setTimeout(r, LINE_PAUSE));
        }
    }

    // ─── Run full scan sequence ──────────────────────
    async function runScan() {
        // fade in overlay first with 'CONNECTING...'
        const overlay = buildOverlay();
        document.body.appendChild(overlay);
        const body = overlay.querySelector('#scanBody');
        const statusEl = overlay.querySelector('#scanStatus');
        const closeBtn = overlay.querySelector('#scanClose');
        const dismissBtn = overlay.querySelector('#scanDismissBtn');
        const ackBtn = overlay.querySelector('#scanAcceptBtn');

        let scanData = null;
        let apiFailed = false;

        // Seed initial connecting line before fetch completes
        const initLine = document.createElement('span');
        initLine.className = 'scan-line scan-line-green';
        body.appendChild(initLine);
        typeInto(initLine, '>>> INITIALISING RECON PROTOCOL...', TYPE_SPEED);

        function closeAll(dismiss) {
            overlay.classList.add('scan-closing');
            if (dismiss) setDismissed();
            setTimeout(() => {
                overlay.remove();
                if (scanData && !isBadgeHidden()) {
                    buildBadge(scanData);
                }
            }, 260);
        }

        closeBtn.addEventListener('click', () => closeAll(false));
        dismissBtn.addEventListener('click', () => closeAll(true));
        ackBtn.addEventListener('click', () => closeAll(false));

        // allow esc to close
        function escHandler(e) {
            if (e.key === 'Escape') {
                closeAll(false);
                document.removeEventListener('keydown', escHandler);
            }
        }
        document.addEventListener('keydown', escHandler);

        try {
            const r = await fetch('/api/visitor/scan', { credentials: 'same-origin' });
            if (r.ok) {
                scanData = await r.json();
            } else if (r.status === 429) {
                apiFailed = true;
            } else {
                apiFailed = true;
            }
        } catch (e) {
            apiFailed = true;
        }

        // clear init line
        body.innerHTML = '';

        if (apiFailed || !scanData) {
            const errSpan = document.createElement('span');
            errSpan.className = 'scan-line scan-line-red';
            body.appendChild(errSpan);
            await typeInto(errSpan, '>>> RECON SERVICE UNAVAILABLE — STANDBY', TYPE_SPEED);
            statusEl.textContent = '● OFFLINE';
            statusEl.style.color = 'var(--danger)';
            ackBtn.disabled = false; ackBtn.style.opacity = '1'; ackBtn.style.cursor = 'pointer';
            return;
        }

        const local = localInfo();
        const lines = buildLines(scanData, local);
        await renderLines(body, lines);

        statusEl.textContent = '● SCAN COMPLETE';
        ackBtn.disabled = false; ackBtn.style.opacity = '1'; ackBtn.style.cursor = 'pointer';
        ackBtn.focus();
    }

    // ─── Boot ────────────────────────────────────────
    function boot() {
        if (isDismissed()) {
            // still show compact badge if not hidden — fetch silently
            if (!isBadgeHidden()) {
                fetch('/api/visitor/scan', { credentials: 'same-origin' })
                    .then(r => r.ok ? r.json() : null)
                    .then(d => { if (d && d.country_code) buildBadge(d); })
                    .catch(() => {});
            }
            return;
        }
        // Slight delay so page renders first
        setTimeout(runScan, 700);
    }

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

    // Expose for debug / re-trigger
    window.__jaeScan = {
        run: runScan,
        reset: function () {
            try {
                localStorage.removeItem(DISMISS_KEY);
                localStorage.removeItem(BADGE_HIDE_KEY);
            } catch (e) {}
            const b = document.getElementById('scanBadge'); if (b) b.remove();
            const o = document.getElementById('scanOverlay'); if (o) o.remove();
            runScan();
        },
    };
})();
