/* global React */
const { useState, useEffect, useRef, useMemo } = React;

// --- Eyebrow label (was bracket label — now soft, no brackets)
function BracketLabel({ children, className = "", style = {} }) {
  return <span className={"bracket-label " + className} style={style}>{children}</span>;
}

// --- Mono meta
function MonoMeta({ children, style = {} }) {
  return <span className="mono-meta" style={style}>{children}</span>;
}

// --- Button
function Button({ children, variant = "primary", icon = false, onClick, type = "button", style = {} }) {
  return (
    <button type={type} className={"btn btn-" + variant} onClick={onClick} style={style}>
      <span>{children}</span>
      {icon && <span className="btn-arrow">→</span>}
    </button>
  );
}

// --- Section header
function SectionHead({ title, meta, style = {} }) {
  return (
    <div className="section-head" style={style}>
      {typeof title === "string" ? <BracketLabel>{title}</BracketLabel> : title}
      {meta && <MonoMeta>{meta}</MonoMeta>}
    </div>
  );
}

// --- Logo mark
function LogoMark({ size = 16, color = "currentColor" }) {
  return (
    <svg width={size} height={size} viewBox="0 0 40 40" fill="none">
      <rect x="0.5" y="0.5" width="39" height="39" stroke={color} />
      <path d="M10 28L20 12L30 28M14 22H26" stroke={color} strokeWidth="1.5" strokeLinecap="square" />
    </svg>
  );
}

// --- Live clock (Fort Worth — America/Chicago)
function LiveClock() {
  const [t, setT] = useState(() => new Date());
  useEffect(() => {
    const id = setInterval(() => setT(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  const fmt = useMemo(() => new Intl.DateTimeFormat("en-US", {
    hour: "2-digit", minute: "2-digit", hour12: false, timeZone: "America/Chicago"
  }), []);
  return (
    <span className="nav-clock">
      <span className="live-dot" />
      <span>Fort Worth · {fmt.format(t)} CT</span>
    </span>
  );
}

// --- Animated counter (count up)
function Counter({ to, dur = 1200, suffix = "" }) {
  const [v, setV] = useState(0);
  const ref = useRef(null);
  const ran = useRef(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting && !ran.current) {
        ran.current = true;
        const start = performance.now();
        const tick = (now) => {
          const p = Math.min(1, (now - start) / dur);
          const eased = 1 - Math.pow(1 - p, 3);
          setV(to * eased);
          if (p < 1) requestAnimationFrame(tick);
        };
        requestAnimationFrame(tick);
      }
    }, { threshold: 0.5 });
    io.observe(el);
    return () => io.disconnect();
  }, [to, dur]);
  const display = to >= 100 ? Math.round(v) : v.toFixed(1).replace(/\.0$/, "");
  return <span ref={ref}>{display}{suffix && <span className="unit">{suffix}</span>}</span>;
}

// --- Generative art card background. Deterministic from seed.
function GenerativeArt({ seed = 1, variant = "lines" }) {
  const layers = [];
  // simple seeded PRNG
  let s = seed * 9301 + 49297;
  const rand = () => { s = (s * 9301 + 49297) % 233280; return s / 233280; };

  // Droplet: clean silhouette, just the shape
  if (variant === "droplet") {
    const g = "d" + seed;
    const dp = "M 200 46 C 256 78, 284 154, 200 250 C 116 154, 144 78, 200 46 Z";
    return (
      <svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice" width="100%" height="100%">
        <defs>
          <radialGradient id={g} cx="50%" cy="40%" r="72%">
            <stop offset="0%" stopColor="#181818" />
            <stop offset="100%" stopColor="#060606" />
          </radialGradient>
        </defs>
        <rect width="400" height="300" fill={"url(#" + g + ")"} />
        <path d={dp} fill="#d6d6d6" />
      </svg>
    );
  }

  if (variant === "lines") {
    for (let i = 0; i < 60; i++) {
      const x1 = rand() * 400;
      const y1 = rand() * 300;
      const len = 40 + rand() * 200;
      const ang = rand() * Math.PI;
      const x2 = x1 + Math.cos(ang) * len;
      const y2 = y1 + Math.sin(ang) * len;
      layers.push(<line key={i} x1={x1} y1={y1} x2={x2} y2={y2} stroke="white" strokeOpacity={0.06 + rand() * 0.18} strokeWidth={0.4} />);
    }
  } else if (variant === "rings") {
    for (let i = 0; i < 20; i++) {
      layers.push(<circle key={i} cx={50 + rand() * 300} cy={50 + rand() * 200} r={20 + rand() * 80} stroke="white" strokeOpacity={0.04 + rand() * 0.16} fill="none" strokeWidth={0.5} />);
    }
  } else if (variant === "blocks") {
    for (let i = 0; i < 30; i++) {
      const w = 10 + rand() * 90;
      const h = 10 + rand() * 90;
      layers.push(<rect key={i} x={rand() * 380} y={rand() * 280} width={w} height={h} stroke="white" fill="white" strokeOpacity={0.05 + rand() * 0.1} fillOpacity={0.02 + rand() * 0.06} />);
    }
  } else if (variant === "grid") {
    for (let i = 0; i < 14; i++) {
      layers.push(<line key={"v" + i} x1={i * 30 + 10} y1={0} x2={i * 30 + 10} y2={300} stroke="white" strokeOpacity={0.06 + rand() * 0.12} strokeWidth={0.3} />);
    }
    for (let i = 0; i < 11; i++) {
      layers.push(<line key={"h" + i} x1={0} y1={i * 30 + 5} x2={400} y2={i * 30 + 5} stroke="white" strokeOpacity={0.06 + rand() * 0.12} strokeWidth={0.3} />);
    }
    for (let i = 0; i < 8; i++) {
      layers.push(<rect key={"r" + i} x={Math.floor(rand() * 13) * 30 + 10} y={Math.floor(rand() * 10) * 30 + 5} width={30} height={30} fill="white" fillOpacity={0.05 + rand() * 0.1} />);
    }
  }
  return (
    <svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice" width="100%" height="100%">
      <defs>
        <radialGradient id={"g" + seed} cx="50%" cy="60%" r="60%">
          <stop offset="0%" stopColor="#1c1b1b" />
          <stop offset="100%" stopColor="#0a0a0a" />
        </radialGradient>
      </defs>
      <rect width="400" height="300" fill={"url(#g" + seed + ")"} />
      {layers}
    </svg>
  );
}

// --- Portrait placeholder (cinematic abstract figure)
function PortraitPlaceholder() {
  return (
    <svg viewBox="0 0 240 320" preserveAspectRatio="xMidYMid slice" width="100%" height="100%">
      <defs>
        <radialGradient id="pgrad" cx="50%" cy="35%" r="60%">
          <stop offset="0%" stopColor="#2a2a2a" />
          <stop offset="60%" stopColor="#131313" />
          <stop offset="100%" stopColor="#0a0a0a" />
        </radialGradient>
      </defs>
      <rect width="240" height="320" fill="url(#pgrad)" />
      {/* Abstract figure */}
      <ellipse cx="120" cy="120" rx="42" ry="52" fill="#1c1b1b" />
      <path d="M 70 180 Q 70 230 60 320 L 180 320 Q 170 230 170 180 Q 150 200 120 200 Q 90 200 70 180 Z" fill="#1c1b1b" />
      {/* Hair shadow */}
      <ellipse cx="120" cy="100" rx="44" ry="32" fill="#0a0a0a" />
      {/* Eye sockets */}
      <ellipse cx="105" cy="125" rx="6" ry="3" fill="#0a0a0a" opacity="0.7" />
      <ellipse cx="135" cy="125" rx="6" ry="3" fill="#0a0a0a" opacity="0.7" />
      {/* Highlight */}
      <ellipse cx="100" cy="105" rx="20" ry="40" fill="white" opacity="0.04" />
      {/* Scan lines */}
      {Array.from({ length: 80 }).map((_, i) => (
        <line key={i} x1={0} y1={i * 4} x2={240} y2={i * 4} stroke="black" strokeOpacity={0.12} strokeWidth={0.5} />
      ))}
    </svg>
  );
}

// --- Reveal-on-scroll wrapper
function Reveal({ children, delay = 0, as: As = "div", className = "" }) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setSeen(true); io.disconnect(); }
    }, { threshold: 0.15 });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const style = {
    opacity: seen ? 1 : 0,
    transform: seen ? "translateY(0)" : "translateY(16px)",
    transition: `opacity 600ms ${delay}ms cubic-bezier(0.2,0.8,0.2,1), transform 600ms ${delay}ms cubic-bezier(0.2,0.8,0.2,1)`,
  };
  return <As ref={ref} className={className} style={style}>{children}</As>;
}

// --- Scroll progress
function ScrollProgress() {
  const [w, setW] = useState(0);
  useEffect(() => {
    const onScroll = () => {
      const top = window.scrollY;
      const h = document.documentElement.scrollHeight - window.innerHeight;
      setW(h > 0 ? (top / h) * 100 : 0);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return <div className="scroll-progress" style={{ width: w + "%" }} />;
}

// --- Custom selection cursor (crosshair)
function CrosshairCursor({ enabled }) {
  const [p, setP] = useState({ x: -100, y: -100 });
  const [hovering, setHovering] = useState(false);
  useEffect(() => {
    if (!enabled) return;
    const onMove = (e) => setP({ x: e.clientX, y: e.clientY });
    const onOver = (e) => {
      const t = e.target;
      setHovering(!!(t && (t.closest("a, button, .project-card, .nav-links a, .cs-thumb, .nav-cta, .nav-brand, .ft-social a, .arsenal-cell, .skill-cell"))));
    };
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseover", onOver);
    return () => {
      window.removeEventListener("mousemove", onMove);
      window.removeEventListener("mouseover", onOver);
    };
  }, [enabled]);
  if (!enabled) return null;
  const sz = hovering ? 56 : 28;
  return (
    <div style={{
      position: "fixed",
      top: 0, left: 0,
      width: sz, height: sz,
      transform: `translate(${p.x - sz/2}px, ${p.y - sz/2}px)`,
      pointerEvents: "none",
      zIndex: 9999,
      transition: "width 220ms cubic-bezier(0.2,0.8,0.2,1), height 220ms cubic-bezier(0.2,0.8,0.2,1)",
      mixBlendMode: "difference",
    }}>
      <div style={{ position: "absolute", inset: 0, border: "1px solid white", boxSizing: "border-box" }} />
      <div style={{ position: "absolute", left: "50%", top: -8, bottom: -8, width: 1, background: "white" }} />
      <div style={{ position: "absolute", top: "50%", left: -8, right: -8, height: 1, background: "white" }} />
    </div>
  );
}

Object.assign(window, {
  Button, BracketLabel, MonoMeta, SectionHead, LogoMark,
  LiveClock, Counter, GenerativeArt, PortraitPlaceholder,
  Reveal, ScrollProgress, CrosshairCursor,
});
