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

local DATA = ns.Data or {}
local PVP_WEEKLY_QUEST_POOLS = DATA.PVP_WEEKLY_QUEST_POOLS or {}

local Util = ns.Util or {}
local getWeeklyResetInfo = Util.GetWeeklyResetInfo

local Quest = ns.Quest or {}
local buildQuestPoolState = Quest.BuildQuestPoolState
local isQuestCompleted = Quest.IsQuestCompleted
local isQuestActive = Quest.IsQuestActive
local getQuestObjectiveLines = Quest.GetQuestObjectiveLines
local isQuestTurnInReady = Quest.IsQuestTurnInReady
local getQuestObjectiveProgressText = Quest.GetQuestObjectiveProgressText
local getQuestTitle = Quest.GetQuestTitle

local function getPvpPoolLabel(pool)
    return L[pool.labelKey] or pool.fallbackLabel or ""
end

local function getPvpQuestRowLabel(pool, questInfo)
    local label = getPvpPoolLabel(pool)
    local questTitle = questInfo and getQuestTitle(questInfo.id, questInfo.fallbackTitle) or nil
    if questTitle and questTitle ~= "" and questTitle ~= label then
        return string.format("%s - %s", label, questTitle)
    end

    return label
end

local function buildPvpQuestEntry(pool, questInfo, status, key)
    local label = getPvpQuestRowLabel(pool, questInfo)
    local questTitle = questInfo and getQuestTitle(questInfo.id, questInfo.fallbackTitle) or label
    local questID = questInfo and questInfo.id or nil

    if status == "complete" then
        return {
            key = key,
            label = label,
            text = L.STATUS_DONE or "Done",
            status = "complete",
            seen = true,
            completed = true,
            questID = questID,
            tooltipTitle = questTitle,
            tooltipLines = { L.PVP_WEEKLY_DONE_TOOLTIP or "Already completed this week." },
        }
    end

    local lines = getQuestObjectiveLines(questID)
    local isTurnInReady = isQuestTurnInReady(questID)
    if #lines == 0 then
        lines[#lines + 1] = isTurnInReady
            and (L.PVP_WEEKLY_TURNIN_TOOLTIP or "This quest is done and can now be turned in.")
            or (L.PVP_WEEKLY_ACTIVE_TOOLTIP or "This quest is active. Check the quest log for the current objective.")
    end

    return {
        key = key,
        label = label,
        text = isTurnInReady and (L.STATUS_TURNIN or "Turn in")
            or getQuestObjectiveProgressText(questID)
            or (L.STATUS_OPEN or "Accepted"),
        status = isTurnInReady and "turnin" or "open",
        seen = true,
        completed = false,
        questID = questID,
        turnInQuestID = isTurnInReady and questID or nil,
        tooltipTitle = questTitle,
        tooltipLines = lines,
    }
end

local function buildPvpQuestPoolStates(pool)
    local legacyEntry = buildQuestPoolState(pool)
    if type(pool) ~= "table" then
        return legacyEntry and { legacyEntry } or {}
    end

    local found = {}
    for _, questInfo in ipairs(pool.quests or {}) do
        if isQuestCompleted(questInfo.id) then
            found[#found + 1] = {
                questInfo = questInfo,
                status = "complete",
            }
        elseif isQuestActive(questInfo.id) then
            found[#found + 1] = {
                questInfo = questInfo,
                status = "active",
            }
        end
    end

    if #found <= 1 then
        return legacyEntry and { legacyEntry } or {}
    end

    local entries = {}
    local legacyQuestID = legacyEntry and tonumber(legacyEntry.questID) or nil
    local usedLegacyEntry = false

    for _, foundEntry in ipairs(found) do
        local questInfo = foundEntry.questInfo
        local questID = tonumber(questInfo and questInfo.id) or 0
        if legacyEntry and not usedLegacyEntry and legacyQuestID == questID then
            legacyEntry.label = getPvpQuestRowLabel(pool, questInfo)
            entries[#entries + 1] = legacyEntry
            usedLegacyEntry = true
        else
            entries[#entries + 1] = buildPvpQuestEntry(
                pool,
                questInfo,
                foundEntry.status,
                string.format("%s:%d", tostring(pool.key or "pvp"), questID)
            )
        end
    end

    return entries
end

function ns:BuildCurrentPvpWeeklyState()
    local entries = {}

    for _, pool in ipairs(PVP_WEEKLY_QUEST_POOLS) do
        for _, entry in ipairs(buildPvpQuestPoolStates(pool)) do
            entries[#entries + 1] = entry
        end
    end

    return entries
end

function ns:RefreshCurrentCharacterPvpWeeklyData()
    local record = self:RefreshCurrentCharacterRecord()
    self:ClearExpiredPvpWeeklyState(record)

    local entries = self:BuildCurrentPvpWeeklyState()
    if not entries then
        return nil
    end

    local _, weeklyResetAt = getWeeklyResetInfo()
    record.pvpWeekly = {
        resetAt = weeklyResetAt,
        entries = entries,
    }

    return entries
end

function ns:GetLivePvpWeeklyState(keyOrCharacter, fallbackEntries)
    local key = keyOrCharacter
    if type(keyOrCharacter) == "table" then
        key = keyOrCharacter.key
    end

    if self:IsCurrentCharacterKey(key) then
        local liveEntries = self:BuildCurrentPvpWeeklyState()
        if liveEntries then
            return liveEntries
        end
    end

    local storedEntries = self:GetStoredPvpWeeklyState(key)
    if storedEntries then
        return storedEntries
    end

    return fallbackEntries
end
