/* CatStage — 小猫舞台:逐帧动画 + 呼吸缓动 + 点摸反应 + 碎碎念气泡 + 盖章 + 爱心 */
const { useState, useEffect, useRef, useCallback } = React;

function CatStage({ action, bubble, stamp, onPet, scale = 1 }) {
  const PET = window.PET;
  const cfg = PET.ACTIONS[action] || PET.ACTIONS.talk;

  const imgRef = useRef(null);
  const breatheRef = useRef(null);
  const frameRef = useRef(0);
  const timerRef = useRef(0);
  const fidgetRef = useRef(0);
  const [hearts, setHearts] = useState([]);
  const [stampShow, setStampShow] = useState(null);

  // 预加载所有动作
  useEffect(() => {
    Object.keys(PET.ACTIONS).forEach((a) => {
      const c = PET.ACTIONS[a];
      for (let i = 0; i < c.frames; i++) {
        const im = new Image();
        im.src = PET.framePath(a, i);
      }
    });
  }, []);

  const draw = useCallback(
    (idx) => {
      const img = imgRef.current;
      if (!img) return;
      img.classList.remove("is-visible");
      img.src = PET.framePath(action, idx);
      requestAnimationFrame(() => img.classList.add("is-visible"));
    },
    [action],
  );

  // 动作切换 + 逐帧循环(非匀速)
  useEffect(() => {
    frameRef.current = 0;
    clearTimeout(timerRef.current);
    draw(0);

    // arrive 落地小弹
    const br = breatheRef.current;
    if (br) {
      br.classList.remove("is-arrive");
      void br.offsetWidth;
      br.classList.add("is-arrive");
    }

    const tick = () => {
      const dur =
        cfg.durations[frameRef.current] ?? cfg.durations.at(-1) ?? 200;
      timerRef.current = setTimeout(() => {
        frameRef.current = (frameRef.current + 1) % cfg.frames;
        draw(frameRef.current);
        tick();
      }, dur);
    };
    tick();
    return () => clearTimeout(timerRef.current);
  }, [action, cfg, draw]);

  // 闲时小动作(fidget):随机轻轻一跳,让待机不僵硬
  useEffect(() => {
    function schedule() {
      const wait = 6000 + Math.random() * 7000;
      fidgetRef.current = setTimeout(() => {
        const br = breatheRef.current;
        if (
          br &&
          (action === "talk" || action === "work" || action === "cute")
        ) {
          br.classList.remove("is-fidget");
          void br.offsetWidth;
          br.classList.add("is-fidget");
          setTimeout(() => br && br.classList.remove("is-fidget"), 650);
        }
        schedule();
      }, wait);
    }
    schedule();
    return () => clearTimeout(fidgetRef.current);
  }, [action]);

  // 盖章
  useEffect(() => {
    if (!stamp || !stamp.key) return;
    const src = PET.STICKERS[stamp.key];
    if (!src) return;
    setStampShow({ src, id: stamp.nonce });
    const t = setTimeout(() => setStampShow(null), 1500);
    return () => clearTimeout(t);
  }, [stamp]);

  // 点摸:蹭一下 + 爱心 + 回调
  const pet = useCallback(
    (e) => {
      const br = breatheRef.current;
      if (br) {
        br.classList.remove("is-pet");
        void br.offsetWidth;
        br.classList.add("is-pet");
        setTimeout(() => br && br.classList.remove("is-pet"), 520);
      }
      const burst = Array.from(
        { length: 3 + Math.floor(Math.random() * 2) },
        (_, i) => ({
          id: Date.now() + "-" + i,
          x: 40 + Math.random() * 20,
          d: Math.random() * 160,
        }),
      );
      setHearts((h) => [...h, ...burst]);
      burst.forEach((b) =>
        setTimeout(
          () => setHearts((h) => h.filter((x) => x.id !== b.id)),
          1200 + b.d,
        ),
      );
      if (onPet) onPet();
    },
    [onPet],
  );

  return (
    <div
      className="cat-area"
      onClick={pet}
      role="button"
      aria-label="摸摸小猫"
      style={{ "--cat-scale": scale }}
    >
      <div className="cat-shadow"></div>
      <div className="cat-breathe" ref={breatheRef}>
        <div
          className="cat-scale"
          style={{ transform: `scale(${scale})`, transformOrigin: "50% 100%" }}
        >
          <img
            ref={imgRef}
            className="cat-frame is-visible"
            alt={`社畜小猫${cfg.label}`}
          />
        </div>
      </div>

      <div className="bubble-layer">
        {bubble && bubble.text ? (
          <div className="speech" key={bubble.nonce}>
            {bubble.text}
          </div>
        ) : null}
      </div>

      <div className="stamp-layer">
        {stampShow ? (
          <div
            className="stamp"
            key={stampShow.id}
            style={{ backgroundImage: `url(${stampShow.src})` }}
          ></div>
        ) : null}
      </div>

      <div className="heart-layer">
        {hearts.map((h) => (
          <span
            key={h.id}
            className="heart"
            style={{ left: h.x + "%", animationDelay: h.d + "ms" }}
          >
            ♥
          </span>
        ))}
      </div>
    </div>
  );
}

window.CatStage = CatStage;
