local addonName, ZL = ...
local LOGO_TEXTURE = "Interface\\AddOns\\ZoneLocked\\assets\\zonelocked-logo.png"

local function StylePanel(frame, r, g, b, a)
    frame:SetBackdrop({
        bgFile = "Interface/Buttons/WHITE8X8",
        edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
        edgeSize = 12,
    })
    frame:SetBackdropColor(r, g, b, a)
    frame:SetBackdropBorderColor(0.25, 0.65, 0.85, 0.9)
end

function ZL:CreateRollFrame()
    local frame = CreateFrame("Frame", "ZoneLockedRollFrame", UIParent, "BackdropTemplate")
    frame:SetSize(610, 270)
    frame:SetPoint("CENTER")
    frame:SetFrameStrata("DIALOG")
    frame:SetFrameLevel(250)
    frame:EnableMouse(true)
    StylePanel(frame, 0.012, 0.022, 0.03, 0.98)

    frame.logo = frame:CreateTexture(nil, "ARTWORK")
    frame.logo:SetTexture(LOGO_TEXTURE)
    frame.logo:SetTexCoord(0.16, 0.84, 0.02, 0.96)
    frame.logo:SetSize(58, 58)
    frame.logo:SetPoint("TOP", 0, -12)
    frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    frame.title:SetPoint("TOP", frame.logo, "BOTTOM", 0, -4)
    frame.title:SetText("Rolling the Borderlands")
    frame.subtitle = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    frame.subtitle:SetPoint("TOP", frame.title, "BOTTOM", 0, -6)
    frame.subtitle:SetText("Every adjacent zone is in the draw")

    frame.cards = {}
    for index = 1, 6 do
        local card = CreateFrame("Frame", nil, frame, "BackdropTemplate")
        card:SetHeight(58)
        StylePanel(card, 0.025, 0.045, 0.06, 0.98)
        card.name = card:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        card.name:SetPoint("CENTER")
        card.name:SetJustifyH("CENTER")
        card.name:SetWordWrap(true)
        card:Hide()
        frame.cards[index] = card
    end

    frame.result = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    frame.result:SetPoint("BOTTOM", 0, 20)
    frame.result:SetText("")
    frame:Hide()
    self.RollFrame = frame
end

local function SetCardState(card, state)
    if state == "active" then
        card:SetBackdropColor(0.04, 0.28, 0.40, 1)
        card:SetBackdropBorderColor(0.35, 0.9, 1, 1)
        card.name:SetTextColor(1, 0.88, 0.35)
    elseif state == "winner" then
        card:SetBackdropColor(0.035, 0.30, 0.13, 1)
        card:SetBackdropBorderColor(0.3, 1, 0.55, 1)
        card.name:SetTextColor(0.45, 1, 0.62)
    else
        card:SetBackdropColor(0.025, 0.045, 0.06, 0.98)
        card:SetBackdropBorderColor(0.18, 0.42, 0.55, 0.75)
        card.name:SetTextColor(0.82, 0.86, 0.9)
    end
end

function ZL:StartZoneRoll(continentID, expansionKey)
    if self.rollInProgress then return false end
    local activeMapID, candidates, errorMessage, context
    if #(ZL_Saved.route or {}) == 0 then
        if not continentID then
            local currentMapID = self:GetCurrentZoneID()
            continentID, expansionKey = self:GetMapContinentID(currentMapID)
            if not continentID or not self:IsExpansionEnabled(expansionKey) then
                local selectable = self:GetSelectableContinents()
                continentID = selectable[1] and selectable[1].continentID
                expansionKey = selectable[1] and selectable[1].expansionKey
            end
        end
        if continentID then
            candidates, context = self:GetInitialRollCandidates(continentID, expansionKey)
            if not candidates then errorMessage, context = context, nil end
        else
            errorMessage = "No enabled continent is available for a starting roll."
        end
    else
        activeMapID, candidates, errorMessage, context = self:GetRollCandidates()
    end
    if not candidates then
        self:Print(errorMessage)
        return false
    end

    self.rollInProgress = true
    self.rollSerial = (self.rollSerial or 0) + 1
    local serial = self.rollSerial
    local frame = self.RollFrame
    frame.title:SetText(context and context.mode == "start" and "Rolling the First Chapter" or "Rolling the Borderlands")
    frame.subtitle:SetText((context and context.label) or "Every adjacent zone is in the draw")
    local count = #candidates
    local gap = 8
    local cardWidth = math.floor((566 - ((count - 1) * gap)) / count)
    for index, card in ipairs(frame.cards) do
        card:ClearAllPoints()
        if index <= count then
            card:SetWidth(cardWidth)
            card.name:SetWidth(cardWidth - 12)
            card:SetPoint("TOPLEFT", 22 + ((index - 1) * (cardWidth + gap)), -148)
            card.name:SetText(self:GetZoneDefinition(candidates[index]).name)
            SetCardState(card, "idle")
            card:Show()
        else
            card:Hide()
        end
    end

    frame.result:SetText("|cff65d1ffMapping possible routes...|r")
    frame:Show()
    frame:SetAlpha(1)

    local selectedIndex = math.random(count)
    local selectedMapID = candidates[selectedIndex]
    local baseSteps = 18
    local baseIndex = ((baseSteps - 1) % count) + 1
    local totalSteps = baseSteps + ((selectedIndex - baseIndex + count) % count)
    local step = 0

    local function Advance()
        if serial ~= self.rollSerial then return end
        step = step + 1
        local activeIndex = ((step - 1) % count) + 1
        for index = 1, count do SetCardState(frame.cards[index], index == activeIndex and "active" or "idle") end
        if SOUNDKIT and SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON then
            PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
        end

        if step < totalSteps then
            C_Timer.After(0.045 + (step * 0.009), Advance)
            return
        end

        SetCardState(frame.cards[selectedIndex], "winner")
        local ok, message
        if context and context.mode == "start" then
            ok, message = self:SetStartingZone(selectedMapID)
        else
            ok, message = self:CommitRolledZone(activeMapID, selectedMapID, context)
        end
        self.rollInProgress = false
        frame.result:SetText(ok and ("|cff55ff88Unlocked: " .. self:GetZoneDefinition(selectedMapID).name .. "|r") or message)
        self:Print(message)
        if ok then self:ShowCollectionAlert(message, nil, 237381) end
        C_Timer.After(3.2, function()
            if serial == self.rollSerial and frame:IsShown() then
                UIFrameFadeOut(frame, 0.35, frame:GetAlpha(), 0)
                C_Timer.After(0.4, function() if serial == self.rollSerial then frame:Hide() end end)
            end
        end)
    end

    C_Timer.After(0.15, Advance)
    return true
end
