local MonkeyGames = LibStub("AceAddon-3.0"):GetAddon("MonkeyGames")
local L = MonkeyGames.L

local GameManager = {}
MonkeyGames.GameManager = GameManager

-- Game states
local STATE_IDLE = "idle"
local STATE_WAITING = "waiting_accept"
local STATE_PLAYING = "playing"
local STATE_GAME_OVER = "game_over"

GameManager.state = STATE_IDLE
GameManager.activeGame = nil
GameManager.activeGameDef = nil
GameManager.gameMode = nil          -- "ai" | "multiplayer"
GameManager.localColor = nil        -- "white" | "black"
GameManager.opponentName = nil
GameManager.isLocalTurn = false
GameManager.moveHistory = {}
GameManager.aiDifficulty = 2
GameManager.gameResult = nil

function GameManager:Initialize()
    -- Nothing needed at init time; systems are ready
end

function GameManager:StartNewGame(gameName, mode, options)
    options = options or {}

    local gameDef = MonkeyGames.GameRegistry:GetGame(gameName)
    if not gameDef then
        MonkeyGames:ErrorPrint("Unknown game: " .. tostring(gameName))
        return
    end

    self.activeGameDef = gameDef
    self.activeGame = gameDef.createGameFunc()
    self.gameMode = mode
    self.state = STATE_PLAYING
    self.moveHistory = {}
    self.gameResult = nil

    if mode == "ai" then
        self.localColor = options.localColor or "white"
        self.aiDifficulty = options.difficulty or MonkeyGames.db.profile.AI.defaultDifficulty
        local diffNames = { "Easy", "Medium", "Hard" }
        self.opponentName = L["AI"] .. " (" .. (diffNames[self.aiDifficulty] or "Medium") .. ")"
        self.isLocalTurn = (self.localColor == "white")

        -- If AI goes first (player is black), trigger AI move
        if not self.isLocalTurn then
            self:ScheduleAIMove()
        end
    elseif mode == "multiplayer" then
        self.localColor = options.localColor or "white"
        self.opponentName = options.opponentName
        self.isLocalTurn = (self.localColor == "white")
    end

    -- Show the game UI
    MonkeyGames.GameBrowser:ShowGameView(gameName)
end

function GameManager:MakeMove(move)
    if self.state ~= STATE_PLAYING then return false end

    local gameDef = self.activeGameDef

    -- Validate
    if not gameDef.validateMoveFunc(self.activeGame, move) then
        return false
    end

    -- Apply
    gameDef.applyMoveFunc(self.activeGame, move)
    table.insert(self.moveHistory, move)

    -- Check game status
    local status = gameDef.getGameStatusFunc(self.activeGame)

    -- Update UI
    if MonkeyGames.activeGameUI and MonkeyGames.activeGameUI.RefreshBoard then
        MonkeyGames.activeGameUI:RefreshBoard()
    end

    if status ~= "playing" then
        self:HandleGameOver(status)
        return true
    end

    -- Switch turn
    self.isLocalTurn = not self.isLocalTurn

    -- Update controls
    if MonkeyGames.activeGameControls then
        MonkeyGames.activeGameControls:UpdateStatus()
    end

    -- If multiplayer, send the move
    if self.gameMode == "multiplayer" then
        MonkeyGames.NetworkManager:SendMove(move)
    end

    -- If AI's turn, schedule AI move
    if self.gameMode == "ai" and not self.isLocalTurn then
        self:ScheduleAIMove()
    end

    return true
end

function GameManager:ScheduleAIMove()
    MonkeyGames:ScheduleTimer(function()
        MonkeyGames.AIManager:RequestMove(
            GameManager.activeGame,
            GameManager.activeGameDef,
            GameManager.aiDifficulty
        )
    end, 0.3)
end

function GameManager:ReceiveMove(move)
    if self.state ~= STATE_PLAYING then return end

    local gameDef = self.activeGameDef
    gameDef.applyMoveFunc(self.activeGame, move)
    table.insert(self.moveHistory, move)
    self.isLocalTurn = true

    -- Update UI
    if MonkeyGames.activeGameUI and MonkeyGames.activeGameUI.RefreshBoard then
        MonkeyGames.activeGameUI:RefreshBoard()
    end

    local status = gameDef.getGameStatusFunc(self.activeGame)
    if status ~= "playing" then
        self:HandleGameOver(status)
    else
        if MonkeyGames.activeGameControls then
            MonkeyGames.activeGameControls:UpdateStatus()
        end
    end
end

function GameManager:HandleGameOver(status)
    self.state = STATE_GAME_OVER

    -- Determine result relative to local player
    local result
    if status == "checkmate" then
        -- The current turn's player is checkmated (they lost)
        local loserColor = self.activeGame.turn
        local localColorChar = self.localColor:sub(1, 1)
        if loserColor == localColorChar then
            result = "loss"
        else
            result = "win"
        end
    elseif status == "resign" then
        result = "loss"
    elseif status == "opponent_resigned" then
        result = "win"
    elseif status:find("draw") or status == "stalemate" then
        result = "draw"
    else
        result = "draw"
    end

    self.gameResult = result

    -- Update stats
    local dbKey = self.activeGameDef.dbKey
    local stats = MonkeyGames.db.char.Stats[dbKey]
    if not stats then
        MonkeyGames.db.char.Stats[dbKey] = { wins = 0, losses = 0, draws = 0 }
        stats = MonkeyGames.db.char.Stats[dbKey]
    end

    if result == "win" then
        stats.wins = stats.wins + 1
    elseif result == "loss" then
        stats.losses = stats.losses + 1
    else
        stats.draws = stats.draws + 1
    end

    -- Save to game history
    table.insert(MonkeyGames.db.char.GameHistory, 1, {
        game = self.activeGameDef.name,
        result = result,
        status = status,
        opponent = self.opponentName,
        date = date("%Y-%m-%d %H:%M"),
        moveCount = #self.moveHistory,
        localColor = self.localColor,
    })

    -- Cap history at 50
    while #MonkeyGames.db.char.GameHistory > 50 do
        table.remove(MonkeyGames.db.char.GameHistory)
    end

    -- Clear saved active game
    MonkeyGames.db.char.ActiveGame = nil

    -- Update UI
    if MonkeyGames.activeGameUI and MonkeyGames.activeGameUI.RefreshBoard then
        MonkeyGames.activeGameUI:RefreshBoard()
    end
    if MonkeyGames.activeGameControls then
        MonkeyGames.activeGameControls:UpdateStatus()
    end
end

function GameManager:Resign()
    if self.state ~= STATE_PLAYING then return end

    if self.gameMode == "multiplayer" then
        MonkeyGames.NetworkManager:SendResign()
    end

    self:HandleGameOver("resign")
end

function GameManager:SerializeGameState()
    if not self.activeGame or not self.activeGameDef then return nil end
    if self.gameMode == "multiplayer" then return nil end -- Don't save multiplayer games

    return {
        gameName = self.activeGameDef.name,
        state = self.activeGame,
        moveHistory = self.moveHistory,
        gameMode = self.gameMode,
        localColor = self.localColor,
        opponentName = self.opponentName,
        aiDifficulty = self.aiDifficulty,
    }
end

function GameManager:ResumeGame(savedData)
    if not savedData or not savedData.gameName then return end

    local gameDef = MonkeyGames.GameRegistry:GetGame(savedData.gameName)
    if not gameDef then return end

    self.activeGameDef = gameDef
    self.activeGame = savedData.state
    self.moveHistory = savedData.moveHistory or {}
    self.gameMode = savedData.gameMode or "ai"
    self.localColor = savedData.localColor or "white"
    self.opponentName = savedData.opponentName or L["AI"]
    self.aiDifficulty = savedData.aiDifficulty or 2
    self.state = STATE_PLAYING
    self.gameResult = nil

    -- Determine whose turn it is
    local turnColor = self.activeGame.turn
    local localColorChar = self.localColor:sub(1, 1)
    self.isLocalTurn = (turnColor == localColorChar)

    -- Show the game UI
    MonkeyGames.GameBrowser:ShowGameView(savedData.gameName)

    -- If it's the AI's turn, schedule a move
    if self.gameMode == "ai" and not self.isLocalTurn then
        self:ScheduleAIMove()
    end

    MonkeyGames:ChatPrint("Resumed " .. savedData.gameName .. " game")
end

function GameManager:IsPlaying()
    return self.state == STATE_PLAYING
end

function GameManager:IsGameOver()
    return self.state == STATE_GAME_OVER
end

function GameManager:Reset()
    self.state = STATE_IDLE
    self.activeGame = nil
    self.activeGameDef = nil
    self.gameMode = nil
    self.localColor = nil
    self.opponentName = nil
    self.isLocalTurn = false
    self.moveHistory = {}
    self.gameResult = nil
    MonkeyGames.db.char.ActiveGame = nil
end
