/* TimeOfDayVisual — gradient + constellation reflects local hour.
   Easter eggs: cursor parallax; triple-click time → speed through 24h. */
const TimeOfDayVisual = (function() {
  const { useState, useEffect, useRef } = React;

  // Returns a palette for an hour 0..23
  function paletteFor(hour) {
    // Five anchor moments: deep night, dawn, day, golden, dusk
    const anchors = [
      { h: 0,  bg: ["#0a1024", "#1a2540"], glow: "#5b8def", accent: "#a4bcfd" }, // night
      { h: 6,  bg: ["#1a2950", "#ffb088"], glow: "#ffb088", accent: "#fcd34d" }, // dawn
      { h: 10, bg: ["#3b82f6", "#bae6fd"], glow: "#84caff", accent: "#7CD4FD" }, // morning
      { h: 14, bg: ["#1e40af", "#60a5fa"], glow: "#84caff", accent: "#a4bcfd" }, // day
      { h: 18, bg: ["#7c2d12", "#f97316"], glow: "#fdb022", accent: "#fec84b" }, // golden
      { h: 21, bg: ["#1e1b4b", "#7c2d12"], glow: "#a78bfa", accent: "#c084fc" }, // dusk
      { h: 24, bg: ["#0a1024", "#1a2540"], glow: "#5b8def", accent: "#a4bcfd" },
    ];
    let lo = anchors[0], hi = anchors[anchors.length - 1];
    for (let i = 0; i < anchors.length - 1; i++) {
      if (hour >= anchors[i].h && hour <= anchors[i+1].h) { lo = anchors[i]; hi = anchors[i+1]; break; }
    }
    const t = (hour - lo.h) / (hi.h - lo.h || 1);
    const mix = (a, b) => {
      const pa = parseInt(a.slice(1), 16), pb = parseInt(b.slice(1), 16);
      const ar=(pa>>16)&255, ag=(pa>>8)&255, ab=pa&255;
      const br=(pb>>16)&255, bg=(pb>>8)&255, bb=pb&255;
      const r = Math.round(ar + (br-ar)*t), g = Math.round(ag + (bg-ag)*t), b2 = Math.round(ab + (bb-ab)*t);
      return "#" + ((1<<24) | (r<<16) | (g<<8) | b2).toString(16).slice(1);
    };
    return {
      bg: [mix(lo.bg[0], hi.bg[0]), mix(lo.bg[1], hi.bg[1])],
      glow: mix(lo.glow, hi.glow),
      accent: mix(lo.accent, hi.accent),
    };
  }

  function fmtTime(d) {
    let h = d.getHours();
    const m = d.getMinutes();
    const ampm = h >= 12 ? "PM" : "AM";
    h = h % 12; if (h === 0) h = 12;
    return `${h}:${String(m).padStart(2,'0')} ${ampm}`;
  }

  function greetingFor(hour) {
    if (hour < 5) return "Late night";
    if (hour < 12) return "Good morning";
    if (hour < 17) return "Good afternoon";
    if (hour < 21) return "Good evening";
    return "Good night";
  }

  function Visual({ onEgg, reduceMotion }) {
    const wrapRef = useRef(null);
    const [now, setNow] = useState(new Date());
    const [virtualHour, setVirtualHour] = useState(null); // overrides during demo
    const [demoActive, setDemoActive] = useState(false);
    const [mouse, setMouse] = useState({ x: 0.5, y: 0.5 });
    const clickTimes = useRef([]);

    useEffect(() => {
      const id = setInterval(() => setNow(new Date()), 60000);
      return () => clearInterval(id);
    }, []);

    // Virtual demo: 24h in 4s
    useEffect(() => {
      if (!demoActive) return;
      const start = performance.now();
      let raf;
      const tick = (t) => {
        const elapsed = (t - start) / 4000;
        if (elapsed >= 1) {
          setDemoActive(false); setVirtualHour(null); return;
        }
        setVirtualHour(elapsed * 24);
        raf = requestAnimationFrame(tick);
      };
      raf = requestAnimationFrame(tick);
      return () => cancelAnimationFrame(raf);
    }, [demoActive]);

    const hour = virtualHour ?? (now.getHours() + now.getMinutes() / 60);
    const pal = paletteFor(hour);

    const onMove = (e) => {
      if (reduceMotion) return;
      const r = wrapRef.current.getBoundingClientRect();
      setMouse({ x: (e.clientX - r.left) / r.width, y: (e.clientY - r.top) / r.height });
    };

    const onTimeClick = () => {
      const t = Date.now();
      clickTimes.current = [...clickTimes.current.filter((x) => t - x < 600), t];
      if (clickTimes.current.length >= 3) {
        clickTimes.current = [];
        setDemoActive(true);
        onEgg && onEgg("Fast-forward · 24h in 4s");
      }
    };

    const px = (mouse.x - 0.5) * 30;
    const py = (mouse.y - 0.5) * 30;

    // Constellation positions (stable seed)
    const stars = Array.from({ length: 80 }, (_, i) => ({
      x: ((i * 137) % 100),
      y: ((i * 73 + 23) % 100),
      r: 1 + (i % 3),
      depth: 0.3 + ((i % 5) / 7),
      bright: 0.3 + ((i * 17) % 70) / 100,
    }));

    // Sun/moon position based on hour
    const sunX = 0.15 + (hour / 24) * 0.7;
    const sunY = 0.7 - Math.sin((hour / 24) * Math.PI) * 0.45;
    const isDay = hour > 5.5 && hour < 19;

    return (
      <div ref={wrapRef} className="layer" onMouseMove={onMove}
        style={{
          background: `linear-gradient(165deg, ${pal.bg[0]} 0%, ${pal.bg[1]} 100%)`,
          transition: reduceMotion ? 'none' : 'background 1.4s ease',
          overflow: 'hidden',
        }}>
        {/* Sun / moon */}
        <div style={{
          position: 'absolute', left: `calc(${sunX*100}% - 60px)`, top: `calc(${sunY*100}% - 60px)`,
          width: 120, height: 120, borderRadius: '50%',
          background: isDay
            ? `radial-gradient(circle, ${pal.glow} 0%, ${pal.glow}88 40%, transparent 70%)`
            : `radial-gradient(circle, #f9fafb 0%, #f9fafb88 40%, transparent 70%)`,
          filter: 'blur(2px)',
          transform: `translate(${px*0.5}px, ${py*0.5}px)`,
          transition: reduceMotion ? 'none' : 'left 1s ease, top 1s ease, background 1.4s ease, transform .8s cubic-bezier(.2,.7,.3,1)',
          boxShadow: `0 0 80px ${pal.glow}66`,
        }}/>

        {/* Stars (only show when not bright day) */}
        <div style={{position:'absolute',inset:0, opacity: isDay ? Math.max(0, (5.5 - hour) + (hour - 19)) / 3 : 1, transition: 'opacity 1.4s ease'}}>
          {stars.map((s, i) => (
            <div key={i} style={{
              position: 'absolute', left: `${s.x}%`, top: `${s.y}%`,
              width: s.r, height: s.r, borderRadius: '50%',
              background: 'white', opacity: s.bright,
              transform: `translate(${px*s.depth}px, ${py*s.depth}px)`,
              transition: 'transform .8s cubic-bezier(.2,.7,.3,1)',
            }}/>
          ))}
        </div>

        {/* Drifting orbs — programmes/modules/actions */}
        {[
          { x: 0.2, y: 0.65, label: "12 programmes" },
          { x: 0.7, y: 0.35, label: "47 modules" },
          { x: 0.45, y: 0.55, label: "8 actions" },
        ].map((o, i) => (
          <div key={i} style={{
            position: 'absolute', left: `${o.x*100}%`, top: `${o.y*100}%`,
            width: 8, height: 8, borderRadius: '50%',
            background: pal.accent, boxShadow: `0 0 24px ${pal.accent}`,
            transform: `translate(${px*0.6 + Math.sin(Date.now()/2000+i)*4}px, ${py*0.6 + Math.cos(Date.now()/2000+i)*4}px)`,
            transition: 'transform 1s cubic-bezier(.2,.7,.3,1)',
            animation: reduceMotion ? 'none' : `tod-pulse 4s ease-in-out ${i*0.7}s infinite`,
          }}/>
        ))}

        {/* Time + greeting display (clickable easter egg) */}
        <div onClick={onTimeClick} style={{
          position: 'absolute', left: 56, top: 56, cursor: 'pointer',
          color: 'white', userSelect: 'none',
        }}>
          <div style={{fontSize: 12, fontWeight: 600, letterSpacing: '0.5px', textTransform: 'uppercase', opacity: 0.6, marginBottom: 4}}>
            {greetingFor(Math.floor(hour))}
          </div>
          <div style={{fontSize: 56, fontWeight: 300, letterSpacing: '-0.03em', lineHeight: 1, fontVariantNumeric: 'tabular-nums'}}>
            {virtualHour !== null
              ? `${String(Math.floor(virtualHour)).padStart(2,'0')}:${String(Math.floor((virtualHour%1)*60)).padStart(2,'0')}`
              : fmtTime(now)}
          </div>
          <div style={{fontSize: 13, opacity: 0.5, marginTop: 8}}>
            {now.toLocaleDateString('en-AU', { weekday: 'long', day: 'numeric', month: 'long' })}
          </div>
        </div>

        <style>{`
          @keyframes tod-pulse { 0%,100% { opacity: 0.6; } 50% { opacity: 1; } }
        `}</style>
      </div>
    );
  }

  return Visual;
})();

window.TimeOfDayVisual = TimeOfDayVisual;
