local AddonName, Kz = ...
Kz.WQ = {}

-- =========================================================================
-- 1. FONCTIONS UTILITAIRES SÉCURISÉES
-- =========================================================================

-- Récupération intelligente de l'icône de gauche
local function GetQuestMapIcon(questID)
    local tagInfo = C_QuestLog.GetQuestTagInfo(questID)
    if tagInfo then
        if tagInfo.worldQuestType == Enum.QuestTagType.PetBattle then return "worldquest-icon-petbattle", true
        elseif tagInfo.worldQuestType == Enum.QuestTagType.Dungeon then return "worldquest-icon-dungeon", true
        elseif tagInfo.worldQuestType == Enum.QuestTagType.Raid then return "worldquest-icon-raid", true
        elseif tagInfo.worldQuestType == Enum.QuestTagType.Profession then return "worldquest-icon-profession", true
        elseif tagInfo.worldQuestType == Enum.QuestTagType.PvP then return "worldquest-icon-pvp", true end
        if tagInfo.quality == Enum.WorldQuestQuality.Rare then return "worldquest-icon-rare", true
        elseif tagInfo.quality == Enum.WorldQuestQuality.Epic then return "worldquest-icon-boss", true end
    end
    return "Interface\\Icons\\Achievement_Quests_Completed_01", false
end

-- Fonction de récompenses BLINDÉE
local function GetAllQuestRewards(questID)
    local rewards = {}
    
    if C_TaskQuest.RequestPreloadRewardData then C_TaskQuest.RequestPreloadRewardData(questID) end
    
    -- 1. OR (GOLD)
    local GetMoneyFunc = _G.GetQuestLogRewardMoney or C_QuestLog.GetQuestLogRewardMoney or C_QuestLog.GetQuestRewardMoney
    if GetMoneyFunc then
        local money = GetMoneyFunc(questID)
        if money and money > 0 then 
            table.insert(rewards, {texture = "Interface\\Icons\\INV_Misc_Coin_02", type = "money", qty = money})
        end
    end
    
    -- 2. OBJETS (ITEMS) - Scan forcé 1-6
    local GetInfoFunc = _G.GetQuestLogRewardInfo or C_QuestLog.GetQuestLogRewardInfo or C_QuestLog.GetQuestRewardInfo
    if GetInfoFunc then
        for i = 1, 6 do
            local name, texture, quantity, quality, isUsable, itemID = GetInfoFunc(i, questID)
            if name then
                if not texture and itemID then texture = C_Item.GetItemIconByID(itemID) end
                table.insert(rewards, {texture = texture, type = "item", id = itemID, qty = quantity, quality = quality})
            end
        end
    end
    
    -- 3. MONNAIES (CURRENCIES)
    if C_QuestLog.GetQuestRewardCurrencies then
        local currencyList = C_QuestLog.GetQuestRewardCurrencies(questID)
        if currencyList then
            for _, cData in ipairs(currencyList) do
                local tex = cData.texture
                if not tex and cData.currencyID then
                    local info = C_CurrencyInfo.GetCurrencyInfo(cData.currencyID)
                    if info then tex = info.iconFileID end
                end
                table.insert(rewards, {
                    texture = tex, 
                    type = "currency", 
                    id = cData.currencyID, 
                    qty = cData.totalRewardAmount or cData.baseRewardAmount
                })
            end
        end
    else
        -- Fallback ancien API
        local GetNumCur = _G.GetNumQuestLogRewardCurrencies or C_QuestLog.GetNumQuestLogRewardCurrencies
        local GetInfoCur = _G.GetQuestLogRewardCurrencyInfo or C_QuestLog.GetQuestLogRewardCurrencyInfo
        if GetNumCur and GetInfoCur then
            local num = GetNumCur(questID) or 0
            for i=1, num do
                local name, texture, quantity, currencyID = GetInfoCur(i, questID)
                if texture then table.insert(rewards, {texture = texture, type = "currency", id = currencyID, qty = quantity}) end
            end
        end
    end

    -- 4. FALLBACK
    if #rewards == 0 then
         table.insert(rewards, {texture = "Interface\\Icons\\Achievement_Reputation_01", type = "other", desc = "Réputation / XP"})
    end
    
    return rewards
end

-- Scanner Récursif
local function GetAllSubMaps(parentMapID, collectedMaps)
    local children = C_Map.GetMapChildrenInfo(parentMapID, nil, true) 
    if children then
        for _, mapInfo in ipairs(children) do
            if not collectedMaps[mapInfo.mapID] and mapInfo.mapType ~= Enum.UIMapType.Continent then
                collectedMaps[mapInfo.mapID] = mapInfo
                GetAllSubMaps(mapInfo.mapID, collectedMaps)
            end
        end
    end
end


-- =========================================================================
-- 2. INITIALISATION
-- =========================================================================
function Kz.WQ.Init(parent)
    local scroll = CreateFrame("ScrollFrame", nil, parent, "UIPanelScrollFrameTemplate")
    scroll:SetPoint("TOPLEFT", 50, -40); scroll:SetPoint("BOTTOMRIGHT", -50, 40)
    
    local content = CreateFrame("Frame", nil, scroll)
    content:SetSize(1, 1)
    scroll:SetScrollChild(content)
    
    Kz.UI.Views.WQ = scroll
    Kz.UI.Views.WQContent = content
    
    local title = scroll:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    title:SetPoint("BOTTOMLEFT", scroll, "TOPLEFT", 0, 10)
    title:SetText("EXPÉDITIONS")
    Kz.UI.Views.WQ.Title = title
    
    Kz.UI.WQGroups = {} 
    
    scroll:RegisterEvent("QUEST_LOG_UPDATE")
    scroll:RegisterEvent("TASK_PROGRESS_UPDATE")
    scroll:RegisterEvent("QUEST_DATA_LOAD_RESULT") 
    scroll:SetScript("OnEvent", function() if Kz.UI.Views.WQ:IsShown() then Kz.WQ.Update() end end)
    
    scroll:Hide()
end


-- =========================================================================
-- 3. MISE À JOUR
-- =========================================================================
function Kz.WQ.Update()
    if not Kz.UI.Views.WQ:IsShown() then return end
    
    local V = Kz.UI.Views.WQContent
    V:SetWidth(Kz.UI.Views.WQ:GetWidth())
    
    if Kz.UI.WQGroups then for _, g in pairs(Kz.UI.WQGroups) do g:Hide() end end
    
    local currentMapID = C_Map.GetBestMapForUnit("player")
    if not currentMapID then return end
    local mapInfo = C_Map.GetMapInfo(currentMapID)
    while mapInfo and mapInfo.mapType and mapInfo.mapType > 2 do 
        currentMapID = mapInfo.parentMapID; if not currentMapID then break end; mapInfo = C_Map.GetMapInfo(currentMapID)
    end
    if not mapInfo then return end
    
    local allMaps = {}
    GetAllSubMaps(currentMapID, allMaps)
    
    local sortedZones = {}
    for _, info in pairs(allMaps) do table.insert(sortedZones, info) end
    table.sort(sortedZones, function(a,b) return a.name < b.name end)
    
    local seenQuests = {} -- Anti-doublons
    local yOffset = 0
    local groupIndex = 0
    
    for _, zone in ipairs(sortedZones) do
        local tasks = C_TaskQuest.GetQuestsOnMap(zone.mapID)
        local activeWQs = {}
        
        if tasks then
            for _, qInfo in ipairs(tasks) do
                local qID = qInfo.questID or qInfo.questId
                
                if not seenQuests[qID] then
                    local timeLeftSec = C_TaskQuest.GetQuestTimeLeftSeconds(qID)
                    local timeLeftMin = 0
                    local hasTime = false
                    if timeLeftSec then 
                        timeLeftMin = math.floor(timeLeftSec / 60)
                        hasTime = (timeLeftMin > 0)
                    end
                    
                    seenQuests[qID] = true
                    table.insert(activeWQs, { id = qID, time = timeLeftMin, hasTime = hasTime })
                    
                    if C_TaskQuest.RequestPreloadRewardData then C_TaskQuest.RequestPreloadRewardData(qID) end
                end
            end
        end
        
        if #activeWQs > 0 then
            groupIndex = groupIndex + 1
            local group = Kz.UI.WQGroups[groupIndex]
            if not group then
                group = CreateFrame("Frame", nil, V, "BackdropTemplate")
                Kz.SkinFrame(group)
                group.Title = group:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
                group.Title:SetPoint("TOPLEFT", 10, -10)
                group.lines = {}
                Kz.UI.WQGroups[groupIndex] = group
            end
            
            group:Show()
            group:SetPoint("TOPLEFT", 0, yOffset)
            group:SetPoint("RIGHT", 0, 0)
            group.Title:SetText(zone.name .. " (" .. #activeWQs .. ")")
            
            local lineY = -40
            for i, wq in ipairs(activeWQs) do
                local line = group.lines[i]
                
                -- CRÉATION INITIALE DE LA LIGNE (Une seule fois)
                if not line then
                    line = CreateFrame("Button", nil, group, "BackdropTemplate")
                    line:SetHeight(30)
                    line:SetBackdrop({bgFile = "Interface\\Buttons\\WHITE8x8"})
                    line:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
                    
                    -- Effet de survol (Highlight)
                    local hl = line:CreateTexture(nil, "HIGHLIGHT")
                    hl:SetAllPoints()
                    hl:SetColorTexture(1, 1, 1, 0.1)
                    line:SetHighlightTexture(hl)
                    
                    -- === GESTION DU CLIC GAUCHE & DROIT ===
                    line:RegisterForClicks("LeftButtonUp", "RightButtonUp")
                    line:SetScript("OnClick", function(self, button)
                        if not self.questID then return end
                        
                        if button == "LeftButton" then
                            -- CLIC GAUCHE : Suivi / SuperTrack
                            local isWatched = C_QuestLog.GetQuestWatchType(self.questID)
                            if isWatched then
                                C_QuestLog.RemoveQuestWatch(self.questID, Enum.QuestWatchType.Automatic)
                                C_SuperTrack.SetSuperTrackedQuestID(0)
                                print("|cff00ccff[Kazolitus]|r Suivi arrêté.")
                            else
                                C_QuestLog.AddQuestWatch(self.questID, Enum.QuestWatchType.Automatic)
                                C_SuperTrack.SetSuperTrackedQuestID(self.questID)
                                print("|cff00ccff[Kazolitus]|r Suivi activé.")
                            end
                        elseif button == "RightButton" then
                            -- CLIC DROIT : Ouvrir la carte
                            if not WorldMapFrame:IsShown() then ToggleWorldMap() end
                        end
                    end)
                    -- ======================================
                    
                    line.mapIcon = line:CreateTexture(nil, "ARTWORK")
                    line.mapIcon:SetSize(18, 18); line.mapIcon:SetPoint("LEFT", 8, 0)
                    
                    line.name = line:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
                    line.name:SetPoint("LEFT", line.mapIcon, "RIGHT", 10, 0)
                    line.name:SetWidth(270)
                    line.name:SetJustifyH("LEFT"); line.name:SetWordWrap(false)
                    
                    line.time = line:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
                    line.time:SetPoint("RIGHT", -10, 0)
                    
                    line.rewardsFrame = CreateFrame("Frame", nil, line)
                    line.rewardsFrame:SetPoint("LEFT", line.name, "RIGHT", 5, 0)
                    line.rewardsFrame:SetPoint("RIGHT", line.time, "LEFT", -5, 0)
                    line.rewardsFrame:SetHeight(24)
                    line.rewardsIcons = {}
                    
                    group.lines[i] = line
                end
                
                -- MISE À JOUR DES DONNÉES DE LA LIGNE
                line:SetPoint("TOPLEFT", 10, lineY)
                line:SetPoint("RIGHT", -10, 0)
                line:Show()
                
                -- IMPORTANT : On stocke l'ID pour le clic
                line.questID = wq.id
                
                local title = C_TaskQuest.GetQuestInfoByQuestID(wq.id)
                line.name:SetText(title or ("Activité " .. wq.id))
                
                if wq.hasTime then
                    local hrs = math.floor(wq.time / 60); local mins = wq.time % 60
                    local colorTime = (hrs < 2) and "|cffff0000" or "|cffffffff"
                    line.time:SetText(string.format("%s%dh %02dm|r", colorTime, hrs, mins))
                else
                    line.time:SetText("|cff00ff00Actif|r")
                end
                
                local iconVal, isAtlas = GetQuestMapIcon(wq.id)
                if isAtlas then
                    line.mapIcon:SetTexture(nil)
                    line.mapIcon:SetAtlas(iconVal)
                else
                    line.mapIcon:SetAtlas(nil)
                    line.mapIcon:SetTexture(iconVal)
                    line.mapIcon:SetTexCoord(0, 1, 0, 1)
                end
                
                local rewards = GetAllQuestRewards(wq.id)
                for ri, iconFrame in ipairs(line.rewardsIcons) do iconFrame:Hide() end
                
                local iconX = 0
                for ri = 1, math.min(#rewards, 5) do
                    local rData = rewards[ri]
                    local ib = line.rewardsIcons[ri]
                    if not ib then
                        ib = CreateFrame("Button", nil, line.rewardsFrame, "BackdropTemplate")
                        ib:SetSize(20, 20)
                        ib.tex = ib:CreateTexture(nil, "ARTWORK"); ib.tex:SetAllPoints()
                        Kz.SkinIcon(ib.tex)
                        ib:EnableMouse(true)
                        line.rewardsIcons[ri] = ib
                    end
                    ib:SetPoint("LEFT", iconX, 0)
                    ib.tex:SetTexture(rData.texture)
                    ib:Show()
                    
                    if rData.type == "item" and rData.quality and rData.quality > 1 then
                         local r,g,b = C_Item.GetItemQualityColor(rData.quality)
                         ib:SetBackdrop({edgeFile = "Interface\\Buttons\\WHITE8x8", edgeSize = 1})
                         ib:SetBackdropBorderColor(r, g, b, 1)
                    else
                         ib:SetBackdrop(nil)
                    end

                    ib:SetScript("OnEnter", function(self)
                        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
                        if rData.type == "item" then
                            GameTooltip:SetHyperlink("item:"..rData.id)
                        elseif rData.type == "currency" then
                            local info = C_CurrencyInfo.GetCurrencyInfo(rData.id)
                            if info then 
                                GameTooltip:AddLine(info.name, 1,1,1)
                                GameTooltip:AddLine("Quantité : " .. (rData.qty or 1), 1,1,1)
                            end
                        elseif rData.type == "money" then
                            GameTooltip:AddLine("Or", 1,1,1)
                            GameTooltip:AddLine(GetMoneyString(rData.qty), 1,1,1)
                        else
                            GameTooltip:AddLine(rData.desc or "Récompense", 1,1,1)
                        end
                        GameTooltip:Show()
                    end)
                    ib:SetScript("OnLeave", function() GameTooltip:Hide() end)
                    iconX = iconX + 22
                end
                
                lineY = lineY - 32
            end
            
            for j = #activeWQs + 1, #group.lines do group.lines[j]:Hide() end
            
            local groupHeight = math.abs(lineY) + 10
            group:SetHeight(groupHeight)
            yOffset = yOffset - groupHeight - 10
        end
    end
    
    V:SetHeight(math.abs(yOffset))
end