const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const cors = require('cors');
require('dotenv').config();
const { v4: uuidv4 } = require('uuid');

const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"]
  }
});

app.use(cors({
  origin: "*",
  methods: ["GET", "POST"],
  credentials: true
}));

const games = new Map();

class GameState {
  constructor(player1Id, player2Id = null) {
    this.players = {
      [player1Id]: { health: 100, ready: false }
    };
    if (player2Id) {
      this.players[player2Id] = { health: 100, ready: false };
    }
    this.gameStatus = 'waiting'; // 'waiting', 'playing', 'finished'
    this.winner = null;
  }

  addPlayer(playerId) {
    if (Object.keys(this.players).length < 2) {
      this.players[playerId] = { health: 100, ready: false };
      return true;
    }
    return false;
  }

  applyDamage(playerId, amount) {
    this.players[playerId].health -= amount;
    if (this.players[playerId].health <= 0) {
      this.gameStatus = 'finished';
      this.winner = Object.keys(this.players).find(id => id !== playerId);
    }
    return this.getGameState();
  }

  setPlayerReady(playerId) {
    this.players[playerId].ready = true;
    if (Object.values(this.players).every(player => player.ready)) {
      this.gameStatus = 'playing';
    }
    return this.getGameState();
  }

  getGameState() {
    return {
      players: this.players,
      gameStatus: this.gameStatus,
      winner: this.winner
    };
  }
}

io.on('connection', (socket) => {
  console.log('Client connected');

  socket.on('joinGame', (gameId) => {
    let game = games.get(gameId);
    
    if (!game) {
      // 새 게임 생성
      game = new GameState(socket.id);
      games.set(gameId, game);
      socket.join(gameId);
      socket.gameId = gameId;
    } else if (game.players[socket.id]) {
      // 이미 참여한 플레이어
      return;
    } else if (Object.keys(game.players).length < 2) {
      // 두 번째 플레이어 추가
      game.addPlayer(socket.id);
      socket.join(gameId);
      socket.gameId = gameId;
    } else {
      // 게임이 이미 가득 참
      return;
    }

    io.to(gameId).emit('gameState', game.getGameState());
  });

  socket.on('ready', () => {
    const gameId = socket.gameId;
    const game = games.get(gameId);
    if (game) {
      const newState = game.setPlayerReady(socket.id);
      io.to(gameId).emit('gameState', newState);
    }
  });

  socket.on('damage', (data) => {
    const gameId = socket.gameId;
    const game = games.get(gameId);
    if (game && game.gameStatus === 'playing') {
      const targetPlayerId = Object.keys(game.players).find(id => id !== socket.id);
      if (targetPlayerId) {
        const newState = game.applyDamage(targetPlayerId, data.amount);
        io.to(gameId).emit('gameState', newState);
      }
    }
  });

  socket.on('useSkill', ({ skillType }) => {
    const gameId = socket.gameId;
    if (gameId) {
      socket.to(gameId).emit('opponentSkillUsed', { skillType: skillType });
    }
  });

  socket.on('disconnect', () => {
    console.log('Client disconnected');
    const gameId = socket.gameId;
    if (gameId) {
      const game = games.get(gameId);
      if (game) {
        delete game.players[socket.id];
        if (Object.keys(game.players).length === 0) {
          games.delete(gameId);
        } else {
          game.gameStatus = 'finished';
          game.winner = Object.keys(game.players)[0];
          io.to(gameId).emit('gameState', game.getGameState());
        }
      }
    }
  });
});

const PORT = process.env.PORT || 7777;
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));