'use client';

import { useEffect, useRef, useState, useCallback } from 'react';
import { motion, AnimatePresence } from 'framer-motion';

// Brand palette — sampled from /public/login.png (Evidence Action wordmark).
//   NAVY    deep brand navy (logo text)
//   MAGENTA brand accent (logo slash) — also used for the heartbeat
//   AMBER   secondary monitoring accent (kept from prior design)
const NAVY = '#0F1B3D';
const MAGENTA = '#EC008C';
const AMBER = '#F59E0B';
const _SUCCESS = '#10B981';
const FAILURE = '#EF4444';

interface Packet {
    id: string;
    lane: 0 | 1 | 2;
    speed: number;
    failed: boolean;
    failAt: number;
    size: number;
    color: string;
}

const LANE_Y = [0.28, 0.50, 0.72];
const PACKET_COLORS = [NAVY, NAVY, NAVY, MAGENTA, AMBER]; // mostly navy, occasional brand-pink + amber

let packetCounter = 0;

function makePacket(containerWidth: number): Packet {
    const failed = Math.random() < 0.18;
    const lane = Math.floor(Math.random() * 3) as 0 | 1 | 2;
    return {
        id: `p-${++packetCounter}`,
        lane,
        speed: 80 + Math.random() * 140,
        failed,
        failAt: containerWidth * (0.4 + Math.random() * 0.35),
        size: 6 + Math.random() * 4,
        color: PACKET_COLORS[Math.floor(Math.random() * PACKET_COLORS.length)],
    };
}

const BUFFER_SIZE = 300;
const NORMAL_Y = 50;

export default function LoginBackground() {
    const containerRef = useRef<HTMLDivElement>(null);
    const [packets, setPackets] = useState<Packet[]>([]);
    const [pulsing, setPulsing] = useState(false);
    const [containerSize, setContainerSize] = useState({ w: 1440, h: 900 });

    const svgRef = useRef<SVGSVGElement>(null);
    const pathRef = useRef<SVGPathElement>(null);
    const bufferRef = useRef<Float32Array>(new Float32Array(BUFFER_SIZE).fill(NORMAL_Y));
    const writeHeadRef = useRef(0);
    const heartColorRef = useRef(MAGENTA);
    const heartColorTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
    const rafRef = useRef<number>(0);
    const frameRef = useRef(0);

    const triggerFailure = useCallback(() => {
        setPulsing(true);

        const spike = [35, 10, 90, 55, 65, 50, 48, 48];
        for (const y of spike) {
            bufferRef.current[writeHeadRef.current % BUFFER_SIZE] = y;
            writeHeadRef.current++;
        }

        heartColorRef.current = FAILURE;
        if (pathRef.current) pathRef.current.setAttribute('stroke', FAILURE);

        if (heartColorTimerRef.current) clearTimeout(heartColorTimerRef.current);
        heartColorTimerRef.current = setTimeout(() => {
            heartColorRef.current = MAGENTA;
            if (pathRef.current) pathRef.current.setAttribute('stroke', MAGENTA);
        }, 800);
    }, []);

    useEffect(() => {
        const el = containerRef.current;
        if (!el) return;
        const ro = new ResizeObserver(([entry]) => {
            setContainerSize({ w: entry.contentRect.width, h: entry.contentRect.height });
        });
        ro.observe(el);
        setContainerSize({ w: el.clientWidth, h: el.clientHeight });
        return () => ro.disconnect();
    }, []);

    useEffect(() => {
        const id = setInterval(() => {
            setPackets(prev => {
                if (prev.length > 25) return prev;
                return [...prev, makePacket(containerSize.w)];
            });
        }, 600 + Math.random() * 600);
        return () => clearInterval(id);
    }, [containerSize.w]);

    useEffect(() => {
        let running = true;

        function tick() {
            if (!running) return;
            frameRef.current++;

            const y = NORMAL_Y + Math.sin(frameRef.current * 0.04) * 3 + (Math.random() - 0.5) * 0.8;
            bufferRef.current[writeHeadRef.current % BUFFER_SIZE] = y;
            writeHeadRef.current++;

            if (pathRef.current && svgRef.current) {
                const svgW = svgRef.current.clientWidth || containerSize.w;
                const svgH = 80;
                const total = BUFFER_SIZE;
                let d = '';
                for (let i = 0; i < total; i++) {
                    const idx = (writeHeadRef.current - total + i + BUFFER_SIZE * 10) % BUFFER_SIZE;
                    const x = (i / (total - 1)) * svgW;
                    const yVal = (bufferRef.current[idx] / 100) * svgH;
                    d += i === 0 ? `M ${x.toFixed(1)} ${yVal.toFixed(1)}` : ` L ${x.toFixed(1)} ${yVal.toFixed(1)}`;
                }
                pathRef.current.setAttribute('d', d);
            }

            rafRef.current = requestAnimationFrame(tick);
        }

        rafRef.current = requestAnimationFrame(tick);
        return () => {
            running = false;
            cancelAnimationFrame(rafRef.current);
            if (heartColorTimerRef.current) clearTimeout(heartColorTimerRef.current);
        };
    }, [containerSize.w]);

    const removePacket = useCallback((id: string) => {
        setPackets(prev => prev.filter(p => p.id !== id));
    }, []);

    // Node positions per lane — drawn as small navy circles at the
    // far-left (source) and far-right (destination) of each lane so the
    // packets visually originate from / terminate at network nodes.
    const NODE_INSET = 24;

    return (
        <div
            ref={containerRef}
            className="fixed inset-0 z-0 overflow-hidden"
            style={{
                background:
                    'radial-gradient(ellipse 80% 60% at 50% 0%, #FFE7F2 0%, #FFF6EE 35%, #FFFFFF 75%)',
            }}
        >
            {/* Subtle navy grid */}
            <div
                className="absolute inset-0 opacity-[0.05]"
                style={{
                    backgroundImage: `linear-gradient(${NAVY} 1px, transparent 1px), linear-gradient(90deg, ${NAVY} 1px, transparent 1px)`,
                    backgroundSize: '60px 60px',
                }}
            />

            {/* Lane divider lines + endpoint nodes */}
            {LANE_Y.map((y, i) => (
                <div key={i}>
                    <div
                        className="absolute left-0 right-0 h-px"
                        style={{
                            top: `${y * 100}%`,
                            background:
                                'linear-gradient(90deg, transparent, rgba(15,27,61,0.18) 15%, rgba(15,27,61,0.18) 85%, transparent)',
                        }}
                    />
                    {/* Source node (left) */}
                    <div
                        className="absolute rounded-full"
                        style={{
                            top: `calc(${y * 100}% - 4px)`,
                            left: NODE_INSET,
                            width: 8,
                            height: 8,
                            background: NAVY,
                            boxShadow: `0 0 12px ${NAVY}66`,
                        }}
                    />
                    {/* Destination node (right) */}
                    <div
                        className="absolute rounded-full"
                        style={{
                            top: `calc(${y * 100}% - 4px)`,
                            right: NODE_INSET,
                            width: 8,
                            height: 8,
                            background: MAGENTA,
                            boxShadow: `0 0 12px ${MAGENTA}66`,
                        }}
                    />
                </div>
            ))}

            {/* Data packets */}
            <AnimatePresence>
                {packets.map(packet => (
                    <PacketNode
                        key={packet.id}
                        packet={packet}
                        containerH={containerSize.h}
                        onFailure={triggerFailure}
                        onDone={removePacket}
                    />
                ))}
            </AnimatePresence>

            {/* Heartbeat SVG — bottom of screen, magenta brand-slash color */}
            <svg
                ref={svgRef}
                className="absolute left-0 right-0 w-full"
                style={{ bottom: '6%', height: '80px' }}
                viewBox={`0 0 ${containerSize.w} 80`}
                preserveAspectRatio="none"
            >
                <defs>
                    <filter id="glow-hb">
                        <feGaussianBlur stdDeviation="1.5" result="blur" />
                        <feMerge><feMergeNode in="blur" /><feMergeNode in="SourceGraphic" /></feMerge>
                    </filter>
                </defs>
                <path
                    ref={pathRef}
                    d=""
                    fill="none"
                    stroke={MAGENTA}
                    strokeWidth="1.8"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    filter="url(#glow-hb)"
                    opacity="0.85"
                />
            </svg>

            {/* Failure pulse — softer on bright background */}
            {pulsing && (
                <motion.div
                    className="absolute inset-0 pointer-events-none"
                    style={{ backgroundColor: FAILURE }}
                    animate={{ opacity: [0, 0.08, 0.03, 0] }}
                    transition={{ duration: 0.18, ease: 'easeOut' }}
                    onAnimationComplete={() => setPulsing(false)}
                />
            )}

            {/* Soft vignette to keep card focal */}
            <div
                className="absolute inset-0 pointer-events-none"
                style={{
                    background:
                        'radial-gradient(ellipse at center, transparent 30%, rgba(255,255,255,0.55) 100%)',
                }}
            />
        </div>
    );
}

function PacketNode({
    packet,
    containerH,
    onFailure,
    onDone,
}: {
    packet: Packet;
    containerH: number;
    onFailure: () => void;
    onDone: (id: string) => void;
}) {
    const y = LANE_Y[packet.lane] * containerH - packet.size / 2;
    const [hasFailed, setHasFailed] = useState(false);
    const travelTime = 1440 / packet.speed;

    if (packet.failed && !hasFailed) {
        return (
            <motion.div
                className="absolute rounded-sm"
                style={{
                    top: y,
                    width: packet.size,
                    height: packet.size,
                    backgroundColor: packet.color,
                    boxShadow: `0 0 ${packet.size * 1.5}px ${packet.color}aa`,
                }}
                initial={{ x: -packet.size, opacity: 1 }}
                animate={{ x: packet.failAt }}
                transition={{ duration: (packet.failAt / 1440) * travelTime, ease: [0.25, 0.46, 0.45, 0.94] }}
                onAnimationComplete={() => {
                    setHasFailed(true);
                    onFailure();
                    setTimeout(() => onDone(packet.id), 300);
                }}
                exit={{ scale: 0, opacity: 0, backgroundColor: FAILURE, transition: { duration: 0.25 } }}
            />
        );
    }

    if (hasFailed) {
        return (
            <motion.div
                className="absolute rounded-sm"
                style={{
                    top: y,
                    left: packet.failAt,
                    width: packet.size,
                    height: packet.size,
                    backgroundColor: FAILURE,
                    boxShadow: `0 0 ${packet.size * 2}px ${FAILURE}`,
                }}
                animate={{ scale: [1, 1.6, 0], opacity: [1, 1, 0] }}
                transition={{ duration: 0.3 }}
            />
        );
    }

    return (
        <motion.div
            className="absolute rounded-sm"
            style={{
                top: y,
                width: packet.size,
                height: packet.size,
                backgroundColor: packet.color,
                boxShadow: `0 0 ${packet.size * 1.5}px ${packet.color}66`,
            }}
            initial={{ x: -packet.size }}
            animate={{ x: 1460 }}
            transition={{
                duration: travelTime,
                ease: 'linear',
            }}
            onAnimationComplete={() => onDone(packet.id)}
        />
    );
}
