local _, ns = ...
local L = ns.L or {}

local UIData = ns.UIData or {}
local VAULT_ROW_MAP = UIData.VAULT_ROW_MAP or {}
local VAULT_ROW_COLORS = UIData.VAULT_ROW_COLORS or {}
local GOAL_BAR_COLOR = UIData.GOAL_BAR_COLOR or { 0.68, 0.34, 0.26 }

local VaultView = {}
ns.UIVaultView = VaultView

local function getVaultRowColor(rowKey)
    local color = VAULT_ROW_COLORS[rowKey or "world"] or VAULT_ROW_COLORS.world or { 0.42, 0.74, 0.88 }
    return color[1], color[2], color[3]
end

local function getDisplayedCompletedCount(row)
    if not row then
        return 0
    end

    local thresholds = type(row.thresholds) == "table" and row.thresholds or {}
    local maxThreshold = tonumber(thresholds[#thresholds]) or 0
    local completed = math.max(0, tonumber(row.completedCount) or 0)
    if maxThreshold <= 0 then
        return completed
    end

    return math.min(completed, maxThreshold)
end

function VaultView.CreateSlotCard(parent, helpers)
    helpers = helpers or {}
    local createSectionFrame = helpers.createSectionFrame
    local createLabel = helpers.createLabel
    local createProgressBar = helpers.createProgressBar

    local card = createSectionFrame(parent, "cardInset")
    card:SetSize(224, 118)

    card.title = createLabel(card, "GameFontHighlight", "LEFT")
    card.title:SetPoint("TOPLEFT", 14, -14)

    card.reward = createLabel(card, "GameFontHighlightSmall", "RIGHT")
    card.reward:SetPoint("TOPRIGHT", -14, -14)

    card.vaultLabel = createLabel(card, "GameFontDisableSmall", "LEFT")
    card.vaultLabel:SetPoint("TOPLEFT", card.title, "BOTTOMLEFT", 0, -12)
    card.vaultLabel:SetText(L.VAULT_UNLOCK_LABEL or "Vault slots")

    card.vaultValue = createLabel(card, "GameFontNormal", "RIGHT")
    card.vaultValue:SetPoint("RIGHT", card.reward, "RIGHT", 0, 0)
    card.vaultValue:SetPoint("CENTER", card.vaultLabel, "CENTER", 0, 0)

    card.vaultBar = createProgressBar(card)
    card.vaultBar:SetPoint("TOPLEFT", card.vaultLabel, "BOTTOMLEFT", 0, -6)
    card.vaultBar:SetPoint("TOPRIGHT", -14, 0)
    card.vaultBar:SetHeight(12)

    card.goalLabel = createLabel(card, "GameFontDisableSmall", "LEFT")
    card.goalLabel:SetPoint("TOPLEFT", card.vaultBar, "BOTTOMLEFT", 0, -14)
    card.goalLabel:SetText(L.VAULT_GOAL_LABEL or "Max reward")

    card.goalValue = createLabel(card, "GameFontNormal", "RIGHT")
    card.goalValue:SetPoint("RIGHT", card.reward, "RIGHT", 0, 0)
    card.goalValue:SetPoint("CENTER", card.goalLabel, "CENTER", 0, 0)

    card.goalBar = createProgressBar(card)
    card.goalBar:SetPoint("TOPLEFT", card.goalLabel, "BOTTOMLEFT", 0, -6)
    card.goalBar:SetPoint("TOPRIGHT", -14, 0)
    card.goalBar:SetHeight(12)

    return card
end

function VaultView.LayoutSlotCards(ui)
    if not ui.frame or not ui.frame.vaultCard or not ui.frame.vaultCard.slotCards then
        return
    end

    local container = ui.frame.vaultCard
    local slotCards = container.slotCards
    if #slotCards < 3 then
        return
    end

    local gap = 14
    local rowGap = 12
    local contentWidth = math.max(0, (container:GetWidth() or 0) - 28)
    local columns = math.min(3, #slotCards)
    local minCardWidth = 180
    while columns > 1 and math.floor((contentWidth - (gap * (columns - 1))) / columns) < minCardWidth do
        columns = columns - 1
    end

    local cardWidth
    if columns == 1 then
        cardWidth = math.max(150, math.min(360, contentWidth))
    else
        cardWidth = math.floor((contentWidth - (gap * (columns - 1))) / columns)
        cardWidth = math.max(minCardWidth, math.min(224, cardWidth))
    end

    for index, slotCard in ipairs(slotCards) do
        slotCard:SetSize(cardWidth, 118)
        slotCard:ClearAllPoints()
        if index == 1 then
            slotCard:SetPoint("TOPLEFT", container.note, "BOTTOMLEFT", 0, -18)
        elseif ((index - 1) % columns) == 0 then
            slotCard:SetPoint("TOPLEFT", slotCards[index - columns], "BOTTOMLEFT", 0, -rowGap)
        else
            slotCard:SetPoint("LEFT", slotCards[index - 1], "RIGHT", gap, 0)
        end
    end
end

function VaultView.RefreshCard(ui, character, snapshot, helpers)
    if not ui.frame or not ui.frame.vaultCard then
        return
    end

    helpers = helpers or {}
    local setProgressBar = helpers.setProgressBar or function() end
    local setProgressBreakpoints = helpers.setProgressBreakpoints or function() end

    local selectedSubTab = ns:GetSelectedSubTab("vault")
    local rowKey = VAULT_ROW_MAP[selectedSubTab] or "raid"
    local row = snapshot and snapshot.rows and snapshot.rows[rowKey] or nil
    local card = ui.frame.vaultCard
    local r, g, b = getVaultRowColor(rowKey)

    if not row then
        card.title:SetText(L.VAULT_EMPTY or "No live Vault snapshot found yet for this character.")
        card.subtitle:SetText(character and string.format("%s-%s", character.name or (L.UNKNOWN or "Unknown"), character.realm or (L.UNKNOWN or "Unknown")) or "")
        card.breakpoints:SetText("")
        card.unlockValue:SetText("--")
        card.goalValue:SetText("--")
        setProgressBar(card.unlockBar, 0, r, g, b)
        setProgressBar(card.goalBar, 0, GOAL_BAR_COLOR[1], GOAL_BAR_COLOR[2], GOAL_BAR_COLOR[3])
        setProgressBreakpoints(card.unlockBar, nil, 0)
        setProgressBreakpoints(card.goalBar, nil, 0)
        card.note:SetText(snapshot and snapshot.summary and snapshot.summary.headline or "")
        card.note:SetShown((snapshot and snapshot.summary and snapshot.summary.headline and snapshot.summary.headline ~= "") and true or false)

        for index, slotCard in ipairs(card.slotCards or {}) do
            slotCard.title:SetText(string.format(L.VAULT_SLOT_LABEL or "Slot %d", index))
            slotCard.reward:SetText(L.VAULT_CURRENT_NONE or "Current --")
            slotCard.vaultValue:SetText("--")
            slotCard.goalValue:SetText("--")
            setProgressBar(slotCard.vaultBar, 0, r, g, b)
            setProgressBar(slotCard.goalBar, 0, GOAL_BAR_COLOR[1], GOAL_BAR_COLOR[2], GOAL_BAR_COLOR[3])
        end
        return
    end

    local thresholds = type(row.thresholds) == "table" and row.thresholds or {}
    local maxThreshold = tonumber(thresholds[#thresholds]) or 0
    local completed = getDisplayedCompletedCount(row)
    local unlockRatio = maxThreshold > 0 and (completed / maxThreshold) or 0
    local goal = row.goal
    local noteText = row.note or (snapshot and snapshot.summary and snapshot.summary.headline) or ""
    local goalDisplayCount = math.max(0, tonumber(goal and goal.displayCount) or 0)
    local goalMax = tonumber(goal and goal.maxThreshold) or maxThreshold
    local goalRatio = goalMax > 0 and math.min(1, goalDisplayCount / goalMax) or 0

    card.title:SetText(row.label or (L.CONTENT_TITLE_FORMAT or "Vault"))
    if rowKey == "world" and row.sourceSummary and row.sourceSummary ~= "" then
        card.subtitle:SetText(row.sourceSummary)
    elseif row.advice and row.advice.bestLabel and row.advice.bestLabel ~= "" then
        card.subtitle:SetText(string.format(L.VAULT_TOP_CURRENT or "Top current: %s", row.advice.bestLabel))
    else
        card.subtitle:SetText(L.VAULT_NONE_TOP or "No top value recorded yet.")
    end

    card.breakpoints:SetText(string.format(L.VAULT_BREAKPOINTS or "Breakpoints: %s", table.concat(thresholds, " / ")))
    card.unlockValue:SetText(string.format("%d/%d", completed, maxThreshold))
    card.goalValue:SetText(
        (goal and goal.displayText)
        or (goal and string.format("%s/%d %s", goal.displayCountText or tostring(goalDisplayCount), goalMax, goal.label or (L.VAULT_GOAL_LABEL or "Max reward")))
        or "--"
    )
    setProgressBar(card.unlockBar, unlockRatio, r, g, b)
    setProgressBar(card.goalBar, goalRatio, GOAL_BAR_COLOR[1], GOAL_BAR_COLOR[2], GOAL_BAR_COLOR[3])
    setProgressBreakpoints(card.unlockBar, thresholds, maxThreshold)
    setProgressBreakpoints(card.goalBar, thresholds, maxThreshold)
    card.note:SetText(noteText)
    card.note:SetShown(noteText ~= "")

    for index, slotCard in ipairs(card.slotCards or {}) do
        local slot = row.slots and row.slots[index] or nil
        local goalSlot = goal and goal.slots and goal.slots[index] or nil
        local slotThreshold = tonumber(slot and slot.threshold) or 0
        local slotCount = slotThreshold > 0 and math.min(completed, slotThreshold) or 0
        local slotGoalThreshold = tonumber(goalSlot and goalSlot.threshold) or slotThreshold
        local slotGoalCount = math.max(0, tonumber(goalSlot and goalSlot.count) or 0)

        slotCard.title:SetText(string.format(L.VAULT_SLOT_LABEL or "Slot %d", index))

        if slot and tonumber(slot.rewardItemLevel) and tonumber(slot.rewardItemLevel) > 0 then
            slotCard.reward:SetText(string.format(L.VAULT_CURRENT_REWARD or "Current %d ilvl", tonumber(slot.rewardItemLevel)))
        elseif slot and slot.rewardLink then
            slotCard.reward:SetText(L.VAULT_CURRENT_UNKNOWN or "Current ?")
        else
            slotCard.reward:SetText(L.VAULT_CURRENT_NONE or "Current --")
        end

        if slotThreshold > 0 then
            slotCard.vaultValue:SetText(string.format("%d/%d", slotCount, slotThreshold))
        else
            slotCard.vaultValue:SetText("--")
        end

        if goalSlot then
            slotCard.goalValue:SetText(goalSlot.displayText or goalSlot.countText or string.format("%d/%d", slotGoalCount, slotGoalThreshold))
        else
            slotCard.goalValue:SetText("--")
        end

        setProgressBar(slotCard.vaultBar, slotThreshold > 0 and (slotCount / slotThreshold) or 0, r, g, b)
        setProgressBar(slotCard.goalBar, slotGoalThreshold > 0 and (slotGoalCount / slotGoalThreshold) or 0, GOAL_BAR_COLOR[1], GOAL_BAR_COLOR[2], GOAL_BAR_COLOR[3])
    end
end
