import { motion, useReducedMotion } from "framer-motion";
import { useEffect, useMemo, useRef, useState } from "react";
import { cn } from "@/lib/utils";
import scanGrid from "@/assets/scan-repos-grid.jpg";
import { useT } from "@/i18n/LanguageProvider";

/**
 * Hero visual — "The Machine".
 *
 * Homage to Person of Interest: a surveillance-AI interface scanning subjects
 * in real time. White corner brackets frame "irrelevant" nodes, red brackets
 * mark Persons of Interest. A central admin terminal streams ASCII telemetry,
 * coordinates tick, a triangular relationship graph forms between subjects,
 * and a horizon scan-line sweeps the canvas. Pure CRT / DARPA aesthetic.
 *
 * Uses semantic tokens (`foreground`, `destructive`, `muted-foreground`,
 * `background`) so it stays on-theme with the rest of the site while looking
 * unmistakably like THE MACHINE.
 */

const SIZE = 460;

type Subject = {
  id: string;
  x: number;
  y: number;
  poi: boolean; // Person of Interest -> red brackets
  label: string;
  ssn: string;
  status: string;
};

const STATIC_SUBJECTS: Subject[] = [
  { id: "P-01", x: 86, y: 110, poi: true,  label: "AURA · COPILOT",   ssn: "PRJ-2026-0411", status: "RELEVANT" },
  { id: "P-02", x: 348, y: 92, poi: true,  label: "ATLAS · RAG-CORE", ssn: "PRJ-2026-0228", status: "RELEVANT" },
  { id: "P-03", x: 76, y: 318, poi: false, label: "ECHO · VOICE-OS",  ssn: "FUT-2027-0091", status: "FUTURE SIGNAL" },
  { id: "P-04", x: 372, y: 332,poi: false, label: "NOVA · AGENT-MESH",ssn: "FUT-2027-0143", status: "FUTURE SIGNAL" },
  { id: "P-05", x: 232, y: 60, poi: true,  label: "HELIX · OPS-AI",   ssn: "PRJ-2026-0001", status: "FLAGSHIP" },
];

/** Detailed dossiers — typed out in the INNOVATION_TARGET panel */
type Dossier = {
  id: string;
  codename: string;
  vector: string;
  novelty: number;   // 0..1
  funding: string;
  patents: number;
  arxiv: number;
  eta: string;
  payoff: string;
  classification: "RELEVANT" | "FUTURE SIGNAL" | "FLAGSHIP";
};

const DOSSIERS: Dossier[] = [
  {
    id: "P-05", codename: "HELIX · OPS-AI",
    vector: "autonomous-devops / self-healing CI",
    novelty: 0.94, funding: "$ 18.2M Series A",
    patents: 3, arxiv: 27, eta: "Q3 · 2026",
    payoff: "−62% MTTR · +4.1× deploy freq",
    classification: "FLAGSHIP",
  },
  {
    id: "P-02", codename: "ATLAS · RAG-CORE",
    vector: "graph-RAG / enterprise knowledge mesh",
    novelty: 0.89, funding: "$ 9.7M Seed-2",
    patents: 1, arxiv: 41, eta: "Q1 · 2026",
    payoff: "−81% hallucination rate",
    classification: "RELEVANT",
  },
  {
    id: "P-01", codename: "AURA · COPILOT",
    vector: "ambient agent / multimodal intent",
    novelty: 0.87, funding: "$ 12.4M Series A",
    patents: 2, arxiv: 33, eta: "Q4 · 2026",
    payoff: "+3.6× engineer throughput",
    classification: "RELEVANT",
  },
  {
    id: "P-04", codename: "NOVA · AGENT-MESH",
    vector: "swarm orchestration / 10⁴ agents",
    novelty: 0.92, funding: "pre-seed · stealth",
    patents: 0, arxiv: 12, eta: "Q2 · 2027",
    payoff: "horizon · category-defining",
    classification: "FUTURE SIGNAL",
  },
];

const ADMIN_LINES = [
  "> root@themachine:~# scan --projects --horizon=2y",
  "> indexing 4,128 repos / 982 research feeds",
  "> cross-reference patents · arXiv · funding",
  "> innovation graph delta computed",
  "> relevance score: 0.9971 · novelty: 0.87",
  "> dispatching team to opportunity vector",
  "> emerging signal locked · future detected",
  "> ARE YOU READY TO BUILD IT?",
];

const COORDS = [
  "40.7589° N · 73.9851° W",
  "40.7128° N · 74.0060° W",
  "40.7484° N · 73.9857° W",
  "40.7061° N · 74.0086° W",
];

// Corner-bracket size by subject importance
const Brackets = ({
  cx,
  cy,
  size,
  red,
  pulse,
  reduced,
}: {
  cx: number;
  cy: number;
  size: number;
  red: boolean;
  pulse: boolean;
  reduced: boolean;
}) => {
  const half = size / 2;
  const len = size * 0.32;
  const stroke = red ? "hsl(var(--destructive))" : "hsl(var(--foreground))";
  const sw = red ? 1.6 : 1.1;
  const corners = [
    [cx - half, cy - half, +1, +1],
    [cx + half, cy - half, -1, +1],
    [cx - half, cy + half, +1, -1],
    [cx + half, cy + half, -1, -1],
  ] as const;

  return (
    <motion.g
      animate={
        reduced || !pulse
          ? undefined
          : { opacity: red ? [0.7, 1, 0.7] : [0.55, 0.85, 0.55] }
      }
      transition={{ duration: red ? 1.2 : 2.4, repeat: Infinity, ease: "easeInOut" }}
    >
      {corners.map(([x, y, dx, dy], i) => (
        <g key={i}>
          <line x1={x} y1={y} x2={x + dx * len} y2={y} stroke={stroke} strokeWidth={sw} />
          <line x1={x} y1={y} x2={x} y2={y + dy * len} stroke={stroke} strokeWidth={sw} />
        </g>
      ))}
    </motion.g>
  );
};

const AIOrb = () => {
  const reduced = useReducedMotion() ?? false;
  const containerRef = useRef<HTMLDivElement>(null);
  const [inView, setInView] = useState(true);
  const [tick, setTick] = useState(0);
  const [coordIdx, setCoordIdx] = useState(0);
  const [logLines, setLogLines] = useState<string[]>(ADMIN_LINES.slice(0, 3));
  const [burst, setBurst] = useState(false);
  const [dossierIdx, setDossierIdx] = useState(0);
  const [typed, setTyped] = useState(0); // chars revealed in dossier "payoff"
  const [now, setNow] = useState<string>(() =>
    new Date().toISOString().replace("T", " · ").slice(0, 19) + " UTC",
  );
  const dossier = DOSSIERS[dossierIdx];

  // Viewport gating
  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    const io = new IntersectionObserver(
      ([e]) => setInView(e.isIntersecting),
      { threshold: 0.2 },
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);

  // Heartbeat
  useEffect(() => {
    if (reduced || !inView) return;
    const id = window.setInterval(() => {
      setTick((t) => t + 1);
      setCoordIdx((c) => (c + 1) % COORDS.length);
      setNow(new Date().toISOString().replace("T", " · ").slice(0, 19) + " UTC");
      setLogLines((prev) => {
        const next = [...prev, ADMIN_LINES[(prev.length) % ADMIN_LINES.length]];
        return next.slice(-6);
      });
    }, 1400);
    return () => window.clearInterval(id);
  }, [reduced, inView]);

  // Dossier rotation — new innovative project locked every ~5s
  useEffect(() => {
    if (reduced || !inView) return;
    const id = window.setInterval(() => {
      setDossierIdx((i) => (i + 1) % DOSSIERS.length);
      setTyped(0);
    }, 5200);
    return () => window.clearInterval(id);
  }, [reduced, inView]);

  // Typewriter for the dossier payoff line
  useEffect(() => {
    if (reduced) {
      setTyped(dossier.payoff.length);
      return;
    }
    if (!inView) return;
    if (typed >= dossier.payoff.length) return;
    const id = window.setTimeout(() => setTyped((n) => n + 1), 38);
    return () => window.clearTimeout(id);
  }, [typed, dossierIdx, reduced, inView, dossier.payoff]);

  // CTA "burst" -> momentary red overlay
  useEffect(() => {
    const onBurst = () => {
      setBurst(true);
      window.setTimeout(() => setBurst(false), 1200);
    };
    window.addEventListener("aiorb:burst", onBurst);
    return () => window.removeEventListener("aiorb:burst", onBurst);
  }, []);

  // Triangular relationship lines among POI + assets
  const links = useMemo(() => {
    const pts = STATIC_SUBJECTS;
    const out: { a: Subject; b: Subject }[] = [];
    for (let i = 0; i < pts.length; i++) {
      for (let j = i + 1; j < pts.length; j++) {
        out.push({ a: pts[i], b: pts[j] });
      }
    }
    return out;
  }, []);

  // The currently "interrogated" subject — cycles
  const focusId = STATIC_SUBJECTS[tick % STATIC_SUBJECTS.length].id;

  const { t } = useT();
  const focused = STATIC_SUBJECTS.find((s) => s.id === focusId)!;
  const liveSummary = t("orb.live.summary", {
    n: STATIC_SUBJECTS.length,
    r: STATIC_SUBJECTS.filter((s) => s.poi).length,
    f: STATIC_SUBJECTS.filter((s) => !s.poi).length,
    label: focused.label,
    status: focused.status,
  });

  return (
    <figure
      ref={containerRef}
      className="relative mx-auto w-full"
      style={{ maxWidth: "100%" }}
      aria-labelledby="aiorb-caption"
    >
      {/* Aspect-ratio spacer keeps the SVG viewBox proportions on any width */}
      <div style={{ paddingTop: "56%" }} aria-hidden="true" />
      <figcaption id="aiorb-caption" className="sr-only">
        {t("orb.caption")}
      </figcaption>
      {/* Live region for screen readers — updates with the focused subject */}
      <div className="sr-only" aria-live="polite" aria-atomic="true">
        {reduced ? t("orb.live.reduced") : ""}
        {liveSummary}
      </div>
      {/* Outer chassis */}
      <div className="absolute inset-0 rounded-md border border-foreground/20 bg-background/60 backdrop-blur-sm shadow-elegant overflow-hidden">
        {/* Satellite reticle background — futuristic schematic + slow parallax */}
        <motion.div
          aria-hidden="true"
          className="absolute -inset-[6%] pointer-events-none"
          initial={reduced ? false : { x: 0, y: 0, scale: 1.06 }}
          animate={
            reduced
              ? undefined
              : {
                  x: ["-1.2%", "1.2%", "-1.2%"],
                  y: ["-0.8%", "0.8%", "-0.8%"],
                  scale: [1.06, 1.09, 1.06],
                }
          }
          transition={{ duration: 28, repeat: Infinity, ease: "easeInOut" }}
        >
          <img
            src={scanGrid}
            alt=""
            aria-hidden="true"
            loading="lazy"
            width={1024}
            height={1024}
            className="h-full w-full object-cover opacity-30 mix-blend-screen select-none"
          />
          {/* Dedicated scanlines on top of the schematic */}
          <div
            className="absolute inset-0 mix-blend-overlay opacity-40"
            style={{
              backgroundImage:
                "repeating-linear-gradient(to bottom, transparent 0 2px, hsl(var(--destructive) / 0.22) 2px 3px)",
            }}
          />
          {!reduced && (
            <motion.div
              className="absolute left-0 right-0 h-8"
              style={{
                background:
                  "linear-gradient(to bottom, transparent, hsl(var(--destructive) / 0.18), transparent)",
                mixBlendMode: "screen",
              }}
              initial={{ top: "-10%" }}
              animate={{ top: ["-10%", "110%"] }}
              transition={{ duration: 9, repeat: Infinity, ease: "linear" }}
            />
          )}
        </motion.div>
        {/* Radial vignette — darken edges */}
        <div
          aria-hidden="true"
          className="absolute inset-0 pointer-events-none"
          style={{
            background:
              "radial-gradient(ellipse at center, transparent 25%, hsl(var(--background) / 0.92) 78%)",
          }}
        />
        {/* Top scrim — dossier legibility */}
        <div
          aria-hidden="true"
          className="absolute inset-x-0 top-0 h-[55%] pointer-events-none"
          style={{
            background:
              "linear-gradient(to bottom, hsl(var(--background) / 0.80) 0%, hsl(var(--background) / 0.50) 45%, transparent 100%)",
          }}
        />
        {/* Bottom scrim — terminal legibility */}
        <div
          aria-hidden="true"
          className="absolute inset-x-0 bottom-0 h-[40%] pointer-events-none"
          style={{
            background:
              "linear-gradient(to top, hsl(var(--background) / 0.85) 0%, hsl(var(--background) / 0.55) 50%, transparent 100%)",
          }}
        />
        {/* Pixel grid */}
        <div
          aria-hidden="true"
          className="absolute inset-0 opacity-[0.08]"
          style={{
            backgroundImage:
              "linear-gradient(hsl(var(--foreground)) 1px, transparent 1px), linear-gradient(90deg, hsl(var(--foreground)) 1px, transparent 1px)",
            backgroundSize: "20px 20px",
          }}
        />
        {/* Scanlines */}
        <div
          aria-hidden="true"
          className="absolute inset-0 pointer-events-none mix-blend-overlay opacity-30"
          style={{
            backgroundImage:
              "repeating-linear-gradient(to bottom, transparent 0 2px, hsl(var(--foreground) / 0.18) 2px 3px)",
          }}
        />
        {/* Sweeping scan line */}
        {!reduced && (
          <motion.div
            aria-hidden="true"
            className="absolute left-0 right-0 h-px"
            style={{
              background:
                "linear-gradient(90deg, transparent, hsl(var(--foreground)/0.85), transparent)",
              boxShadow: "0 0 12px hsl(var(--foreground)/0.6)",
            }}
            initial={{ top: 0 }}
            animate={{ top: ["0%", "100%", "0%"] }}
            transition={{ duration: 6, repeat: Infinity, ease: "linear" }}
          />
        )}

        {/* Burst overlay */}
        {burst && (
          <motion.div
            aria-hidden="true"
            className="absolute inset-0 pointer-events-none"
            initial={{ opacity: 0 }}
            animate={{ opacity: [0, 0.35, 0] }}
            transition={{ duration: 1.2, ease: "easeOut" }}
            style={{
              background:
                "radial-gradient(circle at 50% 50%, hsl(var(--destructive)/0.55), transparent 65%)",
            }}
          />
        )}
      </div>

      {/* SVG layer — graph & brackets */}
      <svg
        viewBox={`0 0 ${SIZE} ${SIZE}`}
        preserveAspectRatio="xMidYMid meet"
        className="absolute inset-0 z-10 h-full w-full overflow-visible"
      >
        {/* Faint relationship lattice */}
        <g>
          {links.map((l, i) => (
            <line
              key={i}
              x1={l.a.x}
              y1={l.a.y}
              x2={l.b.x}
              y2={l.b.y}
              stroke="hsl(var(--foreground))"
              strokeOpacity={0.12}
              strokeDasharray="3 4"
              strokeWidth={0.7}
            />
          ))}
        </g>

        {/* Highlighted triangle for currently focused subject -> two POIs */}
        {(() => {
          const focus = STATIC_SUBJECTS.find((s) => s.id === focusId)!;
          const pois = STATIC_SUBJECTS.filter((s) => s.poi && s.id !== focusId);
          return pois.map((p) => (
            <motion.line
              key={`hl-${focus.id}-${p.id}`}
              x1={focus.x}
              y1={focus.y}
              x2={p.x}
              y2={p.y}
              stroke="hsl(var(--destructive))"
              strokeWidth={1}
              strokeDasharray="6 4"
              initial={{ pathLength: 0, opacity: 0 }}
              animate={{ pathLength: 1, opacity: 0.75 }}
              transition={{ duration: 0.9, ease: "easeOut" }}
            />
          ));
        })()}

        {/* Subjects with corner brackets and metadata */}
        {STATIC_SUBJECTS.map((s) => {
          const focused = s.id === focusId;
          const sz = s.poi ? 64 : 52;
          const stroke = s.poi ? "hsl(var(--destructive))" : "hsl(var(--foreground))";
          return (
            <g key={s.id}>
              <Brackets
                cx={s.x}
                cy={s.y}
                size={sz + (focused ? 8 : 0)}
                red={s.poi}
                pulse={focused || s.poi}
                reduced={reduced}
              />
              {/* tiny crosshair */}
              <line x1={s.x - 4} y1={s.y} x2={s.x + 4} y2={s.y} stroke={stroke} strokeWidth={0.8} opacity={0.7} />
              <line x1={s.x} y1={s.y - 4} x2={s.x} y2={s.y + 4} stroke={stroke} strokeWidth={0.8} opacity={0.7} />
              {/* label */}
              <text
                x={s.x + sz / 2 + 6}
                y={s.y - sz / 2 + 8}
                fontFamily="ui-monospace, SFMono-Regular, monospace"
                fontSize="9"
                fill={stroke}
                opacity={0.95}
              >
                {s.id} · {s.status}
              </text>
              <text
                x={s.x + sz / 2 + 6}
                y={s.y - sz / 2 + 19}
                fontFamily="ui-monospace, SFMono-Regular, monospace"
                fontSize="8"
                fill="hsl(var(--muted-foreground))"
              >
                {s.label}
              </text>
              <text
                x={s.x + sz / 2 + 6}
                y={s.y - sz / 2 + 29}
                fontFamily="ui-monospace, SFMono-Regular, monospace"
                fontSize="7.5"
                fill="hsl(var(--muted-foreground))"
                opacity={0.7}
              >
                {s.ssn}
              </text>
            </g>
          );
        })}
      </svg>

      {/* Top status bar */}
      <div className="absolute top-2 left-2 right-2 z-20 flex items-center justify-between font-mono text-[10px] uppercase tracking-[0.18em] text-foreground/80">
        <div className="flex items-center gap-2">
          <span className="inline-block h-1.5 w-1.5 rounded-full bg-destructive animate-pulse" />
          <span>SCAN</span>
          <span className="text-muted-foreground">· REPOS 4_128</span>
        </div>
        <div className="text-muted-foreground tabular-nums">{now}</div>
      </div>

      {/* INNOVATION_TARGET dossier — animated, rotating */}
      <motion.div
        key={`dossier-${dossier.id}`}
        initial={reduced ? false : { opacity: 0, y: -6, filter: "blur(2px)" }}
        animate={{ opacity: 1, y: 0, filter: "blur(0px)" }}
        transition={{ duration: 0.45, ease: "easeOut" }}
        className="absolute top-9 left-1/2 -translate-x-1/2 z-20 w-[min(420px,72%)] font-mono text-[10px] leading-relaxed bg-background/90 border border-destructive/70 rounded-sm px-3 py-2 shadow-elegant backdrop-blur-md ring-1 ring-destructive/20"
        aria-live="polite"
        aria-atomic="true"
      >
        <div className="flex items-center justify-between text-[8.5px] uppercase tracking-[0.22em] mb-1.5">
          <div className="flex items-center gap-1.5 text-destructive">
            <span className="inline-block h-1.5 w-1.5 rounded-full bg-destructive animate-pulse" />
            INNOVATION_TARGET · LOCKED
          </div>
          <span className="text-muted-foreground">{dossier.id}</span>
        </div>

        <div className="text-foreground text-[11px] tracking-wider">
          {dossier.codename}
        </div>
        <div className="text-muted-foreground text-[9px] uppercase tracking-widest">
          vector · {dossier.vector}
        </div>

        <div className="mt-2 grid grid-cols-2 gap-x-3 gap-y-0.5 text-[9.5px]">
          <div className="text-muted-foreground">NOVELTY</div>
          <div className="text-right text-destructive tabular-nums">
            {(dossier.novelty * 100).toFixed(1)}%
          </div>
          <div className="text-muted-foreground">PATENTS</div>
          <div className="text-right text-foreground tabular-nums">
            {String(dossier.patents).padStart(2, "0")}
          </div>
          <div className="text-muted-foreground">arXiv refs</div>
          <div className="text-right text-foreground tabular-nums">
            {dossier.arxiv}
          </div>
          <div className="text-muted-foreground">FUNDING</div>
          <div className="text-right text-foreground">{dossier.funding}</div>
          <div className="text-muted-foreground">ETA</div>
          <div className="text-right text-foreground tabular-nums">{dossier.eta}</div>
          <div className="text-muted-foreground">CLASS</div>
          <div className="text-right text-destructive">{dossier.classification}</div>
        </div>

        {/* novelty bar */}
        <div className="mt-2">
          <div className="h-1 w-full bg-foreground/10 overflow-hidden">
            <motion.div
              key={`nov-${dossier.id}`}
              initial={reduced ? false : { width: 0 }}
              animate={{ width: `${dossier.novelty * 100}%` }}
              transition={{ duration: 0.9, ease: "easeOut" }}
              className="h-full bg-destructive"
              aria-hidden="true"
            />
          </div>
        </div>

        {/* Typewriter payoff */}
        <div className="mt-1.5 text-[10px] text-foreground/90 min-h-[1.1em]">
          <span className="text-muted-foreground">&gt; </span>
          {dossier.payoff.slice(0, typed)}
          {!reduced && typed < dossier.payoff.length && (
            <span className="ml-0.5 inline-block h-[10px] w-[6px] -mb-[1px] bg-destructive align-middle animate-pulse" />
          )}
        </div>
      </motion.div>

      {/* Bottom-left: admin terminal */}
      <div className="absolute bottom-2 left-2 z-20 w-[58%] font-mono text-[9.5px] leading-relaxed text-foreground bg-background/85 border border-foreground/20 rounded-sm px-2 py-1.5 backdrop-blur-md">
        <div className="flex items-center justify-between text-muted-foreground text-[8.5px] uppercase tracking-widest mb-1">
          <span>INNOVATION_FEED</span>
          <span className="text-destructive">ADMIN</span>
        </div>
        <div className="space-y-0.5 min-h-[78px]">
          {logLines.map((l, i) => (
            <div
              key={`${i}-${l}`}
              className={cn(
                "truncate",
                i === logLines.length - 1 && "text-destructive",
              )}
            >
              {l}
            </div>
          ))}
        </div>
      </div>

      {/* Bottom-right: coordinates / threat panel */}
      <div className="absolute bottom-2 right-2 z-20 font-mono text-[9.5px] text-foreground bg-background/85 border border-foreground/20 rounded-sm px-2 py-1.5 w-[36%] backdrop-blur-md">
        <div className="text-muted-foreground text-[8.5px] uppercase tracking-widest mb-1">
          PROJECT_LOCK
        </div>
        <div className="tabular-nums">{COORDS[coordIdx]}</div>
        <div className="mt-2 text-muted-foreground text-[8.5px] uppercase tracking-widest">
          RELEVANCE
        </div>
        <div className="mt-0.5 flex items-center gap-1">
          {Array.from({ length: 10 }).map((_, i) => {
            const filled = i < (5 + ((tick * 3) % 5));
            return (
              <span
                key={i}
                className={cn(
                  "h-2 w-2 border",
                  filled
                    ? "bg-destructive border-destructive"
                    : "border-foreground/30",
                )}
              />
            );
          })}
        </div>
      </div>

      {/* Center reticle / Machine glyph */}
      <div className="pointer-events-none absolute inset-0 z-10 flex items-center justify-center">
        <div className="flex flex-col items-center text-center">
          <div className="font-mono text-[9px] uppercase tracking-[0.4em] text-muted-foreground">
            the · machine
          </div>
          <div className="mt-1 font-mono text-[10px] text-foreground/70">
            ◢ ◣
          </div>
          <div className="font-mono text-[10px] text-foreground/70">
            ◥ ◤
          </div>
          <div className="mt-1 font-mono text-[8.5px] uppercase tracking-[0.3em] text-destructive">
            relevant
          </div>
        </div>
      </div>

      {/* Magnetic CTA — styled as priority dispatch */}
      <motion.a
        href="/auth"
        onClick={() => window.dispatchEvent(new CustomEvent("aiorb:burst"))}
        whileHover={reduced ? undefined : { scale: 1.04, y: -2 }}
        whileTap={{ scale: 0.97 }}
        className="machine-btn absolute -bottom-14 left-1/2 -translate-x-1/2 z-30 inline-flex items-center gap-2 rounded-sm border border-destructive bg-background/80 px-4 py-2 font-mono text-[11px] uppercase tracking-[0.22em] text-destructive shadow-elegant"
        data-poi="true"
      >
        <span className="inline-block h-1.5 w-1.5 rounded-full bg-destructive animate-pulse" />
        {t("orb.cta")}
      </motion.a>
    </figure>
  );
};

export default AIOrb;
