const express = require('express');
const cors = require('cors');
const mysql = require('mysql2/promise');

const app = express();
app.use(cors());
app.use(express.json());

(async () => {
  console.log("Initializing database connection...");

  try {
    const pool = await mysql.createPool({
      host: 'host.docker.internal',
      user: 'root',
      password: 'somepassword',
      database: 'battleship',
      waitForConnections: true,
      connectionLimit: 10,
      queueLimit: 0
    });

    console.log("Successfully connected to MySQL!");


    const conn = await pool.getConnection();
    const [rows] = await conn.query("SELECT VERSION() AS mysql_version");
    console.log(`MySQL Version: ${rows[0].mysql_version}`);
    conn.release();


    console.log("Checking or creating tables...");
    await pool.execute(`
      CREATE TABLE IF NOT EXISTS games (
        id INT AUTO_INCREMENT PRIMARY KEY,
        player1 VARCHAR(255),
        player2 VARCHAR(255),
        player1_ships JSON,
        player2_ships JSON,
        current_turn INT DEFAULT 1,
        game_state JSON NOT NULL
      )
    `);
    console.log("Table 'games' is ready!");

    await pool.execute(`
      CREATE TABLE IF NOT EXISTS game_results (
        id INT AUTO_INCREMENT PRIMARY KEY,
        game_id INT,
        winner VARCHAR(255),
        loser VARCHAR(255),
        moves INT
      )
    `);
    console.log("Table 'game_results' is ready!");

app.get('/api/results', async (req, res) => {
  try {
    const [results] = await pool.execute('SELECT * FROM game_results ORDER BY id DESC');
    res.json({ results });
  } catch (err) {
    console.error("Error fetching results:", err);
    res.status(500).json({ error: "Database error" });
  }
});

  
    app.post('/api/new-game', async (req, res) => {
      const { player1, player2 } = req.body;
      if (!player1 || !player2) {
        console.warn("Missing player names in request.");
        return res.status(400).json({ error: 'Player names required' });
      }
      
      const gameState = {
        boardSize: 5,
        hits: [],
        misses: [],
        gameOver: false
      };

      try {
        console.log(`Creating new game for ${player1} vs ${player2}...`);
        const [result] = await pool.execute(
          'INSERT INTO games (player1, player2, game_state) VALUES (?, ?, ?)',
          [player1, player2, JSON.stringify(gameState)]
        );
        console.log(`Game created with ID: ${result.insertId}`);
        res.json({ gameId: result.insertId, message: 'Game created' });
      } catch (err) {
        console.error('Error creating game:', err);
        res.status(500).json({ error: 'Database error' });
      }
    });

  
    app.post('/api/place-ships', async (req, res) => {
      const { gameId, player, ships } = req.body;
      if (!gameId || !player || !ships) {
        console.warn("Missing parameters for placing ships.");
        return res.status(400).json({ error: 'Missing parameters' });
      }

      try {
        console.log(`Placing ships for player ${player} in game ID: ${gameId}...`);
        const [rows] = await pool.execute('SELECT * FROM games WHERE id = ?', [gameId]);
        if (rows.length === 0) {
          console.warn(`Game with ID ${gameId} not found.`);
          return res.status(404).json({ error: 'Game not found' });
        }

        let updateField = player === 1 ? 'player1_ships' : 'player2_ships';
        await pool.execute(`UPDATE games SET ${updateField} = ? WHERE id = ?`, [JSON.stringify(ships), gameId]);
        console.log(`Ships placed for player ${player} in game ID: ${gameId}`);

        res.json({ message: `Ships placed for player ${player}` });
      } catch (err) {
        console.error('Error placing ships:', err);
        res.status(500).json({ error: 'Database error' });
      }
    });

    // 🎯 Атака
    app.post('/api/attack', async (req, res) => {
      const { gameId, row, col, player } = req.body;
      if (!gameId || typeof row === 'undefined' || typeof col === 'undefined' || !player) {
        console.warn("Missing attack parameters in request.");
        return res.status(400).json({ error: 'Missing parameters' });
      }

      try {
        console.log(`Player ${player} attacks (${row}, ${col}) in game ID: ${gameId}`);
        const [rows] = await pool.execute('SELECT * FROM games WHERE id = ?', [gameId]);
        if (rows.length === 0) {
          console.warn(`Game with ID ${gameId} not found.`);
          return res.status(404).json({ error: 'Game not found' });
        }

        let game = rows[0];
        let state = JSON.parse(game.game_state);
        let opponentShips = player === 1 ? JSON.parse(game.player2_ships || "[]") : JSON.parse(game.player1_ships || "[]");

        const hit = opponentShips.some(ship => ship.row === row && ship.col === col);

        if (hit) {
          console.log(`HIT! Player ${player} hit an opponent's ship at (${row}, ${col})`);
          state.hits.push({ row, col });
          if (state.hits.length === opponentShips.length) {
            state.gameOver = true;
            console.log(`Player ${player} has won the game!`);
          }
        } else {
          console.log(`MISS! Player ${player} attacked (${row}, ${col}) but missed.`);
          state.misses.push({ row, col });
        }

        state.current_turn = player === 1 ? 2 : 1;

        await pool.execute('UPDATE games SET game_state = ? WHERE id = ?', [JSON.stringify(state), gameId]);

        res.json({ hit, state });
      } catch (err) {
        console.error("Attack error:", err);
        res.status(500).json({ error: 'Database error' });
      }
    });

    app.post('/api/save-result', async (req, res) => {
      const { gameId, winner, loser, moves } = req.body;

      if (!gameId || !winner || !loser || !moves) {
        console.warn("Missing game result parameters.");
        return res.status(400).json({ error: 'Missing parameters' });
      }

      try {
        console.log(`Saving result: Winner - ${winner}, Loser - ${loser}, Moves - ${moves}`);
        await pool.execute(
          `INSERT INTO game_results (game_id, winner, loser, moves) VALUES (?, ?, ?, ?)`,
          [gameId, winner, loser, moves]
        );

        console.log(`Game result saved for game ID ${gameId}`);
        res.json({ message: "Game result saved" });
      } catch (err) {
        console.error("Error saving game result:", err);
        res.status(500).json({ error: "Database error" });
      }
    });

    const port = 4000;
    app.listen(port, () => {
      console.log(`Backend started on port ${port}`);
    });

  } catch (err) {
    console.error("Database connection failed!", err);
  }
})();