// AGENT_TARGET: gravity-drop-game — Gravity Drop mini-game, physics-accurate fall speed per planet

const GRAVITY_DROP_OBJECTS = ["🚀", "🪨", "🍎", "⚽", "🌊", "🎾"];
const EARTH_DROP_MS = 1400; // time to fall ~10 m on Earth

// AGENT_TARGET: gravity-drop-game — GravityDropGame main component
function GravityDropGame({ planet, gravityRatio }) {
  const ratio = gravityRatio != null && gravityRatio > 0 ? gravityRatio : 1;
  // h = 0.5*g*t^2 → same height means t ∝ 1/sqrt(g)
  const duration = EARTH_DROP_MS / Math.sqrt(ratio);

  const [isDropping, setIsDropping] = useState(false);
  const [dropProgress, setDropProgress] = useState(0); // 0 → 1
  const [landed, setLanded] = useState(false);
  const [objectIdx, setObjectIdx] = useState(0);
  const [guess, setGuess] = useState(null);
  const animRef = useRef(null);
  const startRef = useRef(null);

  // AGENT_TARGET: gravity-drop-game — drop animation loop using rAF + quadratic easing
  function startDrop() {
    if (isDropping) return;
    if (!guess) {
      if (typeof playKidSound === "function") playKidSound("boop");
      return;
    }
    if (animRef.current) cancelAnimationFrame(animRef.current);
    setIsDropping(true);
    setLanded(false);
    setDropProgress(0);
    startRef.current = performance.now();

    function tick(now) {
      const elapsed = now - startRef.current;
      const t = Math.min(elapsed / duration, 1);
      setDropProgress(t * t); // quadratic: models h = 0.5·g·t²
      if (t < 1) {
        animRef.current = requestAnimationFrame(tick);
      } else {
        setIsDropping(false);
        setLanded(true);
      }
    }
    animRef.current = requestAnimationFrame(tick);
  }

  function resetDrop() {
    if (animRef.current) cancelAnimationFrame(animRef.current);
    setIsDropping(false);
    setLanded(false);
    setDropProgress(0);
  }

  useEffect(() => {
    return () => {
      if (animRef.current) cancelAnimationFrame(animRef.current);
    };
  }, []);

  const obj = GRAVITY_DROP_OBJECTS[objectIdx % GRAVITY_DROP_OBJECTS.length];
  const earthMs = Math.round(EARTH_DROP_MS);
  const planetMs = Math.round(duration);
  const compareMaxMs = Math.max(earthMs, planetMs);
  const earthBar = (earthMs / compareMaxMs) * 100;
  const planetBar = (planetMs / compareMaxMs) * 100;
  const speedLabel =
    planetMs < earthMs - 50
      ? `${(earthMs / planetMs).toFixed(1)}× faster than Earth!`
      : planetMs > earthMs + 50
        ? `${(planetMs / earthMs).toFixed(1)}× slower than Earth`
        : "Same speed as Earth!";
  const answer = ratio < 0.9 ? "slower" : ratio > 1.1 ? "faster" : "same";
  const guessText =
    landed && guess
      ? guess === answer
        ? "Cosmic guess!"
        : `It was ${answer}. Try another object!`
      : "";

  const factText =
    ratio < 0.3
      ? "So little gravity — you'd float away in one jump!"
      : ratio < 0.8
        ? "Things drift down softly and slowly here."
        : ratio < 1.2
          ? "Falls just like home on Earth."
          : ratio < 3
            ? "Everything crashes down much faster here."
            : "Crushing gravity — things fall super fast!";

  return (
    <div
      className="gravity-drop-card"
      style={{ "--planet-color": planet.color }}
    >
      <div className="gravity-drop-label">GRAVITY DROP</div>
      <div className="gravity-guess-row" aria-label="Gravity guess">
        {[
          { id: "slower", icon: "🪶", label: "Slower" },
          { id: "same", icon: "🌍", label: "Same" },
          { id: "faster", icon: "⚡", label: "Faster" },
        ].map((option) => (
          <button
            key={option.id}
            className={guess === option.id ? "selected" : ""}
            onClick={() => {
              resetDrop();
              setGuess(option.id);
              if (typeof playKidSound === "function") playKidSound("pop");
            }}
            aria-pressed={guess === option.id}
          >
            <span>{option.icon}</span>
            {option.label}
          </button>
        ))}
      </div>
      <div
        className={`gravity-drop-arena${guess ? "" : " waiting-guess"}`}
        role="button"
        tabIndex={0}
        aria-label={
          !guess ? "Pick faster slower or same first" : isDropping ? "Dropping…" : "Tap to drop!"
        }
        onClick={!isDropping ? startDrop : undefined}
        onKeyDown={(e) => {
          if (!isDropping && (e.key === "Enter" || e.key === " ")) startDrop();
        }}
      >
        <div
          className={`gravity-drop-object${landed ? " landed" : ""}`}
          style={{ top: `${dropProgress * 82}%` }}
        >
          {obj}
        </div>
        <div className={`gravity-drop-floor${landed ? " lit" : ""}`} />
        {!isDropping && !landed && (
          <div className="gravity-drop-prompt">
            {guess ? "Tap to drop!" : "Guess first"}
          </div>
        )}
        {landed && <div className="gravity-drop-speed">{speedLabel}</div>}
      </div>
      {landed ? (
        <div className="gravity-drop-time-bars" aria-label="Fall time comparison">
          <span>
            <strong>Earth</strong>
            <i>
              <b style={{ width: `${earthBar}%` }} />
            </i>
            <small>{earthMs} ms</small>
          </span>
          <span>
            <strong>{planet.name}</strong>
            <i>
              <b style={{ width: `${planetBar}%` }} />
            </i>
            <small>{planetMs} ms</small>
          </span>
        </div>
      ) : null}
      <div className="gravity-drop-controls">
        <button
          className="gravity-drop-btn"
          onClick={() => {
            resetDrop();
            setGuess(null);
            setObjectIdx((i) => i + 1);
          }}
        >
          Change object
        </button>
        {landed && (
          <button className="gravity-drop-btn primary" onClick={startDrop}>
            Drop again
          </button>
        )}
      </div>
      {guessText ? <div className="gravity-guess-result">{guessText}</div> : null}
      <div className="gravity-drop-fact">{factText}</div>
    </div>
  );
}
