import { Elysia, t } from 'elysia';
import { html } from '@elysiajs/html';
import { staticPlugin } from '@elysiajs/static';
import { cookie } from '@elysiajs/cookie';
import { WebSocketHandler } from './web-socket-handler';
import { GomokuGame } from './game/game-instance';

const wsHandler = new WebSocketHandler();

const app = new Elysia()
  .use(
    staticPlugin({
      assets: './public',
      prefix: '/',
    }),
  )
  .use(cookie())
  .use(html())
  .ws('/ws', {
    query: t.Object({
      gameId: t.String(),
      playerId: t.String(),
    }),
    open(ws) {
      wsHandler.handleConnection(ws);
    },
    message(ws, message) {
      wsHandler.handleMessage(ws, message);
    },
    close(ws) {
      wsHandler.handleDisconnect(ws);
    },
  })
  .get('/', async ({ query, cookie, request: _request }) => {
    let playerId: string;
    const existingPlayerId = cookie.playerId?.value;
    if (existingPlayerId) {
      playerId = existingPlayerId;
      console.log(`Using existing playerId from cookie: ${playerId}`);
    } else {
      playerId = `player-${Math.random().toString(36).substring(2, 9)}`;
      cookie.playerId.set({
        value: playerId,
        httpOnly: true,
        path: '/',
        maxAge: 30 * 24 * 60 * 60,
      });
      console.log(`Generated new playerId and set cookie: ${playerId}`);
    }

    let gameId = query.gameId as string | undefined;
    let gameIdInitialized = false;
    if (gameId) {
      if (!wsHandler.hasGame(gameId)) {
        wsHandler.createGame(gameId);
        console.log(`Created new game with provided ID: ${gameId}`);
      }
    } else {
      gameId = wsHandler.createGame();
      gameIdInitialized = true;
      console.log(`Created new game without specific ID: ${gameId}`);
    }

    if (gameIdInitialized) {
      return new Response(null, {
        status: 302,
        headers: { Location: `/?gameId=${gameId}` },
      });
    }

    const displayName = wsHandler.getPlayerName(playerId);

    const htmlTemplate = await Bun.file('./index.html').text();
    let finalHtml = htmlTemplate
      .replace(
        '<meta name="gameId" content="" />',
        `<meta name="gameId" content="${gameId}" />`,
      )
      .replace(
        '<meta name="playerId" content="" />',
        `<meta name="playerId" content="${playerId}" />`,
      )
      .replace(
        '<meta name="displayName" content="" />',
        `<meta name="displayName" content="${displayName}" />`,
      );

    return new Response(finalHtml, {
      headers: { 'Content-Type': 'text/html' },
      status: 200,
    });
  });

const port = (() => {
  let p = 3000;
  for (let i = 0; i < Bun.argv.length; i++) {
    if (Bun.argv[i] === '--port') {
      const parsedPort = Number(Bun.argv[i + 1]);
      if (!isNaN(parsedPort) && parsedPort > 0) {
        p = parsedPort;
        break;
      }
    }
  }
  return p;
})();

app.listen(port, () => {
  console.log(`🦊 Elysia is running at ${app.server?.hostname}:${port}`);
});
