import { Server } from "socket.io";
import { BASE_URL } from "../constants/index.js";

function generateId(length = 32) {
  const chars =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let result = "";
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return result;
}

const io = new Server(3002, {
  cors: {
    origin: ["http://localhost:3002"],
    methods: ["GET", "POST"],
  },
});

const PROGRESS_DURATION = 20;
const BREAK_DURATION = 5;
let targetMultiplier = 1.0;
let multiplierInterval = null;
let phaseInterval = null;

let gameState = {
  phase: "waiting",
  timeLeft: 0,
  multiplier: 1.0,
  game_id: generateId(),
  players: [],
  progressDuration: PROGRESS_DURATION,
};



function startRound() {
  // ---- Phase 1: Progress ----
  gameState.phase = "progress";
  gameState.timeLeft = PROGRESS_DURATION;
  gameState.multiplier = 1.0;
  targetMultiplier = parseFloat((Math.random() * 5 + 1).toFixed(1)); // 1.0 → 6.0
  gameState.game_id = generateId();
  gameState.progressDuration = PROGRESS_DURATION;
  io.emit("gameUpdate", gameState);

  phaseInterval = setInterval(() => {
    gameState.timeLeft--;

    io.emit("gameUpdate", gameState);
    // console.log("Progress", gameState.timeLeft);
    if (gameState.timeLeft <= 0) {
      clearInterval(phaseInterval);
      startMultiplierPhase();
    }
  }, 1000);
}

function startMultiplierPhase() {
  gameState.phase = "multiplier";
  gameState.multiplier = 1.0;
  io.emit("gameUpdate", gameState);

  multiplierInterval = setInterval(() => {
    if (gameState.multiplier < targetMultiplier) {
      gameState.multiplier = parseFloat(
        (gameState.multiplier + 0.1).toFixed(1),
      );
      io.emit("gameUpdate", gameState);
    } else {
      clearInterval(multiplierInterval);
      startBreakPhase();
    }
    // console.log("Multiplier", gameState.multiplier);
  }, 100); // increments every 100ms
}

function startBreakPhase() {
  gameState.phase = "break";
  gameState.timeLeft = BREAK_DURATION;

  gameState.players = []; // Clears players object

  //gameState.multiplier = 1.0;
  io.emit("gameUpdate", gameState);
  crashed(gameState.game_id);

  phaseInterval = setInterval(() => {
    gameState.timeLeft--;
    io.emit("gameUpdate", gameState);
    // console.log("Break", gameState.timeLeft);
    if (gameState.timeLeft <= 0) {
      clearInterval(phaseInterval);
      startRound(); // start next round
    }
  }, 1000);
}

startRound();

io.on("connection", (socket) => {
  console.log("Player connected:", socket.id);
  socket.emit("gameUpdate", gameState);
  io.emit("playerCount", io.engine.clientsCount);

  socket.on("joinGame", async ({ user_id, cards, price, image }) => {
    // Prevent duplicate joins
    if (!gameState.players.find((p) => p.user_id === user_id)) {
      let player = {
        user_id,
        image, // User image link
        cards, // array of selected cards
        price, // bet or selected price
        win_cards: [],
        status: "join",
      };
      let d = await joinPlayer(player, gameState.game_id);
      player.show_cards = d.cards;
      gameState.players.push(player);
      io.emit("gameUpdate", gameState); // broadcast updated players
    }
  });

  socket.on("cashoutGame", async (user_id, win_card) => {
    const player = gameState.players.find((p) => p.user_id === user_id);
    if (player && player.status === "join") {
      player.status = "cashout"; // update status
      player.win_cards = [win_card] || [];
      await cashoutPlayer(player.user_id, player.win_cards);
      io.emit("gameUpdate", gameState); // broadcast updated game state
      console.log("Player cashed out:", player);
    }
  });

  socket.on("disconnect", () => {
    io.emit("playerCount", io.engine.clientsCount);
    console.log("Player disconnected:", socket.id);
  });
});

async function joinPlayer(player, game_id) {
  try {
    const response = await fetch(BASE_URL + "/api/crash-join", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        game_id: game_id,
        player: player,
        target: targetMultiplier,
      }),
    });

    if (!response.ok) {
    }
    const data = await response.json();
    return data;
  } catch (error) {
    console.log(error);
    return {
      success: false,
      message: error.message || "Something went wrong",
    };
  }
}

async function cashoutPlayer(player_id, win_card) {
  try {
    const response = await fetch(BASE_URL + "/api/crash-cashout", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        game_id: gameState.game_id,
        multiplier: gameState.multiplier,
        player_id: player_id,
        win_card: win_card,
      }),
    });

    if (!response.ok) {
      console.log(response);
    }
    const data = await response.json();
    console.log(data);
    return data;
  } catch (error) {
    console.log(error);
    return {
      success: false,
      message: error.message || "Something went wrong",
    };
  }
}

async function crashed(game_id) {
  try {
    const response = await fetch(BASE_URL + "/api/crash-out", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        game_id: game_id,
        multiplier: gameState.multiplier,
      }),
    });

    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    return data;
  } catch (error) {
    console.log(error);
    return {
      success: false,
      message: error.message || "Something went wrong",
    };
  }
}
