'use client';

/**
 * NOC Wall — standalone 24/7 TV view (no shell chrome). A fixed 1920×1080
 * canvas scaled to fit any viewport, with a persistent global-uptime hero, a
 * 15s auto-rotating carousel (Overview/Network/Incidents/Performance), a region
 * health strip, and a marquee alert ticker. Burn-in-safe: slow pixel-shift +
 * always-moving ticker, all disabled under prefers-reduced-motion.
 */
import { useCallback, useEffect, useState } from 'react';
import { LayoutGrid, Network, AlertTriangle, Gauge, Maximize2, X } from 'lucide-react';
import { useSentinelData } from '@/lib/executive/useSentinelData';
import { useReducedMotion } from '../_components/useReducedMotion';
import { CountUp, Delta, LiveDot, StatusDot } from '../_components/primitives';
import { PulseGlyph } from '../_components/PulseGlyph';
import { FLAGS } from '../_components/regions';
import { uptimeStatus, responseStatus } from '@/lib/executive/status';
import type { SentinelData, StatusLevel } from '@/lib/executive/types';

const CW = 1920;
const CH = 1080;
const STATUS_RAW: Record<StatusLevel, string> = { healthy: 'var(--ok)', warning: 'var(--warn)', critical: 'var(--crit)' };

export default function WallPage() {
    const { data, error, loading } = useSentinelData({ autoRefreshMs: 30000 });
    const reduced = useReducedMotion();
    const [scale, setScale] = useState(1);
    const [slide, setSlide] = useState(0);
    const [isFs, setIsFs] = useState(false);
    const [pointerIdle, setPointerIdle] = useState(false);

    useEffect(() => {
        const fit = () => setScale(Math.min(window.innerWidth / CW, window.innerHeight / CH));
        fit();
        window.addEventListener('resize', fit);
        return () => window.removeEventListener('resize', fit);
    }, []);

    useEffect(() => {
        const id = setInterval(() => setSlide((s) => (s + 1) % 4), 15000);
        return () => clearInterval(id);
    }, []);

    // Track the Fullscreen API so the exit affordance + cursor only show in fullscreen.
    useEffect(() => {
        const onChange = () => setIsFs(!!document.fullscreenElement);
        document.addEventListener('fullscreenchange', onChange);
        return () => document.removeEventListener('fullscreenchange', onChange);
    }, []);

    // While fullscreen: reveal the exit X + cursor on movement, then fade both
    // after 2.5s idle (kiosk-friendly). No synchronous setState in the effect
    // body — state only changes from the timer / move handler.
    useEffect(() => {
        if (!isFs) return;
        let t = window.setTimeout(() => setPointerIdle(true), 2500);
        const wake = () => {
            setPointerIdle(false);
            window.clearTimeout(t);
            t = window.setTimeout(() => setPointerIdle(true), 2500);
        };
        window.addEventListener('mousemove', wake);
        return () => { window.removeEventListener('mousemove', wake); window.clearTimeout(t); };
    }, [isFs]);

    const enterFs = useCallback(() => { document.documentElement.requestFullscreen?.().catch(() => {}); }, []);
    const exitFs = useCallback(() => { document.exitFullscreen?.().catch(() => {}); }, []);

    // Never leave the login-less NOC wall a silent black rectangle — that reads
    // as a total platform outage. Show an explicit loading/reconnecting state
    // (the 30s auto-refresh clears `error` and swaps in the board on recovery).
    if (!data) {
        return (
            <div style={{ position: 'fixed', inset: 0, background: '#000', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 18, color: '#fff' }}>
                <PulseGlyph size={64} />
                {error ? (
                    <>
                        <div style={{ fontFamily: 'var(--font-heading)', fontSize: 28, fontWeight: 700 }}>Live metrics unavailable</div>
                        <div style={{ fontFamily: 'var(--font-mono)', fontSize: 15, color: '#9aa4b2' }}>
                            Reconnecting automatically… ({error})
                        </div>
                    </>
                ) : (
                    <div style={{ fontFamily: 'var(--font-mono)', fontSize: 18, color: '#9aa4b2' }}>
                        {loading ? 'Loading live metrics…' : 'Waiting for live metrics…'}
                    </div>
                )}
            </div>
        );
    }

    const showExit = isFs && !pointerIdle;

    return (
        <div style={{ position: 'fixed', inset: 0, background: '#000', display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden', cursor: isFs && pointerIdle ? 'none' : 'default' }}>
            <div
                style={{
                    width: CW, height: CH, flex: 'none', transform: `scale(${scale})`, transformOrigin: 'center', position: 'relative',
                    background: 'var(--bg)', color: 'var(--fg)', padding: 48, display: 'flex', flexDirection: 'column', gap: 28,
                    animation: reduced ? 'none' : 'nocPixelShift 150s ease-in-out infinite',
                }}
            >
                <TopBar data={data} onEnterFs={enterFs} isFs={isFs} />
                <div style={{ display: 'grid', gridTemplateColumns: '36% 1fr', gap: 28, flex: 1, minHeight: 0 }}>
                    <Hero data={data} />
                    <Carousel data={data} slide={slide} reduced={reduced} />
                </div>
                <RegionStrip data={data} />
                <Ticker data={data} reduced={reduced} />
            </div>

            {/* Exit affordance — a top-centre X that fades in on cursor movement
                while fullscreen, and auto-hides (with the cursor) when idle. */}
            {showExit && (
                <button
                    type="button"
                    onClick={exitFs}
                    title="Exit fullscreen (Esc)"
                    style={{
                        position: 'absolute', top: 18, left: '50%', transform: 'translateX(-50%)', zIndex: 10,
                        display: 'inline-flex', alignItems: 'center', gap: 8, padding: '9px 18px', cursor: 'pointer',
                        background: 'color-mix(in srgb, var(--crit) 18%, transparent)', border: '1px solid color-mix(in srgb, var(--crit) 45%, transparent)',
                        color: 'var(--crit-fg)', fontFamily: 'var(--font-mono)', fontSize: 13, fontWeight: 700, letterSpacing: '0.04em',
                        backdropFilter: 'blur(8px)', WebkitBackdropFilter: 'blur(8px)', animation: reduced ? 'none' : 'nocFadeUp 0.25s ease-out',
                    }}
                >
                    <X size={16} strokeWidth={2.25} /> Exit fullscreen
                </button>
            )}
        </div>
    );
}

function TopBar({ data, onEnterFs, isFs }: { data: SentinelData; onEnterFs: () => void; isFs: boolean }) {
    const [clock, setClock] = useState('');
    useEffect(() => {
        const f = () => new Date().toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit', timeZone: 'UTC' });
        // Client-only clock: '' on server (no hydration mismatch), real time on mount.
        // eslint-disable-next-line react-hooks/set-state-in-effect
        setClock(f());
        const id = setInterval(() => setClock(f()), 1000);
        return () => clearInterval(id);
    }, []);
    const status = uptimeStatus(data.overview.overallUptime);
    return (
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
                <PulseGlyph size={56} />
                <div>
                    <div style={{ fontFamily: 'var(--font-heading)', fontWeight: 700, fontSize: 26 }}>UpTime Sentinel</div>
                    <div className="eyebrow" style={{ color: 'var(--accent)', fontSize: 13 }}>Command Wall · Live</div>
                </div>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 24 }}>
                <span style={{ fontFamily: 'var(--font-heading)', fontWeight: 700, fontSize: 22, color: STATUS_RAW[status] }}>
                    {status === 'healthy' ? 'OPERATIONAL' : status === 'warning' ? 'DEGRADED' : 'CRITICAL'}
                </span>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, fontFamily: 'var(--font-mono)', fontSize: 15, color: 'var(--ok-fg)' }}><LiveDot color="var(--ok)" size={11} /> LIVE</span>
                <span className="tnum" style={{ fontFamily: 'var(--font-mono)', fontSize: 30, color: 'var(--fg)' }}>{clock} <span style={{ fontSize: 16, color: 'var(--fg-3)' }}>UTC</span></span>
                {!isFs && (
                    <button
                        type="button"
                        onClick={onEnterFs}
                        title="Enter fullscreen"
                        style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '8px 14px', cursor: 'pointer', background: 'var(--card-bg)', border: '1px solid var(--hair)', color: 'var(--fg-2)', fontFamily: 'var(--font-mono)', fontSize: 13 }}
                    >
                        <Maximize2 size={16} strokeWidth={1.75} /> Fullscreen
                    </button>
                )}
            </div>
        </div>
    );
}

function Hero({ data }: { data: SentinelData }) {
    const o = data.overview;
    const status = uptimeStatus(o.overallUptime);
    const statusLabel = status === 'healthy' ? 'Operational' : status === 'warning' ? 'Degraded' : 'Critical';
    // Error budget = share of the 0.1% monthly downtime allowance still unspent.
    // Below zero the budget is blown — show "Exhausted" rather than a wild
    // negative like -23462%.
    const budget = ((o.overallUptime - 99.9) / 0.1) * 100;
    const budgetExhausted = budget < 0;
    return (
        <div className="glass-card" style={{ padding: 40, display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: 14 }}>
            <div className="eyebrow" style={{ fontSize: 15 }}>Global uptime · 30-day rolling</div>
            <div className="tnum" style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'clamp(120px, 12vw, 200px)', lineHeight: 0.9, color: STATUS_RAW[status] }}>
                <CountUp value={o.overallUptime} decimals={2} />%
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginTop: 6 }}>
                <span className="pill" style={{ padding: '8px 18px', background: `color-mix(in srgb, ${STATUS_RAW[status]} 16%, transparent)`, border: `1px solid color-mix(in srgb, ${STATUS_RAW[status]} 40%, transparent)`, color: STATUS_RAW[status], fontFamily: 'var(--font-mono)', fontSize: 16, fontWeight: 700 }}>{statusLabel}</span>
                <Delta value={o.uptimeTrend} goodWhenUp />
            </div>
            <div style={{ display: 'flex', gap: 40, marginTop: 18, fontFamily: 'var(--font-mono)', fontSize: 16, color: 'var(--fg-2)' }}>
                <div><div style={{ color: 'var(--fg-3)', fontSize: 13 }}>SLA TARGET</div><div className="tnum" style={{ fontSize: 24, color: 'var(--fg)' }}>99.90%</div></div>
                <div><div style={{ color: 'var(--fg-3)', fontSize: 13 }}>ERROR BUDGET</div><div className="tnum" style={{ fontSize: 24, color: budgetExhausted ? 'var(--crit-fg)' : 'var(--ok-fg)' }}>{budgetExhausted ? 'Exhausted' : `${budget.toFixed(0)}%`}</div></div>
            </div>
        </div>
    );
}

const SLIDES = [
    { title: 'Overview', icon: LayoutGrid },
    { title: 'Network', icon: Network },
    { title: 'Incidents', icon: AlertTriangle },
    { title: 'Performance', icon: Gauge },
];

function Carousel({ data, slide, reduced }: { data: SentinelData; slide: number; reduced: boolean }) {
    const Icon = SLIDES[slide].icon;
    return (
        <div className="glass-card" style={{ padding: 36, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 20 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 12, fontFamily: 'var(--font-heading)', fontWeight: 700, fontSize: 24 }}>
                    <Icon size={26} strokeWidth={1.75} style={{ color: 'var(--accent)' }} /> {SLIDES[slide].title}
                </div>
                <div style={{ display: 'flex', gap: 8 }}>
                    {SLIDES.map((_, i) => (
                        <span key={i} style={{ width: i === slide ? 28 : 8, height: 8, borderRadius: 4, background: i === slide ? 'var(--cyan)' : 'var(--hair-2)', boxShadow: i === slide ? '0 0 8px var(--cyan)' : 'none', transition: 'width 0.3s' }} />
                    ))}
                </div>
            </div>
            <div key={slide} style={{ flex: 1, animation: reduced ? 'none' : 'nocFadeUp 0.5s ease-out' }}>
                {slide === 0 && <SlideOverview data={data} />}
                {slide === 1 && <SlideNetwork data={data} />}
                {slide === 2 && <SlideIncidents data={data} />}
                {slide === 3 && <SlidePerformance data={data} />}
            </div>
            <div style={{ height: 4, background: 'var(--hair)', marginTop: 16 }}>
                <div key={slide} style={{ height: '100%', background: 'linear-gradient(90deg, var(--cyan), var(--violet))', animation: reduced ? 'none' : 'wallProg 15s linear forwards', width: reduced ? '100%' : 0 }} />
            </div>
            <style>{`@keyframes wallProg { from { width: 0 } to { width: 100% } }`}</style>
        </div>
    );
}

function BigStat({ label, value, color }: { label: string; value: string; color?: string }) {
    return (
        <div>
            <div className="eyebrow" style={{ fontSize: 13 }}>{label}</div>
            <div className="tnum" style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 56, color: color ?? 'var(--fg)', lineHeight: 1 }}>{value}</div>
        </div>
    );
}

function SlideOverview({ data }: { data: SentinelData }) {
    const o = data.overview;
    return (
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 28, height: '100%', alignContent: 'center' }}>
            <BigStat label="Platform uptime" value={`${o.overallUptime.toFixed(2)}%`} color="var(--ok-fg)" />
            <BigStat label="Active incidents" value={String(o.activeIncidents)} color={o.activeIncidents > 0 ? 'var(--crit-fg)' : 'var(--ok-fg)'} />
            <BigStat label="Avg response" value={`${o.avgResponseTime} ms`} color="var(--warn-fg)" />
            <BigStat label="Monitors up" value={`${o.activeMonitors}/${o.totalMonitors}`} />
        </div>
    );
}

function SlideNetwork({ data }: { data: SentinelData }) {
    const up = data.monitors.filter((m) => m.status === 'up').length;
    const withinSla = data.countryBreakdown.filter((c) => c.uptime >= 99.9).length;
    const lowest = [...data.countryBreakdown].sort((a, b) => a.uptime - b.uptime).slice(0, 3);
    return (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 22, height: '100%', justifyContent: 'center' }}>
            <div style={{ display: 'flex', gap: 48 }}>
                <BigStat label="Monitors online" value={`${up}/${data.monitors.length}`} color="var(--ok-fg)" />
                <BigStat label="Regions within SLA" value={`${withinSla}/${data.countryBreakdown.length}`} />
            </div>
            <div>
                <div className="eyebrow" style={{ fontSize: 13, marginBottom: 8 }}>Lowest uptime</div>
                {lowest.map((c) => (
                    <div key={c.code} style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--font-mono)', fontSize: 18, padding: '4px 0', color: 'var(--fg-2)' }}>
                        <span>{FLAGS[c.code]} {c.country}</span>
                        <span className="tnum" style={{ color: STATUS_RAW[uptimeStatus(c.uptime)] }}>{c.uptime.toFixed(2)}%</span>
                    </div>
                ))}
            </div>
        </div>
    );
}

function SlideIncidents({ data }: { data: SentinelData }) {
    const downNow = data.recentAlerts.filter((a) => a.status === 'down').length;
    const top = [...data.topIssues].sort((a, b) => b.incidents - a.incidents).slice(0, 4);
    const downMonitors = data.monitors.filter((m) => m.status === 'down').slice(0, 4);
    return (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 22, height: '100%', justifyContent: 'center' }}>
            <div style={{ display: 'flex', gap: 48 }}>
                <BigStat label="Active incidents" value={String(data.overview.activeIncidents)} color={data.overview.activeIncidents > 0 ? 'var(--crit-fg)' : 'var(--ok-fg)'} />
                <BigStat label="Down now" value={String(downNow)} color={downNow > 0 ? 'var(--crit-fg)' : 'var(--ok-fg)'} />
            </div>
            <div>
                {top.length > 0 ? (
                    <>
                        <div className="eyebrow" style={{ fontSize: 13, marginBottom: 8 }}>Most affected · 30 days</div>
                        {top.map((t) => (
                            <div key={t.id} style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--font-mono)', fontSize: 18, padding: '4px 0', color: 'var(--fg-2)' }}>
                                <span>{t.name}</span><span className="tnum" style={{ color: 'var(--crit-fg)' }}>{t.incidents}×</span>
                            </div>
                        ))}
                    </>
                ) : downMonitors.length > 0 ? (
                    <>
                        <div className="eyebrow" style={{ fontSize: 13, marginBottom: 8 }}>Currently down</div>
                        {downMonitors.map((m) => (
                            <div key={m.id} style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--font-mono)', fontSize: 18, padding: '4px 0', color: 'var(--fg-2)' }}>
                                <span>{FLAGS[m.region]} {m.name}</span><span className="tnum" style={{ color: 'var(--crit-fg)' }}>DOWN</span>
                            </div>
                        ))}
                    </>
                ) : (
                    <div style={{ display: 'flex', alignItems: 'center', gap: 12, color: 'var(--ok-fg)', fontFamily: 'var(--font-mono)', fontSize: 20, padding: '8px 0' }}>
                        <StatusDot status="healthy" size={10} /> No incidents recorded in the last 30 days.
                    </div>
                )}
            </div>
        </div>
    );
}

function SlidePerformance({ data }: { data: SentinelData }) {
    const p = data.responsePercentiles;
    const rows: { k: string; v: number; max: number }[] = [
        { k: 'P50', v: p.p50, max: 400 }, { k: 'P95', v: p.p95, max: 1000 }, { k: 'P99', v: p.p99, max: 2000 },
    ];
    return (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 26, height: '100%', justifyContent: 'center' }}>
            {rows.map((r) => {
                const st = responseStatus(r.v);
                return (
                    <div key={r.k}>
                        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6 }}>
                            <span className="eyebrow" style={{ fontSize: 14 }}>{r.k}</span>
                            <span className="tnum" style={{ fontFamily: 'var(--font-display)', fontSize: 32, fontWeight: 600, color: STATUS_RAW[st] }}>{r.v} ms</span>
                        </div>
                        <div style={{ height: 10, background: 'var(--hair)' }}><div style={{ width: `${Math.min(100, (r.v / r.max) * 100)}%`, height: '100%', background: STATUS_RAW[st] }} /></div>
                    </div>
                );
            })}
        </div>
    );
}

function RegionStrip({ data }: { data: SentinelData }) {
    return (
        <div style={{ display: 'grid', gridTemplateColumns: `repeat(${data.countryBreakdown.length}, 1fr)`, gap: 14 }}>
            {data.countryBreakdown.map((c) => {
                const st = uptimeStatus(c.uptime);
                const up = data.monitors.filter((m) => m.region === c.code && m.status === 'up').length;
                const tot = data.monitors.filter((m) => m.region === c.code).length;
                return (
                    <div key={c.code} className="card" style={{ padding: 16, borderTop: `3px solid ${STATUS_RAW[st]}`, textAlign: 'center' }}>
                        <div style={{ fontSize: 28 }}>{FLAGS[c.code]}</div>
                        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6, fontFamily: 'var(--font-mono)', fontSize: 14, color: 'var(--fg-2)' }}><StatusDot status={st} size={7} /> {c.code}</div>
                        <div className="tnum" style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 30, color: STATUS_RAW[st] }}>{c.uptime.toFixed(1)}%</div>
                        <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--fg-3)' }}>{up}/{tot} up</div>
                    </div>
                );
            })}
        </div>
    );
}

function Ticker({ data, reduced }: { data: SentinelData; reduced: boolean }) {
    const items = [...data.recentAlerts, ...data.recentAlerts]; // duplicate for seamless loop
    return (
        <div style={{ display: 'flex', alignItems: 'center', gap: 0, background: 'var(--panel)', border: '1px solid var(--hair)', overflow: 'hidden', height: 52 }}>
            <span style={{ flex: 'none', padding: '0 20px', height: '100%', display: 'inline-flex', alignItems: 'center', background: 'var(--crit)', color: '#fff', fontFamily: 'var(--font-heading)', fontWeight: 700, fontSize: 15, letterSpacing: '0.1em' }}>ALERTS</span>
            <div style={{ overflow: 'hidden', flex: 1 }}>
                <div style={{ display: 'inline-flex', alignItems: 'center', gap: 0, whiteSpace: 'nowrap', animation: reduced ? 'none' : 'nocMarquee 42s linear infinite' }}>
                    {items.map((a, i) => {
                        const down = a.status === 'down';
                        return (
                            <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 10, padding: '0 24px', fontFamily: 'var(--font-mono)', fontSize: 16, color: 'var(--fg-2)' }}>
                                <span style={{ width: 9, height: 9, borderRadius: '50%', background: down ? 'var(--crit)' : 'var(--ok)' }} />
                                <strong style={{ color: 'var(--fg)' }}>{a.monitorName}</strong>
                                <span style={{ color: down ? 'var(--crit-fg)' : 'var(--ok-fg)' }}>{down ? 'went DOWN' : `recovered · ${a.responseTime}ms`}</span>
                                <span className="slash" style={{ marginLeft: 8 }} />
                            </span>
                        );
                    })}
                </div>
            </div>
        </div>
    );
}
