/**
 * @fileoverview Utility module for useCodeExecution.js
 * 
 * @module pages.Playground.hooks.useCodeExecution
 */

import { useState, useCallback, useRef } from "react";
import { GameInterpreter } from "../../../interpreters/GameInterpreter";

export const useCodeExecution = () => {
  const [output, setOutput] = useState([]);
  const [isRunning, setIsRunning] = useState(false);
  const interpreterRef = useRef(null);

  const addOutput = useCallback((message, type = "log") => {
    setOutput((prev) => [
      ...prev,
      {
        id: Date.now() + Math.random(),
        timestamp: new Date(),
        message,
        type,
      },
    ]);
  }, []);

  const clearOutput = useCallback(() => {
    setOutput([]);
  }, []);

  const runCode = useCallback(
    async (code) => {
      if (!code || code.trim() === "") {
        addOutput("Nenhum código para executar", "error");
        return;
      }

      setIsRunning(true);
      clearOutput();

      // Adicionar linha de início da execução
      addOutput("▶️ Iniciando execução...", "log");

      try {
        interpreterRef.current = new GameInterpreter();

        const apiSetup = (interpreter, globalObject) => {
          const consoleLogWrapper = (text) => {
            addOutput(String(text), "log");
          };
          interpreter.setProperty(
            globalObject,
            "console",
            interpreter.nativeToPseudo({
              log: consoleLogWrapper,
            }),
          );

          const alertWrapper = (text) => {
            addOutput(String(text), "log");
          };
          interpreter.setProperty(
            globalObject,
            "alert",
            interpreter.createNativeFunction(alertWrapper),
          );

          const promptWrapper = (text) => {
            addOutput(`Prompt: ${text} (não suportado)`, "alert");
            return null;
          };
          interpreter.setProperty(
            globalObject,
            "prompt",
            interpreter.createNativeFunction(promptWrapper),
          );
        };

        await interpreterRef.current.executeCode(code, apiSetup);

        addOutput("Execução concluída com sucesso", "success");
      } catch (error) {
        addOutput(`Erro: ${error.message}`, "error");
      } finally {
        setIsRunning(false);
      }
    },
    [addOutput, clearOutput],
  );

  return {
    output,
    isRunning,
    runCode,
    clearOutput,
  };
};
