/**
 * @fileoverview Integra eventos globais de UI com handlers de execução do jogo.
 *
 * O `gameController` encapsula a associação entre o `gameEventBus` (eventos
 * globais disparados pela UI/editor) e callbacks da cena (execute, reset,
 * checkSuccess). Garante também limpeza dos listeners quando a cena é
 * destruída.
 *
 * @module shared.gameController
 */

import { gameEventBus } from "../utils/gameEvents";

/**
 * Registra handlers da cena nos eventos globais do editor/jogos.
 *
 * Associa os callbacks fornecidos ao `gameEventBus` e garante limpeza
 * automática quando a cena é destruída.
 *
 * @param {Phaser.Scene} scene - Instância da cena do Phaser
 * @param {Object} handlers - Handlers da cena
 * @param {Function} handlers.onExecuteCode - Recebe evento com `{ detail: { code, workspace } }`
 * @param {Function} handlers.onReset - Callback para resetar a cena
 * @param {Function} handlers.onCheckSuccess - Verifica sucesso da execução
 * @returns {void}
 */
export function setupGameController(
  scene,
  { onExecuteCode, onReset, onCheckSuccess },
) {
  if (scene.events.listenerCount("destroy") > 0 && scene._cleanupController) {
    scene.events.removeListener("destroy", scene._cleanupController);
  }

  const executeCodeHandler = (event) => {
    onExecuteCode.call(scene, event.detail.code, event.detail.workspace);
  };

  const resetGameHandler = () => {
    onReset.call(scene);
  };

  const stopExecutionHandler = () => {
    if (scene.gameInterpreter) {
      scene.gameInterpreter.stop();
    }
    if (scene.workspace) {
      scene.workspace.highlightBlock(null);
    }
  };

  gameEventBus.addEventListener("executeCode", executeCodeHandler);
  gameEventBus.addEventListener("resetGame", resetGameHandler);
  gameEventBus.addEventListener("stopExecution", stopExecutionHandler);

  const cleanup = () => {
    gameEventBus.removeEventListener("executeCode", executeCodeHandler);
    gameEventBus.removeEventListener("resetGame", resetGameHandler);
    gameEventBus.removeEventListener("stopExecution", stopExecutionHandler);
  };

  scene._cleanupController = cleanup;
  scene.events.on("destroy", cleanup);

  gameEventBus.gameReady();
}
