// quiz-engine-match.jsx
// Engine Match level: pair the rocket part with its function. Self-contained.

const ENGINE_MATCH_ROUNDS = [
  {
    prompt: "What holds the fuel?",
    fact: "Fuel tanks carry the stuff rockets burn.",
    answer: "fuelTank",
    choices: ["fuelTank", "window", "badge"],
  },
  {
    prompt: "What lights the fuel?",
    fact: "An igniter starts the engine burn.",
    answer: "igniter",
    choices: ["antenna", "igniter", "fins"],
  },
  {
    prompt: "What pushes fire down?",
    fact: "The engine bell sends hot gas down so the rocket goes up.",
    answer: "engine",
    choices: ["engine", "nose", "fuelPipes"],
  },
];

const ENGINE_MATCH_ASSET_VERSION = "engine-match-sprites-20260512";

const ENGINE_MATCH_ASSETS = {
  rocket: `data/generated-assets/engine-match/engine-match-rocket.png?v=${ENGINE_MATCH_ASSET_VERSION}`,
  fuelTank:
    `data/generated-assets/engine-match/engine-match-fuelTank.png?v=${ENGINE_MATCH_ASSET_VERSION}`,
  window:
    `data/generated-assets/engine-match/engine-match-window.png?v=${ENGINE_MATCH_ASSET_VERSION}`,
  badge:
    `data/generated-assets/engine-match/engine-match-badge.png?v=${ENGINE_MATCH_ASSET_VERSION}`,
  antenna:
    `data/generated-assets/engine-match/engine-match-antenna.png?v=${ENGINE_MATCH_ASSET_VERSION}`,
  igniter:
    `data/generated-assets/engine-match/engine-match-igniter.png?v=${ENGINE_MATCH_ASSET_VERSION}`,
  fins: `data/generated-assets/engine-match/engine-match-fins.png?v=${ENGINE_MATCH_ASSET_VERSION}`,
  engine:
    `data/generated-assets/engine-match/engine-match-engine.png?v=${ENGINE_MATCH_ASSET_VERSION}`,
  nose: `data/generated-assets/engine-match/engine-match-nose.png?v=${ENGINE_MATCH_ASSET_VERSION}`,
  fuelPipes:
    `data/generated-assets/engine-match/engine-match-fuelPipes.png?v=${ENGINE_MATCH_ASSET_VERSION}`,
};

const ENGINE_MATCH_GUIDE_LINES = {
  start: {
    clip: "game_engine_match_start.mp3",
    text:
      "Look at the clue, then pick the rocket part that does that job.",
  },
  fuelTank: {
    clip: "game_engine_match_fuel_tank.mp3",
    text:
      "The fuel tank stores rocket fuel. When you match it, it joins the rocket body.",
  },
  igniter: {
    clip: "game_engine_match_igniter.mp3",
    text:
      "The igniter makes the first spark. It lights the fuel so the engine can burn.",
  },
  engine: {
    clip: "game_engine_match_engine.mp3",
    text:
      "The engine pushes hot gas downward. That push sends the rocket upward.",
  },
  done: {
    clip: "game_engine_match_done.mp3",
    text:
      "Engine ready. Fuel, spark, and engine worked together to launch the rocket.",
  },
};

const ENGINE_MATCH_FORCE_STEPS = [
  { id: "fuelTank", icon: "⛽", label: "Fuel waits" },
  { id: "igniter", icon: "✨", label: "Spark lights" },
  { id: "engine", icon: "🔥", label: "Gas pushes down" },
  { id: "done", icon: "🚀", label: "Rocket goes up" },
];

function EngineMatchLevel({ onExit }) {
  const partsById = React.useMemo(
    () =>
      Object.fromEntries(
        ROCKET_PARTS.map((part) => [
          part.id,
          {
            ...part,
            asset: ENGINE_MATCH_ASSETS[part.id] || part.asset,
          },
        ]),
      ),
    [],
  );
  const [roundIndex, setRoundIndex] = useState(0);
  const [message, setMessage] = useState("Tap the glowing rocket part.");
  const [pickedId, setPickedId] = useState(null);
  const [installedParts, setInstalledParts] = useState([]);
  const [needsHint, setNeedsHint] = useState(false);
  const [done, setDone] = useState(false);
  const [choiceIndex, setChoiceIndex] = useState(0);
  const feedbackTimerRef = useRef(null);
  const round = ENGINE_MATCH_ROUNDS[roundIndex];
  const choices = resolveChoiceItems(round.choices, (id) => partsById[id]);
  const answerPart = partsById[round.answer];
  const activeGuide = done
    ? ENGINE_MATCH_GUIDE_LINES.done
    : ENGINE_MATCH_GUIDE_LINES[round.answer] || ENGINE_MATCH_GUIDE_LINES.start;
  const selectedChoice = choiceSelectionState(
    choiceIndex,
    choices,
    (part) => part.label,
  );

  useEffect(() => {
    return () => clearChoiceFeedbackTimer(feedbackTimerRef);
  }, []);
  useEffect(() => {
    setChoiceIndex(0);
  }, [roundIndex]);
  useEffect(() => {
    setChoiceIndex((index) => clampChoiceIndex(index, choices.length));
  }, [choices.length]);

  const speakGuide = (guide = activeGuide) => {
    if (!guide) return;
    const narration = window.__narration;
    if (narration && typeof narration.play === "function") {
      narration.play(guide.clip);
    }
  };

  const choose = (part) => {
    if (!part) return;
    if (done) return;
    clearChoiceFeedbackTimer(feedbackTimerRef);
    setPickedId(part.id);
    if (part.id !== round.answer) {
      setNeedsHint(true);
      setMessage(
        answerPart
          ? `Good try. Tap ${answerPart.label} for this clue.`
          : `${part.label} is useful. Try another part.`,
      );
      playKidSound("pop");
      feedbackTimerRef.current = window.setTimeout(() => setPickedId(null), 900);
      return;
    }
    playKidSound("chime");
    setInstalledParts((parts) =>
      parts.includes(part.id) ? parts : [...parts, part.id],
    );
    setNeedsHint(false);
    setMessage(`${part.label}! ${round.fact}`);
    speakGuide(ENGINE_MATCH_GUIDE_LINES[part.id]);
    if (roundIndex >= ENGINE_MATCH_ROUNDS.length - 1) {
      setDone(true);
      window.SpaceExplorerFoundation?.celebrateGameFinish?.({
        gameId: "engine-match",
        emoji: "🔥",
        title: "Engine ready!",
        message: "Fuel, spark, and engine worked together.",
      });
      window.setTimeout(() => speakGuide(ENGINE_MATCH_GUIDE_LINES.done), 260);
      return;
    }
    feedbackTimerRef.current = window.setTimeout(() => {
      setRoundIndex((i) => i + 1);
      setPickedId(null);
      setNeedsHint(false);
      setMessage("Good match! Try the next clue.");
    }, 950);
  };

  const reset = () => {
    clearChoiceFeedbackTimer(feedbackTimerRef);
    setRoundIndex(0);
    setDone(false);
    setPickedId(null);
    setInstalledParts([]);
    setNeedsHint(false);
    setMessage("Tap the glowing rocket part.");
  };

  useWindowKeyHandler(
    (event) => {
      handleChoiceNavigationKey(event, {
        choices,
        selectedChoice,
        disabled: done,
        onMove: (delta) =>
          setChoiceIndex((index) => nextChoiceIndex(index, delta, choices.length)),
        onChoose: choose,
      });
    },
    !done,
  );

  return (
    <section
      className="engine-match-level engine-match-art-v2"
      aria-label="Rocket engine matching game"
    >
      <Starfield count={220} />
      <button className="planet-sort-back" onClick={onExit}>
        ← Back to planets
      </button>
      <div className="engine-match-shell">
        <div className="engine-match-rocket" aria-hidden="true">
          <SafeAssetImage
            className="engine-match-hero-rocket"
            src={ENGINE_MATCH_ASSETS.rocket}
            alt=""
            context="EngineMatch:rocket"
            fallbackText=""
          />
          {installedParts.map((partId) => {
            const part = partsById[partId];
            if (!part) return null;
            return (
              <SafeAssetImage
                key={partId}
                className={`engine-match-installed-part installed-${partId}`}
                src={part.asset}
                alt=""
                context={`EngineMatch:installed:${partId}`}
                fallbackText=""
              />
            );
          })}
        </div>
        <div className="engine-match-panel">
          <span>Engine Match</span>
          <h1>{done ? "Engine ready!" : round.prompt}</h1>
          <p>Rockets work as a team. The helper glow shows the next part.</p>
          <button
            className="engine-match-guide-button"
            type="button"
            aria-label="Hear engine helper"
            onClick={() => speakGuide()}
          >
            <span aria-hidden="true">❓</span>
          </button>
          <div className={`engine-match-message ${done ? "done" : ""}`} role="status">
            <strong>{message}</strong>
          </div>
          <div className="engine-match-force-chain" aria-label="Rocket force chain">
            {ENGINE_MATCH_FORCE_STEPS.map((step) => {
              const active =
                step.id === "done" ? done : installedParts.includes(step.id);
              return (
                <span key={step.id} className={active ? "on" : ""}>
                  <b aria-hidden="true">{step.icon}</b>
                  <strong>{step.label}</strong>
                </span>
              );
            })}
          </div>
          <div className="engine-match-progress" aria-label="Matches">
            {ENGINE_MATCH_ROUNDS.map((item, index) => (
              <span
                key={item.answer}
                className={
                  done ||
                  index < roundIndex ||
                  (index === roundIndex && pickedId === round.answer)
                    ? "on"
                    : ""
                }
              />
            ))}
          </div>
          {done ? (
            <div className="planet-sort-actions">
              <button onClick={reset}>Play again</button>
              <button onClick={onExit}>Done</button>
            </div>
          ) : (
            <div className="engine-match-choices">
              <span className="game-keyboard-status" aria-live="polite">
                {selectedChoice.statusText}
              </span>
              {choices.map((part, index) => (
                <button
                  key={part.id}
                  className={
                    (selectedChoice.index === index ? "selected " : "") +
                    (pickedId === part.id
                      ? part.id === round.answer
                        ? "correct"
                        : "wrong"
                      : needsHint && part.id === round.answer
                        ? "needs-hint"
                        : !pickedId && part.id === round.answer
                          ? "needs-hint"
                        : "")
                  }
                  onClick={() => choose(part)}
                  onFocus={() => setChoiceIndex(clampChoiceIndex(index, choices.length))}
                  aria-current={selectedChoice.index === index ? "true" : undefined}
                  aria-label={choiceButtonLabel(
                    part,
                    index,
                    choices,
                    (item) => item.label,
                    "Choose",
                  )}
                >
                  <SafeAssetImage
                    className="engine-match-part-art"
                    src={part.asset}
                    alt=""
                    context={`EngineMatch:part:${part.id}`}
                    fallbackText={assetFallbackText(`${part.label} picture`)}
                  />
                  <strong>{part.label}</strong>
                  {!pickedId && part.id === round.answer ? (
                    <small>Tap me</small>
                  ) : null}
                </button>
              ))}
            </div>
          )}
        </div>
      </div>
    </section>
  );
}
