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

local BlackjackUI = {}
MonkeyGames.BlackjackUI = BlackjackUI

local CARD_WIDTH = 50
local CARD_HEIGHT = 75
local CARD_SPACING = 8

-- ========================================================================
-- Main UI creation
-- ========================================================================

function BlackjackUI:Create(parent)
    self.parent = parent

    -- Main container
    self.frame = CreateFrame("Frame", nil, parent)
    self.frame:SetPoint("TOPLEFT", parent, "TOPLEFT", 10, -10)
    self.frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", -10, 80)

    -- Table felt background (tiled green felt texture)
    local felt = self.frame:CreateTexture(nil, "BACKGROUND")
    felt:SetAllPoints()
    felt:SetTexture(Theme.TEX_FELT, "REPEAT", "REPEAT")
    felt:SetHorizTile(true)
    felt:SetVertTile(true)

    -- Dealer area (top)
    self.dealerArea = CreateFrame("Frame", nil, self.frame)
    self.dealerArea:SetHeight(120)
    self.dealerArea:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 20, -10)
    self.dealerArea:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -20, -10)

    self.dealerLabel = Widgets:CreateLabel(self.dealerArea, L["Dealer"], Theme.FONT_SIZE_BODY, Theme.TEXT_LABEL)
    self.dealerLabel:SetPoint("TOPLEFT", 0, 0)

    self.dealerValueText = Widgets:CreateLabel(self.dealerArea, "", Theme.FONT_SIZE_BODY, Theme.TEXT_GOLD)
    self.dealerValueText:SetPoint("LEFT", self.dealerLabel, "RIGHT", 8, 0)

    self.dealerCards = CreateFrame("Frame", nil, self.dealerArea)
    self.dealerCards:SetHeight(CARD_HEIGHT)
    self.dealerCards:SetPoint("TOPLEFT", self.dealerLabel, "BOTTOMLEFT", 0, -6)
    self.dealerCards:SetPoint("TOPRIGHT", self.dealerArea, "TOPRIGHT", 0, -20)

    -- Player area (bottom)
    self.playerArea = CreateFrame("Frame", nil, self.frame)
    self.playerArea:SetHeight(160)
    self.playerArea:SetPoint("BOTTOMLEFT", self.frame, "BOTTOMLEFT", 20, 10)
    self.playerArea:SetPoint("BOTTOMRIGHT", self.frame, "BOTTOMRIGHT", -20, 10)

    self.playerLabel = Widgets:CreateLabel(self.playerArea, L["Player"], Theme.FONT_SIZE_BODY, Theme.TEXT_ACCENT)
    self.playerLabel:SetPoint("TOPLEFT", 0, 0)

    self.playerValueText = Widgets:CreateLabel(self.playerArea, "", Theme.FONT_SIZE_BODY, Theme.TEXT_GOLD)
    self.playerValueText:SetPoint("LEFT", self.playerLabel, "RIGHT", 8, 0)

    self.handIndicator = Widgets:CreateLabel(self.playerArea, "", Theme.FONT_SIZE_SMALL, Theme.TEXT_DIM)
    self.handIndicator:SetPoint("LEFT", self.playerValueText, "RIGHT", 8, 0)

    self.playerCards = CreateFrame("Frame", nil, self.playerArea)
    self.playerCards:SetHeight(CARD_HEIGHT)
    self.playerCards:SetPoint("TOPLEFT", self.playerLabel, "BOTTOMLEFT", 0, -6)
    self.playerCards:SetPoint("TOPRIGHT", self.playerArea, "TOPRIGHT", 0, -20)

    -- Result overlay
    self.resultText = self.frame:CreateFontString(nil, "OVERLAY")
    self.resultText:SetFont(Theme.BASE_FONT, 18, "OUTLINE")
    self.resultText:SetPoint("CENTER", self.frame, "CENTER", 0, 0)
    self.resultText:SetText("")

    -- Balance / Bet display
    self.balanceText = Widgets:CreateLabel(self.frame, "", Theme.FONT_SIZE_BODY, Theme.TEXT_GOLD)
    self.balanceText:SetPoint("BOTTOMLEFT", self.frame, "BOTTOMLEFT", 20, -2)

    self.betText = Widgets:CreateLabel(self.frame, "", Theme.FONT_SIZE_BODY, Theme.TEXT_ACCENT)
    self.betText:SetPoint("BOTTOMRIGHT", self.frame, "BOTTOMRIGHT", -20, -2)

    -- Action buttons (below table, in the control area)
    self:CreateActionButtons(parent)

    -- Create betting UI
    self:CreateBettingUI()

    self.cardFrames = { dealer = {}, player = {} }

    MonkeyGames.activeGameUI = self
    self:RefreshBoard()
end

-- ========================================================================
-- Action buttons
-- ========================================================================

function BlackjackUI:CreateActionButtons(parent)
    local btnY = -6
    local btnW = 90
    local btnH = 26

    self.actionFrame = CreateFrame("Frame", nil, parent)
    self.actionFrame:SetHeight(70)
    self.actionFrame:SetPoint("BOTTOMLEFT", parent, "BOTTOMLEFT", 8, 8)
    self.actionFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", -8, 8)

    -- Hit button
    self.hitBtn = Widgets:CreateButton(self.actionFrame, L["Hit"], btnW, btnH)
    self.hitBtn:SetPoint("TOPLEFT", self.actionFrame, "TOPLEFT", 0, btnY)
    self.hitBtn:SetScript("OnClick", function()
        self:DoAction("hit")
    end)

    -- Stand button
    self.standBtn = Widgets:CreateButton(self.actionFrame, L["Stand"], btnW, btnH)
    self.standBtn:SetPoint("LEFT", self.hitBtn, "RIGHT", 6, 0)
    self.standBtn:SetScript("OnClick", function()
        self:DoAction("stand")
    end)

    -- Double Down button
    self.doubleBtn = Widgets:CreateButton(self.actionFrame, L["Double Down"], btnW, btnH)
    self.doubleBtn:SetPoint("LEFT", self.standBtn, "RIGHT", 6, 0)
    self.doubleBtn:SetScript("OnClick", function()
        self:DoAction("double")
    end)

    -- Split button
    self.splitBtn = Widgets:CreateButton(self.actionFrame, L["Split"], 70, btnH)
    self.splitBtn:SetPoint("LEFT", self.doubleBtn, "RIGHT", 6, 0)
    self.splitBtn:SetScript("OnClick", function()
        self:DoAction("split")
    end)

    -- Deal / New Round button
    self.dealBtn = Widgets:CreateButton(self.actionFrame, L["Deal"], btnW, btnH)
    self.dealBtn:SetPoint("TOP", self.actionFrame, "TOP", 0, btnY)
    self.dealBtn:SetScript("OnClick", function()
        self:DoAction("deal")
    end)

    -- Insurance buttons
    self.insuranceFrame = CreateFrame("Frame", nil, self.actionFrame)
    self.insuranceFrame:SetSize(200, 30)
    self.insuranceFrame:SetPoint("TOP", self.actionFrame, "TOP", 0, btnY)
    self.insuranceFrame:Hide()

    local insLabel = Widgets:CreateLabel(self.insuranceFrame, L["Insurance?"], Theme.FONT_SIZE_BODY, Theme.TEXT_GOLD)
    insLabel:SetPoint("LEFT", 0, 0)

    self.insYesBtn = Widgets:CreateButton(self.insuranceFrame, L["Yes"], 60, btnH)
    self.insYesBtn:SetPoint("LEFT", insLabel, "RIGHT", 8, 0)
    self.insYesBtn:SetScript("OnClick", function()
        self:DoAction("insurance_yes")
    end)

    self.insNoBtn = Widgets:CreateButton(self.insuranceFrame, L["No"], 60, btnH)
    self.insNoBtn:SetPoint("LEFT", self.insYesBtn, "RIGHT", 6, 0)
    self.insNoBtn:SetScript("OnClick", function()
        self:DoAction("insurance_no")
    end)

    -- Back button
    self.backBtn = Widgets:CreateButton(self.actionFrame, L["Back"], 60, btnH)
    self.backBtn:SetPoint("BOTTOMRIGHT", self.actionFrame, "BOTTOMRIGHT", 0, 0)
    self.backBtn:SetScript("OnClick", function()
        MonkeyGames.GameManager:Reset()
        MonkeyGames.GameBrowser:ShowBrowserView()
    end)
end

-- ========================================================================
-- Betting UI
-- ========================================================================

function BlackjackUI:CreateBettingUI()
    self.bettingFrame = CreateFrame("Frame", nil, self.frame)
    self.bettingFrame:SetSize(300, 80)
    self.bettingFrame:SetPoint("CENTER", self.frame, "CENTER", 0, 0)

    local betLabel = Widgets:CreateLabel(self.bettingFrame, L["Place your bet"], Theme.FONT_SIZE_TITLE, Theme.TEXT_ACCENT)
    betLabel:SetPoint("TOP", 0, 0)

    local chipAmounts = { 10, 25, 50, 100, 250 }
    self.betAmount = 100

    self.betDisplay = Widgets:CreateLabel(self.bettingFrame, L["Bet: "] .. "100", Theme.FONT_SIZE_BODY, Theme.TEXT_GOLD)
    self.betDisplay:SetPoint("TOP", betLabel, "BOTTOM", 0, -8)

    local chipFrame = CreateFrame("Frame", nil, self.bettingFrame)
    chipFrame:SetSize(300, 30)
    chipFrame:SetPoint("TOP", self.betDisplay, "BOTTOM", 0, -8)

    for i, amount in ipairs(chipAmounts) do
        local chip = Widgets:CreateButton(chipFrame, tostring(amount), 50, 24)
        chip:SetPoint("LEFT", chipFrame, "LEFT", (i - 1) * 56, 0)
        chip:SetScript("OnClick", function()
            local state = MonkeyGames.GameManager.activeGame
            if state and state.phase == "betting" and amount <= state.balance then
                self.betAmount = amount
                state.bet = amount
                self.betDisplay:SetText(L["Bet: "] .. amount)
            end
        end)
    end
end

-- ========================================================================
-- Action dispatch
-- ========================================================================

function BlackjackUI:DoAction(action)
    local gm = MonkeyGames.GameManager
    local state = gm.activeGame
    if not state then return end

    -- After a round ends, "deal" resets to betting phase first
    if action == "deal" and state.phase == "resolved" then
        state.phase = "betting"
        self:RefreshBoard()
        return
    end

    local move = { action = action }
    if action == "bet" then
        move.amount = self.betAmount
    end

    -- For Blackjack we bypass the normal GameManager:MakeMove validation
    -- and call directly since Blackjack has its own flow
    if Blackjack:ValidateMove(state, move) then
        Blackjack:ApplyMove(state, move)

        -- Check if game round ended
        local status = Blackjack:GetGameStatus(state)
        if status ~= "playing" then
            self:HandleRoundEnd(state, status)
        end

        self:RefreshBoard()
    end
end

function BlackjackUI:HandleRoundEnd(state, status)
    -- Update stats
    local stats = MonkeyGames.db.char.Stats.Blackjack
    if not stats then
        MonkeyGames.db.char.Stats.Blackjack = { wins = 0, losses = 0, draws = 0 }
        stats = MonkeyGames.db.char.Stats.Blackjack
    end

    if status == "player_wins" then
        stats.wins = stats.wins + 1
    elseif status == "dealer_wins" then
        stats.losses = stats.losses + 1
    else
        stats.draws = stats.draws + 1
    end
end

-- ========================================================================
-- Board refresh (card rendering)
-- ========================================================================

function BlackjackUI:RefreshBoard()
    local state = MonkeyGames.GameManager.activeGame
    if not state then return end

    -- Clear old card frames
    self:ClearCards()

    -- Show/hide UI based on phase
    local isBetting = (state.phase == "betting")
    local isInsurance = (state.phase == "insurance")
    local isPlaying = (state.phase == "player_turn")
    local isResolved = (state.phase == "resolved")

    self.bettingFrame:SetShown(isBetting)
    self.hitBtn:SetShown(isPlaying)
    self.standBtn:SetShown(isPlaying)
    self.doubleBtn:SetShown(isPlaying and state.canDoubleDown and state.balance >= state.bets[state.activeHandIndex])
    self.splitBtn:SetShown(isPlaying and state.canSplit)
    self.dealBtn:SetShown(isBetting or isResolved)
    self.insuranceFrame:SetShown(isInsurance)

    -- Balance / Bet
    self.balanceText:SetText(L["Balance: "] .. state.balance .. "g")
    self.betText:SetText(L["Bet: "] .. (state.bets[state.activeHandIndex] or state.bet) .. "g")

    -- Render dealer cards
    if #state.dealerHand > 0 then
        self:RenderHand(state.dealerHand, self.dealerCards, "dealer", not state.dealerRevealed)
        if state.dealerRevealed then
            self.dealerValueText:SetText("(" .. Blackjack:HandValue(state.dealerHand) .. ")")
        else
            local upValue = ({ ["A"]=11,["2"]=2,["3"]=3,["4"]=4,["5"]=5,["6"]=6,["7"]=7,["8"]=8,["9"]=9,["10"]=10,["J"]=10,["Q"]=10,["K"]=10 })[state.dealerHand[1].rank] or 10
            self.dealerValueText:SetText("(" .. upValue .. " + ?)")
        end
    else
        self.dealerValueText:SetText("")
    end

    -- Render player cards
    for i, hand in ipairs(state.playerHands) do
        if #hand > 0 then
            local yOffset = (i - 1) * (CARD_HEIGHT + 10)
            local container = self.playerCards
            self:RenderHand(hand, container, "player" .. i, false, yOffset)
        end
    end

    -- Player value
    if #state.playerHands > 0 and #state.playerHands[state.activeHandIndex] > 0 then
        local val = Blackjack:HandValue(state.playerHands[state.activeHandIndex])
        self.playerValueText:SetText("(" .. val .. ")")

        if #state.playerHands > 1 then
            self.handIndicator:SetText("Hand " .. state.activeHandIndex .. "/" .. #state.playerHands)
        else
            self.handIndicator:SetText("")
        end
    else
        self.playerValueText:SetText("")
        self.handIndicator:SetText("")
    end

    -- Result text
    if isResolved then
        local result = state.results[1]
        if result == "blackjack" then
            self.resultText:SetText(L["Blackjack!"])
            self.resultText:SetTextColor(unpack(Theme.TEXT_GOLD))
        elseif result == "win" then
            self.resultText:SetText(L["You win!"])
            self.resultText:SetTextColor(unpack(Theme.TEXT_GREEN))
        elseif result == "bust" then
            self.resultText:SetText(L["Bust!"])
            self.resultText:SetTextColor(unpack(Theme.TEXT_ERROR))
        elseif result == "loss" then
            self.resultText:SetText(L["Dealer wins"])
            self.resultText:SetTextColor(unpack(Theme.TEXT_ERROR))
        elseif result == "push" then
            self.resultText:SetText(L["Push"])
            self.resultText:SetTextColor(unpack(Theme.TEXT_DIM))
        end
    else
        self.resultText:SetText("")
    end
end

-- ========================================================================
-- Card rendering
-- ========================================================================

function BlackjackUI:RenderHand(hand, parent, prefix, hideSecond, yOffset)
    yOffset = yOffset or 0

    for i, card in ipairs(hand) do
        local cardFrame = self:CreateCardFrame(parent, i, yOffset)
        if hideSecond and i == 2 then
            self:RenderCardBack(cardFrame)
        else
            self:RenderCardFace(cardFrame, card)
        end
        self.cardFrames[prefix] = self.cardFrames[prefix] or {}
        self.cardFrames[prefix][i] = cardFrame
    end
end

function BlackjackUI:CreateCardFrame(parent, index, yOffset)
    local card = CreateFrame("Frame", nil, parent)
    card:SetSize(CARD_WIDTH, CARD_HEIGHT)
    card:SetPoint("TOPLEFT", parent, "TOPLEFT", (index - 1) * (CARD_WIDTH + CARD_SPACING), -(yOffset or 0))

    local bgTex = card:CreateTexture(nil, "ARTWORK")
    bgTex:SetAllPoints()
    card.bgTex = bgTex

    return card
end

function BlackjackUI:RenderCardFace(cardFrame, card)
    local tex = Theme:GetCardTexture(card.rank, card.suit)
    if tex then
        cardFrame.bgTex:SetTexture(tex)
    end
end

function BlackjackUI:RenderCardBack(cardFrame)
    cardFrame.bgTex:SetTexture(Theme.CARD_BACK_TEXTURE)
end

function BlackjackUI:ClearCards()
    for prefix, cards in pairs(self.cardFrames) do
        for _, cardFrame in pairs(cards) do
            cardFrame:Hide()
            cardFrame:SetParent(nil)
        end
    end
    self.cardFrames = {}
end

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

function BlackjackUI:Destroy()
    self:ClearCards()
    if self.frame then
        self.frame:Hide()
        self.frame = nil
    end
    if self.actionFrame then
        self.actionFrame:Hide()
        self.actionFrame = nil
    end
    MonkeyGames.activeGameUI = nil
end
