/* =========================================================================
   ScanIQ — animated characters for the Admin password modal
   Adapted from 21st.dev "animated characters login page":
   eyes track the cursor, characters blink, glance at each other when the
   field is focused, and politely look away while the password is visible
   (the red one sneaks a peek).
   ========================================================================= */

function useSceneMouse() {
  const [pos, setPos] = React.useState({ x: 0, y: 0 });
  React.useEffect(() => {
    const onMove = (e) => setPos({ x: e.clientX, y: e.clientY });
    window.addEventListener("mousemove", onMove);
    return () => window.removeEventListener("mousemove", onMove);
  }, []);
  return pos;
}

function useSceneBlink() {
  const [blink, setBlink] = React.useState(false);
  React.useEffect(() => {
    let alive = true, t1, t2;
    const schedule = () => {
      t1 = setTimeout(() => {
        if (!alive) return;
        setBlink(true);
        t2 = setTimeout(() => { if (!alive) return; setBlink(false); schedule(); }, 150);
      }, Math.random() * 4000 + 3000);
    };
    schedule();
    return () => { alive = false; clearTimeout(t1); clearTimeout(t2); };
  }, []);
  return blink;
}

/* Eye with a white ball; lookX/lookY override mouse tracking */
function SceneEyeBall({ size = 12, pupilSize = 5, maxDistance = 4, pupilColor = "#1E2228", blink = false, lookX, lookY, mouse }) {
  const ref = React.useRef(null);
  let x = 0, y = 0;
  if (lookX !== undefined && lookY !== undefined) {
    x = lookX; y = lookY;
  } else if (ref.current) {
    const r = ref.current.getBoundingClientRect();
    const dx = mouse.x - (r.left + r.width / 2);
    const dy = mouse.y - (r.top + r.height / 2);
    const d = Math.min(Math.hypot(dx, dy), maxDistance);
    const a = Math.atan2(dy, dx);
    x = Math.cos(a) * d; y = Math.sin(a) * d;
  }
  return (
    <div ref={ref} style={{
      width: size, height: blink ? 2 : size, backgroundColor: "#FFFFFF",
      borderRadius: 999, overflow: "hidden", flex: "none",
      display: "flex", alignItems: "center", justifyContent: "center",
      transition: "height .15s",
    }}>
      {!blink ? (
        <div style={{
          width: pupilSize, height: pupilSize, borderRadius: 999, backgroundColor: pupilColor,
          transform: "translate(" + x + "px, " + y + "px)", transition: "transform .1s ease-out",
        }}></div>
      ) : null}
    </div>
  );
}

/* Bare pupil (no white) */
function ScenePupil({ size = 8, maxDistance = 4, color = "#1E2228", lookX, lookY, mouse }) {
  const ref = React.useRef(null);
  let x = 0, y = 0;
  if (lookX !== undefined && lookY !== undefined) {
    x = lookX; y = lookY;
  } else if (ref.current) {
    const r = ref.current.getBoundingClientRect();
    const dx = mouse.x - (r.left + r.width / 2);
    const dy = mouse.y - (r.top + r.height / 2);
    const d = Math.min(Math.hypot(dx, dy), maxDistance);
    const a = Math.atan2(dy, dx);
    x = Math.cos(a) * d; y = Math.sin(a) * d;
  }
  return (
    <div ref={ref} style={{
      width: size, height: size, borderRadius: 999, backgroundColor: color, flex: "none",
      transform: "translate(" + x + "px, " + y + "px)", transition: "transform .1s ease-out",
    }}></div>
  );
}

/* Face offset + body lean toward the cursor */
function sceneLean(ref, mouse) {
  if (!ref.current) return { faceX: 0, faceY: 0, skew: 0 };
  const r = ref.current.getBoundingClientRect();
  const dx = mouse.x - (r.left + r.width / 2);
  const dy = mouse.y - (r.top + r.height / 3);
  return {
    faceX: Math.max(-8, Math.min(8, dx / 30)),
    faceY: Math.max(-6, Math.min(6, dy / 40)),
    skew: Math.max(-6, Math.min(6, -dx / 120)),
  };
}

function AdminScene({ password, showPassword, focused }) {
  const mouse = useSceneMouse();
  const redRef = React.useRef(null);
  const inkRef = React.useRef(null);
  const orangeRef = React.useRef(null);
  const amberRef = React.useRef(null);
  const blinkRed = useSceneBlink();
  const blinkInk = useSceneBlink();

  const typingHidden = password.length > 0 && !showPassword;
  const avert = password.length > 0 && showPassword; /* secret on screen — look away! */
  const lean = focused || typingHidden;

  /* brief "glance at each other" when the field gains focus */
  const [glance, setGlance] = React.useState(false);
  React.useEffect(() => {
    if (focused) {
      setGlance(true);
      const t = setTimeout(() => setGlance(false), 800);
      return () => clearTimeout(t);
    }
    setGlance(false);
  }, [focused]);

  /* the red one can't resist peeking while everyone looks away */
  const [peek, setPeek] = React.useState(false);
  React.useEffect(() => {
    if (!avert) { setPeek(false); return; }
    let alive = true, t1, t2;
    const schedule = () => {
      t1 = setTimeout(() => {
        if (!alive) return;
        setPeek(true);
        t2 = setTimeout(() => { if (!alive) return; setPeek(false); schedule(); }, 800);
      }, Math.random() * 2500 + 1500);
    };
    schedule();
    return () => { alive = false; clearTimeout(t1); clearTimeout(t2); };
  }, [avert]);

  const red = sceneLean(redRef, mouse);
  const ink = sceneLean(inkRef, mouse);
  const orange = sceneLean(orangeRef, mouse);
  const amber = sceneLean(amberRef, mouse);

  const charTransition = "transform .7s cubic-bezier(.4,0,.2,1), height .7s cubic-bezier(.4,0,.2,1)";
  const faceTransition = "left .7s cubic-bezier(.4,0,.2,1), top .7s cubic-bezier(.4,0,.2,1)";

  /* shared eye override logic */
  const redLook = avert ? (peek ? { x: 3, y: 4 } : { x: -3, y: -3 }) : glance ? { x: 2, y: 3 } : null;
  const inkLook = avert ? { x: -3, y: -3 } : glance ? { x: 0, y: -3 } : null;
  const frontLook = avert ? { x: -3, y: -3 } : null;

  return (
    <div className="pwscene" aria-hidden="true">
      <div className="pwscene-stage">
        {/* Red tall — back layer */}
        <div ref={redRef} style={{
          position: "absolute", bottom: 0, left: 38, width: 100, zIndex: 1,
          height: lean ? 238 : 218, backgroundColor: "var(--red)", borderRadius: "7px 7px 0 0",
          transform: avert ? "skewX(0deg)" : lean ? "skewX(" + (red.skew - 10) + "deg) translateX(22px)" : "skewX(" + red.skew + "deg)",
          transformOrigin: "bottom center", transition: charTransition,
        }}>
          <div style={{
            position: "absolute", display: "flex", gap: 17, transition: faceTransition,
            left: avert ? 11 : glance ? 30 : 25 + red.faceX,
            top: avert ? 19 : glance ? 35 : 22 + red.faceY,
          }}>
            <SceneEyeBall size={12} pupilSize={5} blink={blinkRed} mouse={mouse} lookX={redLook ? redLook.x : undefined} lookY={redLook ? redLook.y : undefined} />
            <SceneEyeBall size={12} pupilSize={5} blink={blinkRed} mouse={mouse} lookX={redLook ? redLook.x : undefined} lookY={redLook ? redLook.y : undefined} />
          </div>
        </div>

        {/* Ink tall — middle layer */}
        <div ref={inkRef} style={{
          position: "absolute", bottom: 0, left: 132, width: 66, height: 170, zIndex: 2,
          backgroundColor: "#1E2228", borderRadius: "6px 6px 0 0",
          transform: avert ? "skewX(0deg)" : glance ? "skewX(" + (ink.skew * 1.5 + 8) + "deg) translateX(11px)" : "skewX(" + ink.skew + "deg)",
          transformOrigin: "bottom center", transition: charTransition,
        }}>
          <div style={{
            position: "absolute", display: "flex", gap: 13, transition: faceTransition,
            left: avert ? 6 : glance ? 18 : 14 + ink.faceX,
            top: avert ? 15 : glance ? 7 : 18 + ink.faceY,
          }}>
            <SceneEyeBall size={11} pupilSize={4} blink={blinkInk} mouse={mouse} lookX={inkLook ? inkLook.x : undefined} lookY={inkLook ? inkLook.y : undefined} />
            <SceneEyeBall size={11} pupilSize={4} blink={blinkInk} mouse={mouse} lookX={inkLook ? inkLook.x : undefined} lookY={inkLook ? inkLook.y : undefined} />
          </div>
        </div>

        {/* Orange semicircle — front left */}
        <div ref={orangeRef} style={{
          position: "absolute", bottom: 0, left: 0, width: 132, height: 110, zIndex: 3,
          backgroundColor: "#FF9B6B", borderRadius: "66px 66px 0 0",
          transform: avert ? "skewX(0deg)" : "skewX(" + orange.skew + "deg)",
          transformOrigin: "bottom center", transition: charTransition,
        }}>
          <div style={{
            position: "absolute", display: "flex", gap: 18, transition: faceTransition,
            left: avert ? 28 : 45 + orange.faceX,
            top: avert ? 46 : 50 + orange.faceY,
          }}>
            <ScenePupil size={8} mouse={mouse} lookX={frontLook ? frontLook.x : undefined} lookY={frontLook ? frontLook.y : undefined} />
            <ScenePupil size={8} mouse={mouse} lookX={frontLook ? frontLook.x : undefined} lookY={frontLook ? frontLook.y : undefined} />
          </div>
        </div>

        {/* Amber rounded — front right */}
        <div ref={amberRef} style={{
          position: "absolute", bottom: 0, left: 170, width: 77, height: 126, zIndex: 4,
          backgroundColor: "#F2C94C", borderRadius: "38px 38px 0 0",
          transform: avert ? "skewX(0deg)" : "skewX(" + amber.skew + "deg)",
          transformOrigin: "bottom center", transition: charTransition,
        }}>
          <div style={{
            position: "absolute", display: "flex", gap: 13, transition: faceTransition,
            left: avert ? 12 : 28 + amber.faceX,
            top: avert ? 19 : 22 + amber.faceY,
          }}>
            <ScenePupil size={8} mouse={mouse} lookX={frontLook ? frontLook.x : undefined} lookY={frontLook ? frontLook.y : undefined} />
            <ScenePupil size={8} mouse={mouse} lookX={frontLook ? frontLook.x : undefined} lookY={frontLook ? frontLook.y : undefined} />
          </div>
          <div style={{
            position: "absolute", width: 42, height: 3, borderRadius: 999, backgroundColor: "#1E2228", transition: faceTransition,
            left: avert ? 6 : 22 + amber.faceX,
            top: avert ? 48 : 48 + amber.faceY,
          }}></div>
        </div>
      </div>
    </div>
  );
}

function PwEyeIcon({ off = false, size = 18 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z"></path>
      <circle cx="12" cy="12" r="3"></circle>
      {off ? <path d="M4 4 20 20"></path> : null}
    </svg>
  );
}

Object.assign(window, { AdminScene, PwEyeIcon });
