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

local UIData = ns.UIData or {}

local ProfessionCooldownView = {}
ns.UIProfessionCooldownView = ProfessionCooldownView

local function getTheme(helpers)
    return (helpers and helpers.THEME) or UIData.THEME or {}
end

local function getStatusColors(helpers)
    return (helpers and helpers.STATUS_COLORS) or UIData.STATUS_COLORS or {}
end

local function createProfessionConcentrationRow(parent, helpers)
    local THEME = getTheme(helpers)
    local createLabel = helpers and helpers.createLabel
    local createProgressBar = helpers and helpers.createProgressBar

    local row = CreateFrame("Frame", nil, parent)
    row:SetHeight(42)

    row.label = createLabel(row, "GameFontHighlightSmall", "LEFT")
    row.label:SetPoint("TOPLEFT", 0, 0)
    row.label:SetPoint("TOPRIGHT", -104, 0)
    row.label:SetTextColor(THEME.parchment[1], THEME.parchment[2], THEME.parchment[3], 1)

    row.value = createLabel(row, "GameFontNormalSmall", "RIGHT")
    row.value:SetPoint("RIGHT", 0, 0)
    row.value:SetPoint("CENTER", row.label, "CENTER", 0, 0)
    row.value:SetWidth(100)
    row.value:SetTextColor(THEME.gold[1], THEME.gold[2], THEME.gold[3], 1)

    row.bar = createProgressBar(row)
    row.bar:SetPoint("TOPLEFT", row.label, "BOTTOMLEFT", 0, -6)
    row.bar:SetPoint("TOPRIGHT", 0, 0)
    row.bar:SetHeight(12)

    row.hitbox = CreateFrame("Button", nil, row)
    row.hitbox:SetAllPoints()
    row.hitbox:SetScript("OnEnter", function()
        if row.tooltipTitle or (row.tooltipLines and #row.tooltipLines > 0) then
            GameTooltip:SetOwner(row.hitbox, "ANCHOR_CURSOR_RIGHT")
            if row.tooltipTitle and row.tooltipTitle ~= "" then
                GameTooltip:AddLine(row.tooltipTitle, 1, 0.82, 0.18, true)
            end
            for _, line in ipairs(row.tooltipLines or {}) do
                if type(line) == "string" and line ~= "" then
                    GameTooltip:AddLine(line, 0.92, 0.92, 0.92, true)
                end
            end
            GameTooltip:Show()
        end
    end)
    row.hitbox:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)

    return row
end

local function setProfessionConcentrationRow(row, data, helpers)
    if not row then
        return
    end

    if not data then
        row:Hide()
        return
    end

    local STATUS_COLORS = getStatusColors(helpers)
    local setProgressBar = helpers and helpers.setProgressBar

    row.label:SetText(data.label or "")
    row.value:SetText(data.value or "--")
    row.tooltipTitle = data.tooltipTitle
    row.tooltipLines = data.tooltipLines

    local ratio = tonumber(data.ratio) or 0
    local statusColor = STATUS_COLORS[data.status or "missing"] or STATUS_COLORS.missing
    local r = statusColor[1] or 0.42
    local g = statusColor[2] or 0.74
    local b = statusColor[3] or 0.88
    if data.status == "open" then
        r, g, b = 0.36, 0.68, 0.88
    elseif data.status == "complete" then
        r, g, b = STATUS_COLORS.complete[1], STATUS_COLORS.complete[2], STATUS_COLORS.complete[3]
    end
    setProgressBar(row.bar, ratio, r, g, b)
    row:Show()
end

function ProfessionCooldownView.CreateCard(parent, helpers)
    helpers = helpers or {}
    local THEME = getTheme(helpers)
    local createSectionFrame = helpers.createSectionFrame
    local createLabel = helpers.createLabel
    local createWeeklyStatusRow = helpers.createWeeklyStatusRow

    local card = createSectionFrame(parent, "card")
    card:Hide()

    card.summary1 = createLabel(card, "GameFontHighlightSmall", "LEFT")
    card.summary1:SetPoint("TOPLEFT", 14, -18)

    card.summary2 = createLabel(card, "GameFontHighlightSmall", "LEFT")
    card.summary2:SetPoint("LEFT", card.summary1, "RIGHT", 24, 0)

    card.summary3 = createLabel(card, "GameFontHighlightSmall", "LEFT")
    card.summary3:SetPoint("LEFT", card.summary2, "RIGHT", 24, 0)

    card.concentrationHeader = createLabel(card, "GameFontHighlightSmall", "LEFT")
    card.concentrationHeader:SetPoint("TOPLEFT", card.summary1, "BOTTOMLEFT", 0, -18)
    card.concentrationHeader:SetText(L.PROFESSION_COOLDOWNS_CONCENTRATION or "Concentration")
    card.concentrationHeader:SetTextColor(THEME.gold[1], THEME.gold[2], THEME.gold[3], 1)

    card.concentrationRows = {}
    for index = 1, 2 do
        local row = createProfessionConcentrationRow(card, helpers)
        if index == 1 then
            row:SetPoint("TOPLEFT", card.concentrationHeader, "BOTTOMLEFT", 0, -10)
            row:SetPoint("TOPRIGHT", -14, 0)
        else
            row:SetPoint("TOPLEFT", card.concentrationRows[index - 1], "BOTTOMLEFT", 0, -10)
            row:SetPoint("TOPRIGHT", -14, 0)
        end
        row:Hide()
        card.concentrationRows[index] = row
    end

    card.cooldownHeader = createLabel(card, "GameFontHighlightSmall", "LEFT")
    card.cooldownHeader:SetPoint("TOPLEFT", card.concentrationRows[2], "BOTTOMLEFT", 0, -16)
    card.cooldownHeader:SetText(L.PROFESSION_COOLDOWNS_COOLDOWNS or "Recipe cooldowns")
    card.cooldownHeader:SetTextColor(THEME.gold[1], THEME.gold[2], THEME.gold[3], 1)

    card.cooldownRows = {}
    for index = 1, 6 do
        local row = createWeeklyStatusRow(card)
        if index == 1 then
            row:SetPoint("TOPLEFT", card.cooldownHeader, "BOTTOMLEFT", 0, -8)
            row:SetPoint("TOPRIGHT", -14, 0)
        else
            row:SetPoint("TOPLEFT", card.cooldownRows[index - 1], "BOTTOMLEFT", 0, -8)
            row:SetPoint("TOPRIGHT", -14, 0)
        end
        row:Hide()
        card.cooldownRows[index] = row
    end

    return card
end

function ProfessionCooldownView.RefreshCard(ui, helpers)
    if not ui.frame or not ui.frame.professionCooldownCard then
        return
    end

    helpers = helpers or {}
    local setWeeklyStatusRow = helpers.setWeeklyStatusRow
    local formatLastSeen = helpers.formatLastSeen

    local card = ui.frame.professionCooldownCard
    local character = ns:GetSelectedCharacter()
    local view = ns.BuildProfessionCooldownView and ns:BuildProfessionCooldownView(character) or {}
    local summary = view.summary or {}
    local concentrationRows = view.concentrationRows or {}
    local cooldownRows = view.cooldownRows or {}

    card.summary1:SetText(string.format(
        "%s  %d/%d",
        L.PROFESSION_COOLDOWNS_CONCENTRATION or "Concentration",
        tonumber(summary.concentrationKnown) or 0,
        tonumber(summary.concentrationTotal) or 0
    ))
    card.summary2:SetText(string.format(
        "%s  %d/%d",
        L.PROFESSION_COOLDOWNS_PROGRESS or "Cooldowns",
        tonumber(summary.cooldownReady) or 0,
        tonumber(summary.cooldownTotal) or 0
    ))
    card.summary3:SetText(
        (tonumber(summary.updatedAt) or 0) > 0
            and string.format(L.HERO_SYNC or "Last sync %s", formatLastSeen(tonumber(summary.updatedAt) or 0))
            or ""
    )

    if #concentrationRows == 0 then
        concentrationRows = {
            {
                label = L.PROFESSION_COOLDOWNS_CONCENTRATION or "Concentration",
                value = "--",
                ratio = 0,
                status = "missing",
                tooltipTitle = L.PROFESSION_COOLDOWNS_CONCENTRATION or "Concentration",
                tooltipLines = {
                    L.PROFESSION_COOLDOWNS_OPEN_HINT or "Open a profession window on this character to update cooldowns and concentration.",
                },
            },
        }
    end

    card.concentrationHeader:SetText(L.PROFESSION_COOLDOWNS_CONCENTRATION or "Concentration")
    for index, rowFrame in ipairs(card.concentrationRows or {}) do
        setProfessionConcentrationRow(rowFrame, concentrationRows[index], helpers)
    end

    card.cooldownHeader:SetText(L.PROFESSION_COOLDOWNS_COOLDOWNS or "Recipe cooldowns")
    local rowLimit = #(card.cooldownRows or {})
    if #cooldownRows == 0 then
        cooldownRows = {
            {
                label = L.PROFESSION_COOLDOWNS_NO_COOLDOWNS or "No known recipe cooldowns",
                entry = {
                    status = "missing",
                    text = "--",
                    seen = false,
                    completed = false,
                    tooltipTitle = L.PROFESSION_COOLDOWNS_NO_COOLDOWNS or "No known recipe cooldowns",
                    tooltipLines = {
                        L.PROFESSION_COOLDOWNS_OPEN_HINT or "Open a profession window on this character to update cooldowns and concentration.",
                    },
                },
            },
        }
    elseif #cooldownRows > rowLimit and rowLimit > 0 then
        local hiddenCount = #cooldownRows - rowLimit + 1
        cooldownRows[rowLimit] = {
            label = string.format("+%d", hiddenCount),
            entry = {
                status = "pending",
                text = L.PROFESSION_COOLDOWNS_PROGRESS or "Cooldowns",
                hideStatusBadge = true,
                tooltipTitle = L.PROFESSION_COOLDOWNS_COOLDOWNS or "Recipe cooldowns",
                tooltipLines = {
                    string.format(L.PROFESSION_COOLDOWNS_MORE_ROWS or "%d more cooldown rows are stored for this character.", hiddenCount),
                },
            },
        }
    end

    for index, rowFrame in ipairs(card.cooldownRows or {}) do
        local rowData = cooldownRows[index]
        if rowData then
            setWeeklyStatusRow(rowFrame, rowData.entry, rowData.label)
        else
            rowFrame:Hide()
        end
    end
end
