local addonName = "WDD"

-- -- All specializations
-- local specializations = {
-- 	"Blood Death Knight",
-- 	"Frost Death Knight",
-- 	"Unholy Death Knight",
-- 	"Brewmaster Monk",
-- 	"Windwalker Monk",
-- 	"Mistweaver Monk",
-- 	"Arcane Mage",
-- 	"Fire Mage",
-- 	"Frost Mage",
-- 	"Affliction Warlock",
-- 	"Demonology Warlock",
-- 	"Destruction Warlock",
-- 	"Balance Druid",
-- 	"Feral Druid",
-- 	"Guardian Druid",
-- 	"Restoration Druid",
-- 	"Beast Mastery Hunter",
-- 	"Marksmanship Hunter",
-- 	"Survival Hunter",
-- 	"Discipline Priest",
-- 	"Holy Priest",
-- 	"Shadow Priest",
-- 	"Assassination Rogue",
-- 	"Outlaw Rogue",
-- 	"Subtlety Rogue",
-- 	"Elemental Shaman",
-- 	"Enhancement Shaman",
-- 	"Restoration Shaman",
-- 	"Havoc Demon Hunter",
-- 	"Vengeance Demon Hunter",
-- 	"Devourer Demon Hunter",
-- 	"Fury Warrior",
-- 	"Arms Warrior",
-- 	"Protection Warrior",
-- 	"Retribution Paladin",
-- 	"Protection Paladin",
-- 	"Holy Paladin",
-- 	"Devastation Evoker",
-- 	"Preservation Evoker",
-- 	"Augmentation Evoker"
-- }

-- Role mappings
local roleNames = {
    [0] = "",
    [1] = "Tank",
    [2] = "Healer",
    [3] = "DPS"
}

-- Role icons (WoW built-in)
local roleIcons = {
    [0] = "",
    [1] = "|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES.blp:16:16:0:0:64:64:0:19:22:41|t",  -- Tank
    [2] = "|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES.blp:16:16:0:0:64:64:20:39:1:20|t",  -- Healer
    [3] = "|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES.blp:16:16:0:0:64:64:20:39:22:41|t"  -- DPS
}

local roleColors = {
    [0] = {r=0.5, g=0.5, b=0.5},
    [1] = {r=0.78, g=0.61, b=0.43}, -- Tank (tan)
    [2] = {r=0.25, g=0.78, b=0.25}, -- Healer (green)
    [3] = {r=0.78, g=0.25, b=0.25}  -- DPS (red)
}

-- Format number as K (thousands), always rounded up to next thousand
local function FormatNumber(num)
    if num == 0 then return "0K" end
    return string.format("%.0fK", math.ceil(num / 1000))
end

-- Get color based on percentage
local function GetPercentageColor(percentage)
    if percentage >= 100 then
        return {r=1, g=0.5, b=0}     -- Orange
    elseif percentage >= 75 then
        return {r=0.64, g=0.21, b=0.93}  -- Purple
    elseif percentage >= 50 then
        return {r=0, g=0.44, b=0.87}     -- Blue
    elseif percentage >= 25 then
        return {r=0.25, g=0.78, b=0.25}  -- Green
    else
        return {r=0.5, g=0.5, b=0.5}     -- Gray
    end
end

-- Create a frame to register events
local frame = CreateFrame("Frame")
frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function(self, event, loadedAddon)
    if loadedAddon == addonName then
        self:UnregisterEvent("ADDON_LOADED")
        
        -- Check if data is loaded
        if not _G.WDD_Data or not _G.WDD_DungeonData then
            print("|cFFFF0000WDD:|r Data file not loaded!")
            return
        end

        local wddDataCount = 0
        for _ in pairs(_G.WDD_Data) do wddDataCount = wddDataCount + 1 end

        -- Compute dungeon keys and 10th-highest DPS per dungeon per role from player data.
        -- top10[key][role] = ascending list of up to 10 d values (role: 1=tank, 2=healer, 3=dps)
        local dungeonKeys = {}
        local top10 = {}

        for _, playerData in pairs(_G.WDD_Data) do
            for key, data in pairs(playerData) do
                if not top10[key] then
                    top10[key] = {}
                    dungeonKeys[#dungeonKeys + 1] = key
                end
                local d = data.d
                local r = data.r
                if d > 0 and r and r >= 1 and r <= 3 then
                    if not top10[key][r] then top10[key][r] = {} end
                    local top = top10[key][r]
                    local n = #top
                    if n < 10 or d > top[1] then
                        local pos = n + 1
                        for i = 1, n do
                            if d < top[i] then pos = i; break end
                        end
                        table.insert(top, pos, d)
                        if #top > 10 then table.remove(top, 1) end
                    end
                end
            end
        end

        table.sort(dungeonKeys)

        -- Build dungeon name → key mapping from DungeonData for LFG activity matching.
        -- Names are stripped of non-alpha characters to avoid apostrophe encoding mismatches.
        local function simplifyName(s)
            return s:lower():gsub("[^%a%s]", "")
        end
        local dungeonNameToKey = {}
        for _, dungeonInfo in ipairs(_G.WDD_DungeonData) do
            dungeonNameToKey[simplifyName(dungeonInfo.name)] = dungeonInfo.key
        end

        -- maxDps[key][role] = 10th highest value for that dungeon+role
        local maxDps = {}
        for _, key in ipairs(dungeonKeys) do
            maxDps[key] = {}
            for role = 1, 3 do
                local top = top10[key][role]
                maxDps[key][role] = (top and top[1]) or 100000
            end
        end

        print("|cFF00FF00WDD:|r " .. wddDataCount .. " characters loaded successfully.")

        -- Helper to add dungeon DPS lines to any tooltip for a given lookup key
        -- currentDungeonKey: optional key (e.g. "AA") to highlight in green
        local function AddDungeonDpsLines(tooltip, lookupKey, currentDungeonKey)
            local playerData = _G.WDD_Data[lookupKey]
            if not playerData then return end

            tooltip:AddLine(" ")
            tooltip:AddLine("Best Dungeon DPS:", 0.5, 0.8, 1, true)

            for _, dungeonKey in ipairs(dungeonKeys) do
                local data = playerData[dungeonKey]
                local isCurrent = dungeonKey == currentDungeonKey
                local keyR, keyG, keyB = isCurrent and 0 or 1, isCurrent and 1 or 1, isCurrent and 0 or 1

                if data and data.d > 0 then
                    local roleIcon = roleIcons[data.r]
                    local dpsText = FormatNumber(data.d)
                    local percentage = math.floor((data.d / maxDps[dungeonKey][data.r]) * 100)
                    local displayText = roleIcon .. " " .. dpsText .. " (" .. percentage .. "%)"
                    local percentageColor = GetPercentageColor(percentage)
                    tooltip:AddDoubleLine(dungeonKey, displayText, keyR, keyG, keyB, percentageColor.r, percentageColor.g, percentageColor.b)
                else
                    tooltip:AddDoubleLine(dungeonKey, "-", keyR, keyG, keyB, 0.5, 0.5, 0.5)
                end
            end

            tooltip:Show()
        end

        -- Hook into LFG search entry tooltip (shows leader's data)
        hooksecurefunc("LFGListUtil_SetSearchEntryTooltip", function(tooltip, resultID)
            local searchResultInfo = C_LFGList.GetSearchResultInfo(resultID)
            if not searchResultInfo or not searchResultInfo.leaderName then return end

            local dashPos = searchResultInfo.leaderName:find("-")
            if not dashPos then return end
            local name = searchResultInfo.leaderName:sub(1, dashPos - 1)
            local realm = searchResultInfo.leaderName:sub(dashPos + 1):gsub(" ", "")
            local lookupKey = name .. "-" .. realm .. "-eu"

            -- Match activityInfo.fullName against our dungeon name→key map
            local currentDungeonKey
            local activityID = searchResultInfo.activityIDs and searchResultInfo.activityIDs[1]
            if activityID then
                local activityInfo = C_LFGList.GetActivityInfoTable(activityID)
                if activityInfo and activityInfo.fullName then
                    local simplified = simplifyName(activityInfo.fullName)
                    for name, key in pairs(dungeonNameToKey) do
                        if simplified:find(name, 1, true) then
                            currentDungeonKey = key
                            break
                        end
                    end
                end
            end

            AddDungeonDpsLines(tooltip, lookupKey, currentDungeonKey)
        end)

        -- Hook applicant member rows in the ApplicationViewer (players applying to your group)
        local function HookApplicantButton(button)
            button:HookScript("OnEnter", function(self)
                local parent = self:GetParent()
                local applicantID = parent and parent.applicantID
                local memberIdx = self.memberIdx
                if not applicantID or not memberIdx then return end

                local fullName = C_LFGList.GetApplicantMemberInfo(applicantID, memberIdx)
                if not fullName then return end

                local dashPos = fullName:find("-")
                if not dashPos then return end
                local name = fullName:sub(1, dashPos - 1)
                local realm = fullName:sub(dashPos + 1):gsub(" ", "")
                local lookupKey = name .. "-" .. realm .. "-eu"

                GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
                GameTooltip:ClearLines()
                GameTooltip:AddLine(fullName, 1, 1, 1)
                AddDungeonDpsLines(GameTooltip, lookupKey)
            end)
            button:HookScript("OnLeave", function()
                GameTooltip:Hide()
            end)
        end

        if LFGListFrame and LFGListFrame.ApplicationViewer and LFGListFrame.ApplicationViewer.ScrollBox then
            LFGListFrame.ApplicationViewer.ScrollBox:RegisterCallback("OnViewFramesChanged", function()
                local frames = LFGListFrame.ApplicationViewer.ScrollBox:GetFrames()
                if not frames then return end
                for _, applicantFrame in ipairs(frames) do
                    if applicantFrame.Members then
                        for _, memberButton in ipairs(applicantFrame.Members) do
                            if not memberButton._wddHooked then
                                memberButton._wddHooked = true
                                HookApplicantButton(memberButton)
                            end
                        end
                    end
                end
            end, {})
        end

        -- Shared helper: append a single WDD summary line to any tooltip for a given lookupKey
        local function AddWDDSummaryLine(tooltip, lookupKey)
            local totalDungeons = #dungeonKeys
            local count = 0
            local totalPercent = 0

            local playerData = _G.WDD_Data[lookupKey]
            if playerData then
                for _, dungeonKey in ipairs(dungeonKeys) do
                    local entry = playerData[dungeonKey]
                    if entry and entry.d > 0 and entry.r and entry.r >= 1 and entry.r <= 3 then
                        local percentage = math.floor((entry.d / maxDps[dungeonKey][entry.r]) * 100)
                        totalPercent = totalPercent + percentage
                        count = count + 1
                    end
                end
            end

            local text, r, g, b
            if count == 0 then
                text = string.format("- (0/%d)", totalDungeons)
                r, g, b = 0.5, 0.5, 0.5
            else
                local avgPercent = math.floor(totalPercent / count)
                local color = GetPercentageColor(avgPercent)
                text = string.format("%d%% (%d/%d)", avgPercent, count, totalDungeons)
                r, g, b = color.r, color.g, color.b
            end
            tooltip:AddDoubleLine("WDD", text, 1, 0.5, 0, r, g, b)
        end

        -- Hook into normal unit tooltip (player mouseover in world/UI)
        TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Unit, function(tooltip, data)
            local _, unit = tooltip:GetUnit()
            if not unit or not UnitIsPlayer(unit) then return end

            local name, realm = UnitName(unit)
            if not name then return end
            if not realm or realm == "" then
                realm = GetRealmName():gsub(" ", "")
            else
                realm = realm:gsub(" ", "")
            end
            AddWDDSummaryLine(tooltip, name .. "-" .. realm .. "-eu")
        end)

        -- Hook guild member entries in the Communities/Guild frame
        local function SetupCommunitiesMemberHooks()
            if not CommunitiesMemberListEntryMixin then return end
            hooksecurefunc(CommunitiesMemberListEntryMixin, "OnEnter", function(self)
                local memberInfo = self.memberInfo
                if not memberInfo or not memberInfo.name then return end

                local fullName = memberInfo.name
                local name, realm
                local dashPos = fullName:find("-")
                if dashPos then
                    name = fullName:sub(1, dashPos - 1)
                    realm = fullName:sub(dashPos + 1):gsub(" ", "")
                else
                    name = fullName
                    realm = GetRealmName():gsub(" ", "")
                end

                AddWDDSummaryLine(GameTooltip, name .. "-" .. realm .. "-eu")
                GameTooltip:Show()
            end)
        end

        -- Blizzard_Communities loads lazily; hook it when ready
        local commFrame = CreateFrame("Frame")
        commFrame:RegisterEvent("ADDON_LOADED")
        commFrame:SetScript("OnEvent", function(self, event, addon)
            if addon == "Blizzard_Communities" then
                self:UnregisterEvent("ADDON_LOADED")
                SetupCommunitiesMemberHooks()
            end
        end)
        -- In case it's already loaded
        if C_AddOns.IsAddOnLoaded("Blizzard_Communities") then
            SetupCommunitiesMemberHooks()
        end

    end
end)
