Clone
import Phaser from "phaser"
import { Socket, Presence } from "phoenix"
import { HubScene } from "./game/HubScene"
import { PiMemoryGame } from "./game/PiMemoryGame"
import { MonteCarloGame } from "./game/MonteCarloGame"
import { SliceThePiGame } from "./game/SliceThePiGame"
import { TriviaGame } from "./game/TriviaGame"
import { ProjectileGame } from "./game/ProjectileGame"
import { SoundFX } from "./game/SoundFX"

// --- Phoenix Socket Connection ---
const socket = new Socket("/game_socket", {
  params: { token: window.PLAYER_TOKEN }
})
socket.connect()

const hubChannel = socket.channel("game:hub", {})
const miniChannel = (gameType) => {
  const ch = socket.channel(`game:mini:${gameType}`, {})
  ch.join()
  return ch
}

const presence = new Presence(hubChannel)

// --- Phaser Game Config ---
const config = {
  type: Phaser.AUTO,
  parent: "game-canvas",
  width: 800,
  height: 600,
  backgroundColor: "#0a0a2e",
  scale: {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH,
  },
  scene: [HubScene],
  physics: {
    default: "arcade",
    arcade: { debug: false }
  },
  input: {
    activePointers: 2,
  }
}

const game = new Phaser.Game(config)

// Pass dependencies to scene
game.registry.set("hubChannel", hubChannel)
game.registry.set("presence", presence)
game.registry.set("socket", socket)
game.registry.set("miniChannel", miniChannel)

// Join hub channel
hubChannel.join()
  .receive("ok", () => {
    console.log("Joined hub!")
    // Auto-open game if navigated to a game URL (e.g. /projectile-pi)
    if (window.AUTO_OPEN_GAME) {
      setTimeout(() => window.piStation.openMiniGame(window.AUTO_OPEN_GAME), 500)
    }
  })
  .receive("error", (resp) => console.error("Unable to join hub", resp))

// --- Mini-game Manager ---
window.piStation = {
  openMiniGame(gameType) {
    // Don't re-open if a game is already active
    if (window.piStation._currentGame) return

    const overlay = document.getElementById("mini-game-overlay")
    const content = document.getElementById("mini-game-content")
    overlay.classList.add("active")

    // Hide station prompt
    document.getElementById("station-prompt").classList.remove("visible")

    // Disable Phaser input while overlay is active
    const scene = game.scene.getScene("HubScene")
    if (scene) scene.input.enabled = false

    hubChannel.push("enter_game", { game: gameType })
    SoundFX.countdown()

    const channel = miniChannel(gameType)

    switch (gameType) {
      case "pi_memory":
        PiMemoryGame.start(content, channel)
        break
      case "monte_carlo":
        MonteCarloGame.start(content, channel)
        break
      case "slice_the_pi":
        SliceThePiGame.start(content, channel)
        break
      case "pi_trivia":
        TriviaGame.start(content, channel)
        break
      case "projectile_pi":
        ProjectileGame.start(content, channel)
        break
    }

    window.piStation._currentChannel = channel
    window.piStation._currentGame = gameType
  },

  closeMiniGame() {
    const overlay = document.getElementById("mini-game-overlay")
    overlay.classList.remove("active")

    const content = document.getElementById("mini-game-content")
    while (content.firstChild) content.removeChild(content.firstChild)

    hubChannel.push("leave_game", {})

    // Re-enable Phaser input
    const scene = game.scene.getScene("HubScene")
    if (scene) scene.input.enabled = true

    if (window.piStation._currentChannel) {
      window.piStation._currentChannel.leave()
      window.piStation._currentChannel = null
    }
    window.piStation._currentGame = null
  },

  // Chat
  sendChat(message) {
    if (message) {
      hubChannel.push("chat", { message })
    }
  },

  // Station prompt — called from HubScene
  showStationPrompt(station) {
    const el = document.getElementById("station-prompt")
    const isMobile = "ontouchstart" in window
    if (station) {
      const action = isMobile ? "Tap" : "Press SPACE"
      el.textContent = `${action} to play ${station.label.replace("\n", " ")}!`
      el.classList.add("visible")
      el.onclick = () => window.piStation.openMiniGame(station.game)
    } else {
      el.classList.remove("visible")
      el.onclick = null
    }
  },

  _currentChannel: null,
  _currentGame: null,
}

// --- Chat messages from server ---
hubChannel.on("chat", ({ player_id, name, message }) => {
  SoundFX.chat()

  // Pass to Phaser scene for bubble rendering
  const scene = game.scene.getScene("HubScene")
  if (scene && scene.showRemoteChat) {
    scene.showRemoteChat(player_id, name, message)
  }
})

// --- Players List UI ---
const playersListEl = document.getElementById("players-list")

const avatarSymbols = {
  pi: "\u03C0", sigma: "\u03A3", delta: "\u0394", omega: "\u03A9",
  theta: "\u03B8", lambda: "\u03BB", phi: "\u03C6", psi: "\u03C8",
  epsilon: "\u03B5", zeta: "\u03B6"
}

let prevPlayerCount = 0

function updatePlayersList() {
  const players = []
  presence.list((id, { metas: [meta] }) => {
    players.push({ id, ...meta })
  })

  // Play join sound when new player appears
  if (players.length > prevPlayerCount && prevPlayerCount > 0) {
    SoundFX.join()
  }
  prevPlayerCount = players.length

  players.sort((a, b) => (b.score || 0) - (a.score || 0))

  while (playersListEl.firstChild) playersListEl.removeChild(playersListEl.firstChild)

  // Header
  const header = document.createElement("div")
  header.style.cssText = "color:#a78bfa;font-size:0.6rem;padding:0.2rem 0.4rem;font-weight:bold;"
  header.textContent = `Online: ${players.length}`
  playersListEl.appendChild(header)

  players.forEach(p => {
    const entry = document.createElement("div")
    entry.className = "player-entry"

    const avatar = document.createElement("span")
    avatar.className = "player-avatar"
    avatar.textContent = avatarSymbols[p.avatar_key] || "?"

    const name = document.createElement("span")
    name.textContent = p.name

    const score = document.createElement("span")
    score.className = "player-score"
    score.textContent = p.score || 0

    entry.appendChild(avatar)
    entry.appendChild(name)
    entry.appendChild(score)
    playersListEl.appendChild(entry)
  })
}

presence.onSync(() => updatePlayersList())

// Export SoundFX globally for mini-games
window.SoundFX = SoundFX