local _, ns = ...

local function getCurrentRenownLevel(factionID)
    if not C_MajorFactions or type(C_MajorFactions.GetCurrentRenownLevel) ~= "function" then
        return 0
    end

    local ok, renownLevel = pcall(C_MajorFactions.GetCurrentRenownLevel, factionID)
    if ok and tonumber(renownLevel) then
        return tonumber(renownLevel)
    end

    return 0
end

local function getMajorFactionNameByID(factionID, fallbackName)
    if C_MajorFactions and type(C_MajorFactions.GetMajorFactionData) == "function" then
        local ok, data = pcall(C_MajorFactions.GetMajorFactionData, factionID)
        if ok and type(data) == "table" and type(data.name) == "string" and data.name ~= "" then
            return data.name
        end
    end

    if C_Reputation and type(C_Reputation.GetFactionDataByID) == "function" then
        local ok, data = pcall(C_Reputation.GetFactionDataByID, factionID)
        if ok and type(data) == "table" and type(data.name) == "string" and data.name ~= "" then
            return data.name
        end
    end

    return fallbackName or string.format("Faction %d", tonumber(factionID) or 0)
end

local function getSpellNameByID(spellID, fallbackName)
    if spellID and C_Spell and type(C_Spell.GetSpellName) == "function" then
        local ok, name = pcall(C_Spell.GetSpellName, spellID)
        if ok and type(name) == "string" and name ~= "" then
            return name
        end
    end

    if type(GetSpellInfo) == "function" then
        local ok, name = pcall(GetSpellInfo, spellID)
        if ok and type(name) == "string" and name ~= "" then
            return name
        end
    end

    return fallbackName
end

local function getMapNameByID(uiMapID)
    if not uiMapID or not C_Map or type(C_Map.GetMapInfo) ~= "function" then
        return nil
    end

    local ok, mapInfo = pcall(C_Map.GetMapInfo, uiMapID)
    if ok and type(mapInfo) == "table" and type(mapInfo.name) == "string" and mapInfo.name ~= "" then
        return mapInfo.name
    end

    return nil
end

local function getActivePreyMapName()
    if not C_QuestLog or type(C_QuestLog.GetActivePreyQuest) ~= "function" or type(GetQuestUiMapID) ~= "function" then
        return nil
    end

    local okQuest, activeQuestID = pcall(C_QuestLog.GetActivePreyQuest)
    if not okQuest or not activeQuestID then
        return nil
    end

    local okMap, uiMapID = pcall(GetQuestUiMapID, activeQuestID)
    if not okMap or not uiMapID then
        return nil
    end

    return getMapNameByID(uiMapID), activeQuestID
end

local function getCurrencyInfoByID(currencyID)
    if not currencyID or currencyID <= 0 then
        return nil
    end

    if C_CurrencyInfo and type(C_CurrencyInfo.GetCurrencyInfo) == "function" then
        local ok, info = pcall(C_CurrencyInfo.GetCurrencyInfo, currencyID)
        if ok and type(info) == "table" then
            return info
        end
    end

    if type(GetCurrencyInfo) == "function" then
        local ok, info = pcall(GetCurrencyInfo, currencyID)
        if ok and type(info) == "table" then
            return info
        end
    end

    return nil
end

local function getItemCountByID(itemID)
    if not itemID or itemID <= 0 then
        return 0
    end

    if C_Item and type(C_Item.GetItemCount) == "function" then
        local ok, count = pcall(C_Item.GetItemCount, itemID, false, false, false, false)
        if ok then
            return math.max(0, tonumber(count) or 0)
        end
    end

    if type(GetItemCount) == "function" then
        local ok, count = pcall(GetItemCount, itemID, false, false, false)
        if ok then
            return math.max(0, tonumber(count) or 0)
        end
    end

    return 0
end

local WoWApi = ns.WoWApi or {}
ns.WoWApi = WoWApi

WoWApi.GetCurrentRenownLevel = getCurrentRenownLevel
WoWApi.GetMajorFactionNameByID = getMajorFactionNameByID
WoWApi.GetSpellNameByID = getSpellNameByID
WoWApi.GetMapNameByID = getMapNameByID
WoWApi.GetActivePreyMapName = getActivePreyMapName
WoWApi.GetCurrencyInfoByID = getCurrencyInfoByID
WoWApi.GetItemCountByID = getItemCountByID
