"use client";

import React, { useEffect, useRef, useState } from "react";
import dynamic from "next/dynamic";

/* ============================================================
   WorkflowScene — compact, self-driven mount of the PRODUCTION
   Three.js scenes (OptimizationCanvas / LogisticsBrainCanvas).

   These are the EXACT same scene components used by the full
   OptimizationSection / LogisticsBrainSection experiences — same
   shaders, assets, particles, camera rig and animation system.
   The only difference here is how `progress` is driven: instead
   of a multi-viewport pinned scroll (which made the workflows
   extremely tall), the scene idles in its "settled" narrative
   band with a gentle autonomous oscillation so it stays alive
   inside the split-screen media panel.

   Exactly ONE canvas instance is created per workflow — no
   duplicate scenes, no duplicate render loops. The render loop
   is paused (frameloop="never") whenever the panel is off-screen.
   ============================================================ */

// Client-only, code-split so the heavy 3D bundle never blocks first paint.
const OptimizationCanvas = dynamic(() => import("../optimization/OptimizationCanvas"), { ssr: false });
const LogisticsBrainCanvas = dynamic(() => import("../logisticsbrain/LogisticsBrainCanvas"), { ssr: false });

type Variant = "optimization" | "logistics";

/** Per-scene background (matches each Canvas's own <color attach="background">)
 *  so there is no flash before the WebGL context paints. */
const SCENE_BG: Record<Variant, string> = {
  optimization: "#020617",
  logistics: "#08080c",
};

/** Settled narrative band each scene idles within. The optimization scene reads
 *  best inside its post-optimize band (mirrors the production mobile idle); the
 *  logistics scene around its score/network phase where city + routes + brain
 *  are all alive. Held at a single static value under reduced-motion. */
const IDLE: Record<Variant, { center: number; amp: number; speed: number; still: number }> = {
  optimization: { center: 0.78, amp: 0.14, speed: 0.5, still: 0.85 },
  logistics: { center: 0.5, amp: 0.13, speed: 0.4, still: 0.52 },
};

export default function WorkflowScene({
  variant,
  ariaLabel,
}: {
  variant: Variant;
  ariaLabel?: string;
}) {
  const wrapRef = useRef<HTMLDivElement>(null);
  const progressRef = useRef(IDLE[variant].still);

  const [mountScene, setMountScene] = useState(false);
  const [sceneActive, setSceneActive] = useState(false);
  const [isMobile, setIsMobile] = useState(false);
  const [isTablet, setIsTablet] = useState(false);
  const [reduced, setReduced] = useState(false);

  // Responsive + reduced-motion flags (same breakpoints as the production sections).
  useEffect(() => {
    const mqMobile = window.matchMedia("(max-width: 767px)");
    const mqTablet = window.matchMedia("(min-width: 768px) and (max-width: 1024px)");
    const mqReduce = window.matchMedia("(prefers-reduced-motion: reduce)");
    const sync = () => {
      setIsMobile(mqMobile.matches);
      setIsTablet(mqTablet.matches);
      setReduced(mqReduce.matches);
    };
    sync();
    mqMobile.addEventListener("change", sync);
    mqTablet.addEventListener("change", sync);
    mqReduce.addEventListener("change", sync);
    return () => {
      mqMobile.removeEventListener("change", sync);
      mqTablet.removeEventListener("change", sync);
      mqReduce.removeEventListener("change", sync);
    };
  }, []);

  // Mount the heavy scene a little before it enters; keep the render loop gated
  // to actual visibility so it never burns frames off-screen.
  useEffect(() => {
    const el = wrapRef.current;
    if (!el) return;
    const mountIo = new IntersectionObserver(
      (entries) => {
        if (entries.some((e) => e.isIntersecting)) {
          setMountScene(true);
          setSceneActive(true);
          mountIo.disconnect();
        }
      },
      { rootMargin: "60% 0px" },
    );
    const activeIo = new IntersectionObserver(
      (entries) => setSceneActive(entries.some((e) => e.isIntersecting)),
      { rootMargin: "10% 0px" },
    );
    mountIo.observe(el);
    activeIo.observe(el);
    return () => {
      mountIo.disconnect();
      activeIo.disconnect();
    };
  }, []);

  // Drive `progress` autonomously: a slow sine within the settled band keeps the
  // hologram breathing. Runs only while visible; held static under reduced-motion.
  useEffect(() => {
    const cfg = IDLE[variant];
    if (reduced) {
      progressRef.current = cfg.still;
      return;
    }
    if (!sceneActive) return;
    let raf = 0;
    const tick = () => {
      const t = performance.now() / 1000;
      progressRef.current = cfg.center + Math.sin(t * cfg.speed) * cfg.amp;
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [variant, reduced, sceneActive]);

  return (
    <div
      ref={wrapRef}
      className="wf-scene"
      role="img"
      aria-label={ariaLabel ?? "DoorMile 3D logistics scene"}
      style={{ background: SCENE_BG[variant] }}
    >
      <style dangerouslySetInnerHTML={{ __html: `
        .wf-scene {
          position: relative;
          width: 100%;
          /* Compact, fixed-ratio media panel — replaces the multi-viewport pinned
             scroll experience so the workflow is dramatically shorter. */
          aspect-ratio: 4 / 3;
          border-radius: 16px;
          overflow: hidden;
        }
        .wf-scene__canvas { position: absolute; inset: 0; }
        .wf-scene__canvas canvas { display: block; width: 100% !important; height: 100% !important; }
        @media (max-width: 991px) {
          .wf-scene { aspect-ratio: 16 / 10; }
        }
        /* Phones: shorter scene panel (~17% less tall than the old 4/3) so the
           card + KPI bar are reached sooner. The closer mobile camera framing
           keeps the depot/routes/vehicles readable in the reduced height. */
        @media (max-width: 480px) {
          .wf-scene { aspect-ratio: 16 / 10; }
        }
      `}} />
      <div className="wf-scene__canvas">
        {mountScene &&
          (variant === "optimization" ? (
            <OptimizationCanvas
              progress={progressRef}
              reduced={reduced}
              isMobile={isMobile}
              isTablet={isTablet}
              active={sceneActive}
            />
          ) : (
            <LogisticsBrainCanvas
              progress={progressRef}
              reduced={reduced}
              isMobile={isMobile}
              active={sceneActive}
            />
          ))}
      </div>
    </div>
  );
}
