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

local ChessUI = {}
MonkeyGames.ChessUI = ChessUI

-- Piece display characters (fallback for missing textures)
local PIECE_DISPLAY = {
    wK = "K", wQ = "Q", wR = "R", wB = "B", wN = "N", wP = "P",
    bK = "K", bQ = "Q", bR = "R", bB = "B", bN = "N", bP = "P",
}

-- File/rank labels
local FILE_LABELS = { "a", "b", "c", "d", "e", "f", "g", "h" }
local RANK_LABELS = { "8", "7", "6", "5", "4", "3", "2", "1" }

local CELL_SIZE = 48

-- ========================================================================
-- Board creation and rendering
-- ========================================================================

function ChessUI:Create(parent)
    self.parent = parent
    self.selectedSquare = nil
    self.cachedLegalMoves = nil
    self.lastMoveFrom = nil
    self.lastMoveTo = nil
    self.flipped = false

    local boardSize = 8 * CELL_SIZE

    -- Board container (centered in parent)
    self.boardFrame = CreateFrame("Frame", nil, parent)
    self.boardFrame:SetSize(boardSize + 24, boardSize + 24) -- extra space for labels
    self.boardFrame:SetPoint("TOP", parent, "TOP", 0, -8)

    -- Create the grid
    self.board = BoardWidget:Create(self.boardFrame, 8, 8, CELL_SIZE)
    self.board:SetPoint("TOPLEFT", self.boardFrame, "TOPLEFT", 20, -4)

    -- Color the squares
    self:ColorBoard()

    -- Set click handler
    self.board.onCellClick = function(board, row, col)
        ChessUI:OnCellClicked(row, col)
    end

    -- File labels (a-h below the board)
    self.fileLabels = {}
    for col = 1, 8 do
        local fs = self.boardFrame:CreateFontString(nil, "OVERLAY")
        fs:SetFont(Theme.BASE_FONT, Theme.FONT_SIZE_SMALL, "")
        fs:SetPoint("TOP", self.board, "BOTTOMLEFT", (col - 0.5) * CELL_SIZE, -2)
        fs:SetText(FILE_LABELS[col])
        fs:SetTextColor(unpack(Theme.TEXT_DIM))
        self.fileLabels[col] = fs
    end

    -- Rank labels (1-8 to the left of the board)
    self.rankLabels = {}
    for row = 1, 8 do
        local fs = self.boardFrame:CreateFontString(nil, "OVERLAY")
        fs:SetFont(Theme.BASE_FONT, Theme.FONT_SIZE_SMALL, "")
        fs:SetPoint("RIGHT", self.board, "TOPLEFT", -4, -(row - 0.5) * CELL_SIZE)
        fs:SetText(RANK_LABELS[row])
        fs:SetTextColor(unpack(Theme.TEXT_DIM))
        self.rankLabels[row] = fs
    end

    -- Opponent label (above board)
    self.opponentLabel = self.boardFrame:CreateFontString(nil, "OVERLAY")
    self.opponentLabel:SetFont(Theme.BASE_FONT, Theme.FONT_SIZE_SMALL, "")
    self.opponentLabel:SetPoint("BOTTOMLEFT", self.board, "TOPLEFT", 0, 4)
    self.opponentLabel:SetTextColor(unpack(Theme.TEXT_DIM))

    -- Player label (below board)
    self.playerLabel = self.boardFrame:CreateFontString(nil, "OVERLAY")
    self.playerLabel:SetFont(Theme.BASE_FONT, Theme.FONT_SIZE_SMALL, "")
    self.playerLabel:SetPoint("TOPLEFT", self.board, "BOTTOMLEFT", 0, -14)
    self.playerLabel:SetTextColor(unpack(Theme.TEXT_ACCENT))

    -- Check if board should be flipped (player plays black)
    local gm = MonkeyGames.GameManager
    if gm.localColor == "black" then
        self.flipped = true
        self:ColorBoard()
    end

    self:UpdateLabels()

    MonkeyGames.activeGameUI = self
    self:RefreshBoard()
end

function ChessUI:ColorBoard()
    for row = 1, 8 do
        for col = 1, 8 do
            local displayRow, displayCol = self:ToDisplayCoords(row, col)
            local isLight = (displayRow + displayCol) % 2 == 0
            local color = isLight and Theme.BOARD_LIGHT or Theme.BOARD_DARK
            BoardWidget:SetCellBgColor(self.board, row, col, color)
        end
    end
end

function ChessUI:UpdateLabels()
    local gm = MonkeyGames.GameManager
    local playerName = UnitName("player") or "You"
    local opponentName = gm.opponentName or L["AI"]
    local playerColor = gm.localColor or "white"
    local opponentColor = (playerColor == "white") and "black" or "white"

    self.playerLabel:SetText(playerName .. " (" .. playerColor .. ")")
    self.opponentLabel:SetText(opponentName .. " (" .. opponentColor .. ")")

    -- Update file/rank labels for flipped board
    for col = 1, 8 do
        local displayCol = self.flipped and (9 - col) or col
        self.fileLabels[col]:SetText(FILE_LABELS[displayCol])
    end
    for row = 1, 8 do
        local displayRow = self.flipped and (9 - row) or row
        self.rankLabels[row]:SetText(RANK_LABELS[displayRow])
    end
end

--- Convert board coordinates to display coordinates (handles flipping).
function ChessUI:ToDisplayCoords(boardRow, boardCol)
    if self.flipped then
        return 9 - boardRow, 9 - boardCol
    end
    return boardRow, boardCol
end

--- Convert display coordinates back to board coordinates.
function ChessUI:FromDisplayCoords(displayRow, displayCol)
    if self.flipped then
        return 9 - displayRow, 9 - displayCol
    end
    return displayRow, displayCol
end

-- ========================================================================
-- Board refresh
-- ========================================================================

function ChessUI:RefreshBoard()
    local state = MonkeyGames.GameManager.activeGame
    if not state or not self.board then return end

    -- Clear all highlights
    BoardWidget:ClearAllHighlights(self.board)

    -- Render pieces
    for boardRow = 1, 8 do
        for boardCol = 1, 8 do
            local piece = state.board[boardRow][boardCol]
            local displayRow, displayCol = self:ToDisplayCoords(boardRow, boardCol)

            if piece ~= "" then
                local pieceTex = Theme.CHESS_PIECE_TEXTURES[piece]
                if pieceTex then
                    BoardWidget:SetCellContent(self.board, displayRow, displayCol, "", nil)
                    BoardWidget:SetCellTexture(self.board, displayRow, displayCol, pieceTex)
                else
                    BoardWidget:SetCellTexture(self.board, displayRow, displayCol, nil)
                    local pieceColor = piece:sub(1, 1)
                    local textColor = (pieceColor == "w") and Theme.PIECE_WHITE or Theme.PIECE_BLACK
                    local display = PIECE_DISPLAY[piece] or ""
                    BoardWidget:SetCellContent(self.board, displayRow, displayCol, display, textColor)
                    BoardWidget:SetCellFontSize(self.board, displayRow, displayCol, Theme.FONT_SIZE_PIECE)
                end
            else
                BoardWidget:SetCellContent(self.board, displayRow, displayCol, "", nil)
                BoardWidget:SetCellTexture(self.board, displayRow, displayCol, nil)
            end
        end
    end

    -- Highlight last move
    if self.lastMoveFrom and self.lastMoveTo then
        local dr1, dc1 = self:ToDisplayCoords(self.lastMoveFrom[1], self.lastMoveFrom[2])
        local dr2, dc2 = self:ToDisplayCoords(self.lastMoveTo[1], self.lastMoveTo[2])
        BoardWidget:SetCellHighlight(self.board, dr1, dc1, Theme.HIGHLIGHT_LAST_MOVE)
        BoardWidget:SetCellHighlight(self.board, dr2, dc2, Theme.HIGHLIGHT_LAST_MOVE)
    end

    -- Highlight king in check
    if state.inCheck then
        local kingPos = state.kingPositions[state.turn]
        local dr, dc = self:ToDisplayCoords(kingPos[1], kingPos[2])
        BoardWidget:SetCellHighlight(self.board, dr, dc, Theme.HIGHLIGHT_CHECK)
    end

    -- Re-highlight selected square and legal moves if applicable
    if self.selectedSquare then
        local sr, sc = self:ToDisplayCoords(self.selectedSquare[1], self.selectedSquare[2])
        BoardWidget:SetCellHighlight(self.board, sr, sc, Theme.HIGHLIGHT_SELECTED)

        if self.cachedLegalMoves then
            for _, move in ipairs(self.cachedLegalMoves) do
                local mr, mc = self:ToDisplayCoords(move.toRow, move.toCol)
                local targetPiece = state.board[move.toRow][move.toCol]
                local isCapture = (targetPiece ~= "") or move.enPassant
                if isCapture then
                    BoardWidget:SetCellHighlight(self.board, mr, mc, Theme.HIGHLIGHT_CAPTURE)
                else
                    BoardWidget:SetCellIndicator(self.board, mr, mc, Theme.HIGHLIGHT_LEGAL)
                end
            end
        end
    end
end

-- ========================================================================
-- Click interaction
-- ========================================================================

function ChessUI:OnCellClicked(displayRow, displayCol)
    local state = MonkeyGames.GameManager.activeGame
    local gm = MonkeyGames.GameManager
    if not state or gm.state ~= "playing" or not gm.isLocalTurn then return end

    -- Convert display coords to board coords
    local boardRow, boardCol = self:FromDisplayCoords(displayRow, displayCol)

    local piece = state.board[boardRow][boardCol]
    local localColorChar = gm.localColor:sub(1, 1)

    if self.selectedSquare then
        -- Second click: attempt to move
        local fromRow, fromCol = self.selectedSquare[1], self.selectedSquare[2]

        -- Check if clicking on own piece (re-select)
        if piece ~= "" and piece:sub(1, 1) == localColorChar then
            if boardRow == fromRow and boardCol == fromCol then
                -- Deselect
                self.selectedSquare = nil
                self.cachedLegalMoves = nil
                self:RefreshBoard()
            else
                -- Select different piece
                self:SelectSquare(boardRow, boardCol)
            end
            return
        end

        -- Find matching legal move
        local targetMove = nil
        if self.cachedLegalMoves then
            for _, move in ipairs(self.cachedLegalMoves) do
                if move.toRow == boardRow and move.toCol == boardCol then
                    -- For non-promotion moves, or we'll handle promotion separately
                    if not move.promotion then
                        targetMove = move
                        break
                    elseif not targetMove then
                        targetMove = move -- take the first promotion option, will show popup
                    end
                end
            end
        end

        if targetMove then
            -- Check if this is a promotion move (need popup)
            local movingPiece = state.board[fromRow][fromCol]
            if movingPiece:sub(2, 2) == "P" and (boardRow == 1 or boardRow == 8) then
                self:ShowPromotionPopup(fromRow, fromCol, boardRow, boardCol)
                return
            end

            -- Record last move for highlighting
            self.lastMoveFrom = { fromRow, fromCol }
            self.lastMoveTo = { boardRow, boardCol }

            -- Execute the move
            self.selectedSquare = nil
            self.cachedLegalMoves = nil
            gm:MakeMove(targetMove)
        else
            -- Invalid target, deselect
            self.selectedSquare = nil
            self.cachedLegalMoves = nil
            self:RefreshBoard()
        end
    else
        -- First click: select a piece
        if piece ~= "" and piece:sub(1, 1) == localColorChar then
            self:SelectSquare(boardRow, boardCol)
        end
    end
end

function ChessUI:SelectSquare(boardRow, boardCol)
    local state = MonkeyGames.GameManager.activeGame
    if not state then return end

    self.selectedSquare = { boardRow, boardCol }
    self.cachedLegalMoves = Chess:GetLegalMoves(state, boardRow, boardCol)
    self:RefreshBoard()
end

-- ========================================================================
-- Promotion popup
-- ========================================================================

function ChessUI:ShowPromotionPopup(fromRow, fromCol, toRow, toCol)
    -- Remove old popup if exists
    if self.promoPopup then
        self.promoPopup:Hide()
    end

    local popup = CreateFrame("Frame", nil, self.board, BackdropTemplateMixin and "BackdropTemplate")
    popup:SetSize(4 * CELL_SIZE + 8, CELL_SIZE + 8)
    popup:SetFrameStrata("DIALOG")
    popup:SetFrameLevel(20)

    popup.backdropInfo = Theme.BACKDROP
    popup:ApplyBackdrop()
    popup:SetBackdropColor(Theme.BG_COLOR[1], Theme.BG_COLOR[2], Theme.BG_COLOR[3], 0.95)
    popup:SetBackdropBorderColor(unpack(Theme.BORDER_COLOR))

    -- Position near the promotion square
    local displayRow, displayCol = self:ToDisplayCoords(toRow, toCol)
    local cell = self.board.cells[displayRow][displayCol]
    if displayRow <= 4 then
        popup:SetPoint("TOP", cell.frame, "BOTTOM", 0, -4)
    else
        popup:SetPoint("BOTTOM", cell.frame, "TOP", 0, 4)
    end

    -- Label
    local label = popup:CreateFontString(nil, "OVERLAY")
    label:SetFont(Theme.BASE_FONT, Theme.FONT_SIZE_SMALL, "")
    label:SetPoint("TOP", popup, "TOP", 0, -2)
    label:SetText(L["Choose a piece:"])
    label:SetTextColor(unpack(Theme.TEXT_ACCENT))

    local gm = MonkeyGames.GameManager
    local localColorChar = gm.localColor:sub(1, 1)
    local pieceColor = (localColorChar == "w") and Theme.PIECE_WHITE or Theme.PIECE_BLACK

    local promoOptions = { "Q", "R", "B", "N" }
    local promoNames = { "Q", "R", "B", "N" }

    for i, promoPiece in ipairs(promoOptions) do
        local btn = CreateFrame("Button", nil, popup)
        btn:SetSize(CELL_SIZE, CELL_SIZE)
        btn:SetPoint("TOPLEFT", popup, "TOPLEFT", 4 + (i - 1) * CELL_SIZE, -4)

        local bg = btn:CreateTexture(nil, "BACKGROUND")
        bg:SetAllPoints()
        bg:SetTexture(Theme.TEX_WHITE8X8)
        bg:SetVertexColor(Theme.BUTTON_BG[1], Theme.BUTTON_BG[2], Theme.BUTTON_BG[3], 0.8)

        local pieceKey = localColorChar .. promoPiece
        local pieceTex = Theme.CHESS_PIECE_TEXTURES[pieceKey]
        if pieceTex then
            local tex = btn:CreateTexture(nil, "ARTWORK")
            tex:SetSize(CELL_SIZE * 0.75, CELL_SIZE * 0.75)
            tex:SetPoint("CENTER", 0, 0)
            tex:SetTexture(pieceTex)
        else
            local text = btn:CreateFontString(nil, "ARTWORK")
            text:SetFont(Theme.BASE_FONT, Theme.FONT_SIZE_PIECE, "OUTLINE")
            text:SetPoint("CENTER", 0, 0)
            text:SetText(promoNames[i])
            text:SetTextColor(unpack(pieceColor))
        end

        btn:SetScript("OnEnter", function(self)
            bg:SetVertexColor(Theme.BUTTON_BG_HOVER[1], Theme.BUTTON_BG_HOVER[2], Theme.BUTTON_BG_HOVER[3], 0.9)
        end)
        btn:SetScript("OnLeave", function(self)
            bg:SetVertexColor(Theme.BUTTON_BG[1], Theme.BUTTON_BG[2], Theme.BUTTON_BG[3], 0.8)
        end)

        btn:SetScript("OnClick", function()
            popup:Hide()
            ChessUI.promoPopup = nil

            local move = {
                fromRow = fromRow,
                fromCol = fromCol,
                toRow = toRow,
                toCol = toCol,
                promotion = promoPiece,
            }

            ChessUI.lastMoveFrom = { fromRow, fromCol }
            ChessUI.lastMoveTo = { toRow, toCol }
            ChessUI.selectedSquare = nil
            ChessUI.cachedLegalMoves = nil

            gm:MakeMove(move)
        end)
    end

    self.promoPopup = popup
end

-- ========================================================================
-- Cleanup
-- ========================================================================

function ChessUI:Destroy()
    if self.promoPopup then
        self.promoPopup:Hide()
        self.promoPopup = nil
    end
    if self.boardFrame then
        self.boardFrame:Hide()
        self.boardFrame = nil
    end
    self.board = nil
    self.selectedSquare = nil
    self.cachedLegalMoves = nil
    self.lastMoveFrom = nil
    self.lastMoveTo = nil
    MonkeyGames.activeGameUI = nil
end
