'use client';

/**
 * Mission Control rail shell — frames the four routed sections (Overview,
 * Network, Incidents, Performance). Slim 86px icon rail that hover-expands to
 * 268px as an overlay; translucent header floating over an ambient drifting
 * gradient. The standalone /executive/wall route is NOT in this group, so it
 * renders chrome-free.
 */
import { useEffect, useState } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import {
    LayoutGrid,
    Network,
    AlertTriangle,
    Gauge,
    Sun,
    Moon,
    RefreshCw,
    Bell,
    Download,
    LogOut,
} from 'lucide-react';
import { SentinelDataProvider, useSentinelContext } from '../_components/SentinelDataContext';
import { useTheme } from '../_components/ThemeProvider';
import { useReducedMotion } from '../_components/useReducedMotion';
import { PulseGlyph } from '../_components/PulseGlyph';
import { LiveDot, Slash } from '../_components/primitives';
import { useExecutiveExport } from '../_components/useExecutiveExport';

const NAV = [
    { href: '/executive/overview', label: 'Overview', icon: LayoutGrid },
    { href: '/executive/network', label: 'Network status', icon: Network },
    { href: '/executive/incidents', label: 'Incidents', icon: AlertTriangle, badgeKey: 'incidents' as const },
    { href: '/executive/performance', label: 'Performance', icon: Gauge },
];

const RAIL_COLLAPSED = 86;
const RAIL_EXPANDED = 268;

export default function RailLayout({ children }: { children: React.ReactNode }) {
    return (
        <SentinelDataProvider autoRefreshMs={30000}>
            <Shell>{children}</Shell>
        </SentinelDataProvider>
    );
}

function Shell({ children }: { children: React.ReactNode }) {
    const pathname = usePathname();
    const reduced = useReducedMotion();
    const { mode, toggle } = useTheme();
    const { data, loading, error, refreshing, refresh } = useSentinelContext();
    const { exportPdf, exporting } = useExecutiveExport();
    const [hover, setHover] = useState(false);

    const active = NAV.find((n) => pathname.startsWith(n.href)) ?? NAV[0];
    const incidents = data?.overview.activeIncidents ?? 0;
    // "degraded" = we have no data to show AND the last load failed. Only then
    // do we replace the blank <main> with an error panel and drop the green
    // "operational" chrome. A refresh blip that still has stale data keeps
    // rendering the board (the 30s auto-refresh clears `error` on recovery).
    const degraded = !!error && !data;

    return (
        <div style={{ position: 'relative', height: '100%', overflow: 'hidden' }}>
            {/* ambient drift backdrop */}
            <AmbientBackdrop reduced={reduced} />

            {/* RAIL */}
            <aside
                onMouseEnter={() => setHover(true)}
                onMouseLeave={() => setHover(false)}
                style={{
                    position: 'absolute',
                    top: 0,
                    left: 0,
                    height: '100%',
                    width: hover ? RAIL_EXPANDED : RAIL_COLLAPSED,
                    background: 'color-mix(in srgb, var(--panel) 92%, transparent)',
                    borderRight: '1px solid var(--hair)',
                    backdropFilter: 'blur(8px)',
                    WebkitBackdropFilter: 'blur(8px)',
                    zIndex: 30,
                    display: 'flex',
                    flexDirection: 'column',
                    transition: reduced ? 'none' : 'width 0.25s var(--ease)',
                    boxShadow: hover ? '8px 0 40px rgba(0,0,0,0.35)' : 'none',
                    overflow: 'hidden',
                }}
            >
                {/* brand */}
                <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '20px 22px 24px' }}>
                    <PulseGlyph size={42} />
                    <div style={{ opacity: hover ? 1 : 0, transition: 'opacity 0.2s', whiteSpace: 'nowrap' }}>
                        <div style={{ fontFamily: 'var(--font-heading)', fontWeight: 700, fontSize: 15, color: 'var(--fg)' }}>
                            UpTime Sentinel
                        </div>
                        <div className="eyebrow" style={{ color: 'var(--accent)' }}>Executive Command</div>
                    </div>
                </div>

                {/* nav */}
                <nav style={{ display: 'flex', flexDirection: 'column', gap: 4, padding: '0 14px', flex: 1 }}>
                    {NAV.map((item) => {
                        const Icon = item.icon;
                        const isActive = pathname.startsWith(item.href);
                        const badge = item.badgeKey === 'incidents' ? incidents : 0;
                        return (
                            <Link
                                key={item.href}
                                href={item.href}
                                style={{
                                    position: 'relative',
                                    display: 'flex',
                                    alignItems: 'center',
                                    gap: 14,
                                    padding: '12px 14px',
                                    textDecoration: 'none',
                                    color: isActive ? 'var(--accent)' : 'var(--fg-2)',
                                    background: isActive ? 'color-mix(in srgb, var(--accent) 16%, transparent)' : 'transparent',
                                    border: isActive ? '1px solid color-mix(in srgb, var(--accent) 35%, transparent)' : '1px solid transparent',
                                    filter: isActive ? 'drop-shadow(0 0 8px color-mix(in srgb, var(--accent) 50%, transparent))' : 'none',
                                }}
                            >
                                {isActive && (
                                    <span
                                        className="slash"
                                        style={{ position: 'absolute', left: -1, top: '50%', transform: 'translateY(-50%) skewX(-18deg)', height: 22 }}
                                    />
                                )}
                                <span style={{ position: 'relative', flex: 'none' }}>
                                    <Icon size={20} strokeWidth={1.5} />
                                    {badge > 0 && !hover && (
                                        <span style={{ position: 'absolute', top: -3, right: -3, width: 7, height: 7, borderRadius: '50%', background: 'var(--crit)' }} />
                                    )}
                                </span>
                                <span style={{ opacity: hover ? 1 : 0, transition: 'opacity 0.2s', whiteSpace: 'nowrap', fontFamily: 'var(--font-heading)', fontSize: 13, fontWeight: 500, flex: 1 }}>
                                    {item.label}
                                </span>
                                {badge > 0 && hover && (
                                    <span className="tnum pill" style={{ background: 'var(--crit)', color: '#fff', fontSize: 11, fontWeight: 700, padding: '1px 7px', fontFamily: 'var(--font-mono)' }}>
                                        {badge}
                                    </span>
                                )}
                            </Link>
                        );
                    })}
                </nav>

                {/* footer */}
                <div style={{ display: 'flex', flexDirection: 'column', gap: 4, padding: '0 14px 18px' }}>
                    <RailButton onClick={toggle} icon={mode === 'dark' ? <Sun size={20} strokeWidth={1.5} /> : <Moon size={20} strokeWidth={1.5} />} label={mode === 'dark' ? 'Light mode' : 'Dark mode'} hover={hover} />
                    <RailButton onClick={() => { window.location.href = '/executive'; }} icon={<LogOut size={20} strokeWidth={1.5} />} label="Sign out" hover={hover} danger />
                </div>
            </aside>

            {/* MAIN */}
            <div style={{ marginLeft: RAIL_COLLAPSED, position: 'relative', zIndex: 10, height: '100%', display: 'flex', flexDirection: 'column' }}>
                {/* header */}
                <header
                    style={{
                        flex: 'none',
                        zIndex: 20,
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'space-between',
                        gap: 24,
                        padding: '14px 28px',
                        background: 'color-mix(in srgb, var(--bg) 70%, transparent)',
                        backdropFilter: 'blur(14px)',
                        WebkitBackdropFilter: 'blur(14px)',
                        borderBottom: '1px solid var(--hair)',
                    }}
                >
                    <div>
                        <h1 style={{ margin: 0, fontFamily: 'var(--font-heading)', fontWeight: 700, fontSize: 28, color: 'var(--fg)', letterSpacing: '-0.01em', display: 'flex', alignItems: 'center', gap: 12 }}>
                            <Slash style={{ height: 24 }} />
                            {active.label}
                        </h1>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4 }}>
                            <LiveDot color={degraded ? 'var(--crit)' : 'var(--ok)'} size={7} />
                            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--fg-3)' }}>
                                {degraded
                                    ? 'Live data unavailable'
                                    : incidents > 0 ? `${incidents} active incident${incidents > 1 ? 's' : ''}` : 'All systems operational'}
                            </span>
                        </div>
                    </div>

                    <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
                        <LivePill degraded={degraded} />
                        <LiveClock />
                        <IconButton title="Refresh" onClick={refresh}>
                            <RefreshCw size={16} strokeWidth={1.75} style={{ animation: refreshing && !reduced ? 'spin 0.72s linear' : 'none' }} />
                        </IconButton>
                        <IconButton title="Alerts" badge={data?.recentAlerts.filter((a) => a.status === 'down').length ?? 0}>
                            <Bell size={16} strokeWidth={1.75} />
                        </IconButton>
                        <button
                            type="button"
                            disabled={exporting || !data}
                            onClick={() => data && exportPdf(data)}
                            className="pill"
                            style={{
                                display: 'inline-flex',
                                alignItems: 'center',
                                gap: 8,
                                padding: '9px 18px',
                                border: 'none',
                                cursor: data ? 'pointer' : 'default',
                                background: 'linear-gradient(135deg, var(--magenta), var(--violet))',
                                color: '#fff',
                                fontFamily: 'var(--font-heading)',
                                fontSize: 12,
                                fontWeight: 700,
                                textTransform: 'uppercase',
                                letterSpacing: '0.06em',
                                opacity: exporting ? 0.7 : 1,
                            }}
                        >
                            <Download size={15} strokeWidth={2} />
                            {exporting ? 'Exporting…' : 'Export'}
                        </button>
                    </div>
                </header>

                <main style={{ flex: 1, minHeight: 0, overflow: 'hidden', padding: 18, display: 'flex', flexDirection: 'column' }}>
                    {degraded
                        ? <ExecStatePanel kind="error" message={error} onRetry={refresh} refreshing={refreshing} />
                        : !data && loading
                            ? <ExecStatePanel kind="loading" />
                            : children}
                </main>
            </div>

            <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
        </div>
    );
}

function RailButton({ onClick, icon, label, hover, danger }: { onClick: () => void; icon: React.ReactNode; label: string; hover: boolean; danger?: boolean }) {
    return (
        <button
            type="button"
            onClick={onClick}
            style={{
                display: 'flex',
                alignItems: 'center',
                gap: 14,
                padding: '12px 14px',
                background: 'transparent',
                border: '1px solid transparent',
                cursor: 'pointer',
                color: danger ? 'var(--crit-fg)' : 'var(--fg-2)',
                textAlign: 'left',
                width: '100%',
            }}
        >
            <span style={{ flex: 'none' }}>{icon}</span>
            <span style={{ opacity: hover ? 1 : 0, transition: 'opacity 0.2s', whiteSpace: 'nowrap', fontFamily: 'var(--font-heading)', fontSize: 13, fontWeight: 500 }}>{label}</span>
        </button>
    );
}

function IconButton({ children, title, onClick, badge = 0 }: { children: React.ReactNode; title: string; onClick?: () => void; badge?: number }) {
    return (
        <button
            type="button"
            title={title}
            onClick={onClick}
            style={{
                position: 'relative',
                width: 40,
                height: 40,
                display: 'inline-flex',
                alignItems: 'center',
                justifyContent: 'center',
                background: 'var(--card-bg)',
                border: '1px solid var(--hair)',
                borderRadius: 0,
                color: 'var(--fg-2)',
                cursor: 'pointer',
            }}
        >
            {children}
            {badge > 0 && (
                <span className="tnum" style={{ position: 'absolute', top: -6, right: -6, minWidth: 16, height: 16, padding: '0 4px', borderRadius: 8, background: 'var(--crit)', color: '#fff', fontSize: 10, fontWeight: 700, fontFamily: 'var(--font-mono)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}>
                    {badge}
                </span>
            )}
        </button>
    );
}

function LivePill({ degraded }: { degraded?: boolean }) {
    const c = degraded ? 'var(--crit)' : 'var(--ok)';
    const fg = degraded ? 'var(--crit-fg)' : 'var(--ok-fg)';
    return (
        <span className="pill" style={{ display: 'inline-flex', alignItems: 'center', gap: 7, padding: '6px 12px', background: `color-mix(in srgb, ${c} 14%, transparent)`, border: `1px solid color-mix(in srgb, ${c} 35%, transparent)`, color: fg, fontFamily: 'var(--font-mono)', fontSize: 11, fontWeight: 700, letterSpacing: '0.1em' }}>
            <LiveDot color={c} size={8} />
            {degraded ? 'OFFLINE' : 'LIVE'}
        </span>
    );
}

/**
 * Fills the executive <main> when there is no data to show — either the first
 * load is still in flight ("loading") or the last load failed ("error"). This
 * replaces the previous silent blank viewport that read as a total outage.
 */
function ExecStatePanel({ kind, message, onRetry, refreshing }: { kind: 'error' | 'loading'; message?: string | null; onRetry?: () => void; refreshing?: boolean }) {
    return (
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 14, textAlign: 'center' }}>
            {kind === 'loading' ? (
                <>
                    <RefreshCw size={26} strokeWidth={1.5} style={{ color: 'var(--fg-3)', animation: 'spin 0.9s linear infinite' }} />
                    <div style={{ fontFamily: 'var(--font-mono)', fontSize: 13, color: 'var(--fg-3)' }}>Loading live metrics…</div>
                </>
            ) : (
                <>
                    <AlertTriangle size={26} strokeWidth={1.5} style={{ color: 'var(--crit)' }} />
                    <div style={{ fontFamily: 'var(--font-heading)', fontSize: 16, fontWeight: 700, color: 'var(--fg)' }}>Live metrics unavailable</div>
                    <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--fg-3)', maxWidth: 420 }}>
                        The executive report didn&apos;t load{message ? ` (${message})` : ''}. It retries automatically every 30s.
                    </div>
                    {onRetry && (
                        <button type="button" onClick={onRetry} disabled={refreshing} className="pill" style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '9px 18px', border: '1px solid var(--hair)', cursor: 'pointer', background: 'var(--card-bg)', color: 'var(--fg)', fontFamily: 'var(--font-heading)', fontSize: 12, fontWeight: 700 }}>
                            <RefreshCw size={14} strokeWidth={2} style={{ animation: refreshing ? 'spin 0.72s linear infinite' : 'none' }} />
                            {refreshing ? 'Retrying…' : 'Retry now'}
                        </button>
                    )}
                </>
            )}
        </div>
    );
}

function LiveClock() {
    const [now, setNow] = useState<string>('');
    useEffect(() => {
        const fmt = () =>
            new Date().toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit', timeZone: 'UTC' });
        // Client-only clock: starts '' on the server to avoid a hydration
        // mismatch, then sets the real time on mount. Intentional.
        // eslint-disable-next-line react-hooks/set-state-in-effect
        setNow(fmt());
        const id = setInterval(() => setNow(fmt()), 1000);
        return () => clearInterval(id);
    }, []);
    return (
        <span className="tnum" style={{ fontFamily: 'var(--font-mono)', fontSize: 13, color: 'var(--fg-2)', minWidth: 96, textAlign: 'right' }}>
            {now} UTC
        </span>
    );
}

function AmbientBackdrop({ reduced }: { reduced: boolean }) {
    const blob: React.CSSProperties = {
        position: 'absolute',
        borderRadius: '50%',
        filter: 'blur(120px)',
        opacity: 0.5,
        animation: reduced ? 'none' : 'nocDrift 28s ease-in-out infinite',
    };
    return (
        <div style={{ position: 'absolute', inset: 0, zIndex: 0, pointerEvents: 'none', overflow: 'hidden' }}>
            <div style={{ ...blob, width: 520, height: 520, top: -160, left: '12%', background: 'color-mix(in srgb, var(--magenta) 30%, transparent)' }} />
            <div style={{ ...blob, width: 460, height: 460, bottom: -180, right: '8%', background: 'color-mix(in srgb, var(--violet) 30%, transparent)', animationDelay: '-9s' }} />
        </div>
    );
}
