// CheekPouch character — uses the actual illustrated reference (6 frames
// cropped from the source sheet: 0 / 10 / 30 / 50 / 70 / 100 %).
//
// API
//   <CheekPouch count={n} max={10} accent="#…" size={96}
//               animateOnChange={true} headOnly={false} />
//
// `accent`, `face` and `mood` are still accepted so existing call sites
// keep working, but in this version the artwork is the same for everyone —
// mascot picking arrives in a later release.

// 6 reference frames cropped + alpha-knocked-out from the source illustration.
// All 6 are 340 × 230 px, anchored at bottom-center (so paws/seed stay put
// across frames while cheeks bulge outward).
const _CP_FRAMES = [
  { upTo: 0.05, src: 'assets/hamster-h0.png',   label: 0   },
  { upTo: 0.20, src: 'assets/hamster-h10.png',  label: 10  },
  { upTo: 0.40, src: 'assets/hamster-h30.png',  label: 30  },
  { upTo: 0.60, src: 'assets/hamster-h50.png',  label: 50  },
  { upTo: 0.85, src: 'assets/hamster-h70.png',  label: 70  },
  { upTo: 1.01, src: 'assets/hamster-h100.png', label: 100 },
];
const _CP_W = 340;
const _CP_H = 230;
const _CP_ASPECT = _CP_H / _CP_W; // ≈ 0.676

// Head occupies roughly the top portion of the canvas (ears down to chin).
// (used by headOnly to position the face at the avatar's center)

// Preload all 6 once per page so frame swaps are instant.
let _CP_PRELOADED = false;
function _cpPreload() {
  if (_CP_PRELOADED) return;
  _CP_PRELOADED = true;
  _CP_FRAMES.forEach(f => { const i = new Image(); i.src = f.src; });
}

function _cpPickFrame(fill) {
  for (const f of _CP_FRAMES) if (fill <= f.upTo) return f;
  return _CP_FRAMES[_CP_FRAMES.length - 1];
}

function CheekPouch({
  count = 0,
  max = 10,
  // eslint-disable-next-line no-unused-vars
  accent = '#C19A6B',
  size = 96,
  animateOnChange = true,
  headOnly = false,
  // accepted but unused — one character only in this version
  // eslint-disable-next-line no-unused-vars
  face = 'basic',
  // eslint-disable-next-line no-unused-vars
  mood = 'happy',
}) {
  const prevCount = React.useRef(count);
  const wrapRef = React.useRef(null);

  React.useEffect(() => { _cpPreload(); }, []);

  React.useEffect(() => {
    if (!animateOnChange) return;
    if (count > prevCount.current && wrapRef.current) {
      wrapRef.current.style.animation = 'none';
      void wrapRef.current.offsetWidth;
      wrapRef.current.style.animation = 'cp-puff 0.55s cubic-bezier(0.34, 1.56, 0.64, 1)';
    }
    prevCount.current = count;
  }, [count, animateOnChange]);

  const fill = Math.min(Math.max(count / Math.max(1, max), 0), 1);
  const frame = _cpPickFrame(fill);

  // `size` is the rendered width (preserves the old API).
  const W = size;
  const H = Math.round(size * _CP_ASPECT);

  // headOnly produces a square crop centered on the face (ears + cheeks
  // visible, body/paws/seed clipped). Used by HamsterAvatar.
  if (headOnly) {
    // Render the source image at 1.45× the avatar size, then position it
    // so the face (≈ 30% from the image top) lands at the container's
    // vertical center.
    const imgW = Math.round(size * 1.45);
    const imgH = Math.round(imgW * _CP_ASPECT);
    const FACE_Y = 0.30;                           // face center, in image coords
    const top = Math.round(size / 2 - FACE_Y * imgH);
    return (
      <div ref={wrapRef} style={{
        position: 'relative',
        display: 'inline-block',
        width: size, height: size,
        overflow: 'hidden',
        borderRadius: '50%',
        transformOrigin: 'center bottom',
        lineHeight: 0,
      }}>
        <img src={frame.src} alt="" draggable={false}
             style={{
               position: 'absolute',
               width: imgW, height: imgH,
               left: '50%',
               top: top,
               transform: 'translateX(-50%)',
               userSelect: 'none', pointerEvents: 'none',
             }} />
      </div>
    );
  }

  return (
    <div ref={wrapRef} style={{
      display: 'inline-block',
      width: W, height: H,
      transformOrigin: 'center bottom',
      lineHeight: 0,
    }}>
      <img src={frame.src} alt="" draggable={false}
           style={{
             width: W, height: H,
             display: 'block',
             userSelect: 'none', pointerEvents: 'none',
           }} />
    </div>
  );
}

// Small inline indicator — head only, no animation
function CheekDot({ count = 0, max = 10, accent = '#C19A6B', size = 28 }) {
  return <CheekPouch count={count} max={max} accent={accent} size={size}
                     animateOnChange={false} headOnly={true} />;
}

// Big animated breathing pouch — for the processing screen.
// Cycles through frame levels to feel actively "puffing".
function CheekPouchAnimated({ accent = '#C19A6B', size = 200 }) {
  const [phase, setPhase] = React.useState(0);
  React.useEffect(() => {
    const t = setInterval(() => setPhase(p => (p + 1) % 4), 620);
    return () => clearInterval(t);
  }, []);
  const counts = [3, 6, 9, 6];
  return (
    <div style={{ display: 'inline-block', animation: 'cp-breathe 1.6s ease-in-out infinite' }}>
      <CheekPouch count={counts[phase]} max={10} accent={accent}
                  size={size} animateOnChange={false} />
    </div>
  );
}

Object.assign(window, { CheekPouch, CheekDot, CheekPouchAnimated });
