import { h, render } from 'preact';
import { signal } from '@preact/signals-core';
import Phaser from 'phaser';
import { createGameContext } from 'boardgame-core';
import { GameUI, PromptDialog, CommandLog } from 'boardgame-phaser';
import { createInitialState, registry, type TicTacToeState } from './game/tic-tac-toe';
import { GameScene, type GameSceneData } from './scenes/GameScene';
import './style.css';

const gameContext = createGameContext<TicTacToeState>(registry, createInitialState);

const promptSignal = signal<null | Awaited<ReturnType<typeof gameContext.commands.promptQueue.pop>>>(null);
const commandLog = signal<Array<{ input: string; result: string; timestamp: number }>>([]);

gameContext.commands.on('prompt', (event) => {
  promptSignal.value = event;
});

const originalRun = gameContext.commands.run.bind(gameContext.commands);
(gameContext.commands as any).run = async (input: string) => {
  const result = await originalRun(input);
  commandLog.value = [
    ...commandLog.value,
    {
      input,
      result: result.success ? `OK: ${JSON.stringify(result.result)}` : `ERR: ${result.error}`,
      timestamp: Date.now(),
    },
  ];
  return result;
};

const sceneData: GameSceneData = {
  state: gameContext.state,
  commands: gameContext.commands,
};

const phaserConfig: Phaser.Types.Core.GameConfig = {
  type: Phaser.AUTO,
  width: 560,
  height: 560,
  parent: 'phaser-container',
  backgroundColor: '#f9fafb',
  scene: [],
};

const game = new Phaser.Game(phaserConfig);

game.scene.add('GameScene', GameScene, true, sceneData);

const ui = new GameUI({
  container: document.getElementById('ui-root')!,
  root: h('div', { className: 'flex flex-col h-screen' },
    h('div', { className: 'flex-1 relative' },
      h('div', { id: 'phaser-container', className: 'w-full h-full' }),
      h(PromptDialog, {
        prompt: promptSignal.value,
        onSubmit: (input: string) => {
          gameContext.commands._tryCommit(input);
          promptSignal.value = null;
        },
        onCancel: () => {
          gameContext.commands._cancel('cancelled');
          promptSignal.value = null;
        },
      }),
    ),
    h('div', { className: 'p-4 bg-gray-100 border-t' },
      h(CommandLog, { entries: commandLog }),
    ),
  ),
});

ui.mount();

gameContext.commands.run('setup');
