-- ===================== Achievement definitions =====================
-- All IDs verified on Wowhead (Merciless=8297, Vengeful=8298, Brutal=8300, Deadly=8301,
-- Pet Brawler=6595, Experienced=6596, Master=6597, Grand Master=6598, Legendary=6599).
-- nameKey points to a GOAL_NAME_* entry in Locales.lua, so achievement names
-- follow the same translation system (and fallback-to-English) as everything else.
BPS_GOALS = {
    { id="brawler_10",    nameKey="GOAL_NAME_BRAWLER_10",   achID=6595, threshold=10,   type="wins" },
    { id="brawler_50",    nameKey="GOAL_NAME_BRAWLER_50",   achID=6596, threshold=50,   type="wins" },
    { id="brawler_250",   nameKey="GOAL_NAME_BRAWLER_250",  achID=6597, threshold=250,  type="wins" },
    { id="brawler_1000",  nameKey="GOAL_NAME_BRAWLER_1000", achID=6598, threshold=1000, type="wins" },
    { id="brawler_5000",  nameKey="GOAL_NAME_BRAWLER_5000", achID=6599, threshold=5000, type="wins" },
    { id="merciless",     nameKey="GOAL_NAME_MERCILESS",    achID=8297, threshold=10,   type="rank25" },
    { id="vengeful",      nameKey="GOAL_NAME_VENGEFUL",     achID=8298, threshold=50,   type="rank25" },
    { id="brutal",        nameKey="GOAL_NAME_BRUTAL",       achID=8300, threshold=250,  type="rank25" },
    { id="deadly",        nameKey="GOAL_NAME_DEADLY",       achID=8301, threshold=1000, type="rank25" },
}

BPS_BIG_CELEBRATION_GOAL_ID = "brawler_5000"   -- fires the trumpet + big congrats

function BPS_GetGoalName(goal)
    if not goal or not goal.nameKey then return "" end
    local L = BPS_GetLocale()
    return L[goal.nameKey] or goal.nameKey
end

-- Returns the in-game progress to DISPLAY for a goal in the dropdown.
-- Always read from the real Blizzard achievement criteria (GetAchievementCriteriaInfo),
-- for every goal type. No manual/internal counting.
function BPS_GetRealProgress(goal)
    if not goal or not goal.achID then return 0 end
    local ok, _, _, _, quantity = pcall(GetAchievementCriteriaInfo, goal.achID, 1)
    if ok and quantity then
        return math.floor(quantity)
    end
    return 0
end

-- Returns whether the goal is completed. ALWAYS based on the real Blizzard
-- achievement (GetAchievementInfo), for every goal type, no matter how the
-- progress above is displayed.
function BPS_IsGoalCompletedByGame(goal)
    if not goal or not goal.achID then return false end
    -- GetAchievementInfo returns: id, name, points, completed, month, day, year, ...
    -- pcall prepends its own "ok" boolean, shifting every subsequent value by one.
    local ok, _, _, _, completed = pcall(GetAchievementInfo, goal.achID)
    return ok and completed == true
end

local function GetGoalIndex(id)
    for i, g in ipairs(BPS_GOALS) do
        if g.id == id then return i end
    end
    return nil
end

local function EnsureGoalDB()
    if not BattlePetStatisticsDB.currentGoalId then
        BattlePetStatisticsDB.currentGoalId = BPS_GOALS[1].id
    end
end

function BPS_GetCurrentGoal()
    EnsureGoalDB()
    local id = BattlePetStatisticsDB.currentGoalId
    if not id then return nil end
    local idx = GetGoalIndex(id)
    if not idx then return nil end
    return BPS_GOALS[idx]
end

function BPS_IsGoalCompleted(goalId)
    for _, g in ipairs(BPS_GOALS) do
        if g.id == goalId then
            return BPS_IsGoalCompletedByGame(g)
        end
    end
    return false
end

function BPS_AllGoalsCompleted()
    for _, g in ipairs(BPS_GOALS) do
        if not BPS_IsGoalCompletedByGame(g) then
            return false
        end
    end
    return true
end

function BPS_SetCurrentGoal(goalId)
    if BPS_IsGoalCompleted(goalId) then return end
    EnsureGoalDB()
    BattlePetStatisticsDB.currentGoalId = goalId
end

-- Auto-advance the current goal past any already-completed ones (can skip
-- several in a row, e.g. on a fresh install where the player already has
-- pre-existing achievement progress covering multiple thresholds at once).
function BPS_AutoAdvanceGoal()
    EnsureGoalDB()
    local goal = BPS_GetCurrentGoal()
    if not goal then return nil end
    if not BPS_IsGoalCompletedByGame(goal) then return nil end

    local lastCompleted = goal
    local idx = GetGoalIndex(goal.id)
    for i = idx + 1, #BPS_GOALS do
        if not BPS_IsGoalCompletedByGame(BPS_GOALS[i]) then
            BattlePetStatisticsDB.currentGoalId = BPS_GOALS[i].id
            return lastCompleted -- return the just-completed one for celebration check
        end
        lastCompleted = BPS_GOALS[i]
    end
    BattlePetStatisticsDB.currentGoalId = nil
    return lastCompleted
end

-- ===================== Pre-battle snapshot for win detection =====================
-- We snapshot the criteria quantity for EVERY general-win achievement before the
-- battle. After PET_BATTLE_OVER + a short delay we compare. If any count went up
-- the battle was a WIN; this is far more reliable than checking which pets died.

local snapshot = {}

local WIN_ACHIEVEMENT_IDS = { 6595, 6596, 6597, 6598, 6599 }

function BPS_SnapshotAchievements()
    wipe(snapshot)
    for _, achID in ipairs(WIN_ACHIEVEMENT_IDS) do
        local ok, _, _, _, quantity = pcall(GetAchievementCriteriaInfo, achID, 1)
        snapshot[achID] = (ok and quantity) or 0
    end
end

-- Returns true if a win was detected, false if loss, nil if couldn't determine.
function BPS_DetectWinFromAchievements()
    for _, achID in ipairs(WIN_ACHIEVEMENT_IDS) do
        local ok, _, _, _, quantity = pcall(GetAchievementCriteriaInfo, achID, 1)
        if ok and quantity and snapshot[achID] and quantity > snapshot[achID] then
            return true
        end
    end
    return nil -- no increase detected – caller should fall back to other methods
end
