const { Op } = require("sequelize");
const Player = require("../../models/Player");
const sessionManager = require("../../game/SessionManager");
const economyService = require("../../game/EconomyService.js");

module.exports = async (io, socket) => {
  const userId = socket.user?.id;
  const username = socket.user?.username;
  const sid = socket.id.substring(0, 5);

  if (!userId) {
    return socket.disconnect();
  }

  try {
    let player = await Player.findByPk(userId);

    if (!player) {
      try {
        player = await Player.create({
          id: userId,
          username: username,
        });
      } catch (createErr) {
        player = await Player.findByPk(userId);
      }
    }

    const offlineCredits = await economyService.handleOfflineEarnings(player);

    socket.playerId = userId;
    socket.join("online_room");
    economyService.addPlayer(userId);

    const playerRaw = player.get({ plain: true });
    sessionManager.addPlayer(socket.id, playerRaw);
    const onlinePlayersData = sessionManager.getAllOnline();
    const onlineUsernames = onlinePlayersData.map((p) => p.username);

    const onlineIds = onlinePlayersData.map((p) => p.id);

    const offlinePlayersModels = await Player.findAll({
      where: {
        id: { [Op.notIn]: onlineIds },
      },
      attributes: ["username"],
      raw: true,
    });

    const offlineUsernames = offlinePlayersModels.map((p) => p.username);

    socket.emit("session:ready", {
      player: {
        id: playerRaw.id,
        username: playerRaw.username,
        level: playerRaw.level,
        credits: playerRaw.credits,
        experience: playerRaw.experience,
      },
      offlineEarned: offlineCredits,
      onlinePlayers: onlineUsernames,
      offlinePlayers: offlineUsernames,
    });

    socket.broadcast.emit("player:joined", { username: playerRaw.username });
    socket.join(`user_${socket.user.id}`);
    socket.on("player:get_dashboard", async () => {
      try {
        const p = await Player.findByPk(userId);
        if (p) socket.emit("player:dashboard_data", p.toJSON());
      } catch (err) {
        console.error(`❌ [${sid}] Dashboard error:`, err.message);
      }
    });

    socket.on("disconnect", async () => {
      try {
        await Player.update(
          { lastCreditUpdate: new Date() },
          { where: { id: userId } },
        );
      } catch (e) {}

      economyService.removePlayer(userId);
      sessionManager.removePlayer(socket.id);
      socket.broadcast.emit("player:left", { username: playerRaw.username });
    });
  } catch (err) {
    console.error(`❌ [${sid}] Connection Error:`, err.message);
    socket.disconnect();
  }
};
