local PT = AhUI
if not PT then return end

local IP = PT.InfoPanel
local Tooltip = PT.Tooltip
local L = PT.L
if not IP then return end

IP:RegisterElementInfo("calltoarms", {
    name  = L["CALL_TO_ARMS"] or "Call to Arms",
    order = 60,
})

local CTA_ATLAS = "countdown-swords-glow"

local ROLE_ATLAS = {
    TANK   = "GM-icon-role-tank",
    HEALER = "GM-icon-role-healer",
    DPS    = "GM-icon-role-dps",
}

local ROLE_NAMES = {
    TANK   = TANK,
    HEALER = HEALER,
    DPS    = DAMAGER,
}

local ROLE_ORDER = { "TANK", "HEALER", "DPS" }

local function ScanCTA()
    if not GetNumRandomDungeons
        or not GetLFGRandomDungeonInfo
        or not GetLFGRoleShortageRewards
    then
        return nil
    end

    local roles = {}

    for i = 1, GetNumRandomDungeons() do
        local dungeonID = GetLFGRandomDungeonInfo(i)
        if dungeonID then
            for j = 1, LFG_ROLE_NUM_SHORTAGE_TYPES do
                local _, tank, heal, dps, itemCount =
                    GetLFGRoleShortageRewards(dungeonID, j)

                if itemCount and itemCount > 0 then
                    if tank then roles.TANK = true end
                    if heal then roles.HEALER = true end
                    if dps  then roles.DPS = true end
                end
            end
        end
    end

    return next(roles) and roles or nil
end

local function RolesKey(roles)
    if not roles then return nil end
    local t = {}
    for k in pairs(roles) do
        t[#t + 1] = k
    end
    table.sort(t)
    return table.concat(t, ",")
end

local function RolesText(roles)
    local t = {}
    for _, r in ipairs(ROLE_ORDER) do
        if roles[r] then
            t[#t + 1] = ROLE_NAMES[r]
        end
    end
    return table.concat(t, ", ")
end

IP:RegisterElementType("calltoarms", function(uid)
    local parent = (IP.frame and IP.frame.content) or UIParent
    local height = (IP.config and IP.config.appearance and IP.config.appearance.height) or 24

    local f = CreateFrame("Button", nil, parent)
    f:SetHeight(height)

    local iconSize = math.max(16, height - 2)
    local ctaSize  = math.floor(iconSize * 0.85)

    local icon = f:CreateTexture(nil, "ARTWORK")
    icon:SetSize(ctaSize, ctaSize)
    icon:SetPoint("LEFT", 0, 0)
    icon:SetAtlas(CTA_ATLAS)
    f.icon = icon

    local rolesTex = {}

    for i = 1, 3 do
        local t = f:CreateTexture(nil, "ARTWORK")
        t:SetSize(iconSize, iconSize)
        if i == 1 then
            t:SetPoint("LEFT", icon, "RIGHT", 0, 0)
        else
            t:SetPoint("LEFT", rolesTex[i - 1], "RIGHT", -8, 0)
        end
        t:Hide()
        rolesTex[i] = t
    end

    f.rolesTex = rolesTex
    f.lastRolesKey = nil
    f.lastRoles = nil

    f:RegisterForClicks("LeftButtonUp")
	f:SetScript("OnClick", function()
		if not PVEFrame or not PVEFrame:IsShown() then
			PVEFrame_ToggleFrame()
		end

		if PVEFrame and PVEFrame_ShowFrame then
			PVEFrame_ShowFrame("LFDParentFrame")
		end
	end)

    f:SetScript("OnEnter", function(self)
        if not Tooltip then return end

        Tooltip:Clear()
        Tooltip:AddLine(L["CALL_TO_ARMS"] or "Call to Arms", 14, 1, 1, 1)
        Tooltip:AddLine(" ")

        if self.lastRoles then
            Tooltip:AddLine(
                string.format(
                    L["CALL_TO_ARMS_ROLE"] or "Roles: %s",
                    RolesText(self.lastRoles)
                ),
                12, 0.9, 0.9, 0.9
            )
        else
            Tooltip:AddLine(
                L["CALL_TO_ARMS_DESC"] or "A bonus role is available in random dungeons",
                12, 0.9, 0.9, 0.9
            )
        end

        Tooltip:AddLine(" ")
        Tooltip:AddLine(
            L["CALL_TO_ARMS_HINT_LMB"] or "Left Click: Open Dungeon Finder",
            11, 0.7, 0.7, 0.7
        )

        Tooltip:ShowSmart(self)
    end)

    f:SetScript("OnLeave", function()
        if Tooltip then Tooltip:Clear() end
    end)

    function f:Update()
        local roles = ScanCTA()
        local key = RolesKey(roles)

        local baseWidth = self.icon:GetWidth()
        local w = baseWidth

        if not roles then
            self.lastRoles = nil
            self.lastRolesKey = nil

            for i = 1, 3 do
                self.rolesTex[i]:Hide()
            end

            self.icon:SetAlpha(0.4)
            self:SetWidth(baseWidth)
            self:Show()
            return
        end

        if key ~= self.lastRolesKey then
            print(
                string.format(
                    "|cff00ccffAhUI|r: " ..
                    (L["CALL_TO_ARMS_CHAT"] or "Call to Arms — roles available: %s"),
                    RolesText(roles)
                )
            )
        end

        self.lastRoles = roles
        self.lastRolesKey = key

        self.icon:SetAlpha(1)

        local idx = 1
        for _, r in ipairs(ROLE_ORDER) do
            if roles[r] and self.rolesTex[idx] then
                local tex = self.rolesTex[idx]
                tex:SetAtlas(ROLE_ATLAS[r])
                tex:Show()
                w = w + tex:GetWidth()
                idx = idx + 1
            end
        end

        for i = idx, 3 do
            self.rolesTex[i]:Hide()
        end

        self:SetWidth(w)
        self:Show()
    end

    f:Update()

    local element = {
        _type  = "CallToArms",
        id     = uid,
        frame  = f,
        Update = function()
            f:Update()
        end,
    }

    function element:ApplyHeight(h)
        local iconSize = math.max(16, h - 2)
        local ctaSize  = math.floor(iconSize * 0.85)
        f.icon:SetSize(ctaSize, ctaSize)
        for _, t in ipairs(f.rolesTex) do
            t:SetSize(iconSize, iconSize)
        end
    end

    if IP.EnableDrag then
        IP:EnableDrag(element)
    end

    return element
end)

local ev = CreateFrame("Frame")
ev:RegisterEvent("PLAYER_ENTERING_WORLD")
ev:RegisterEvent("LFG_UPDATE_RANDOM_INFO")

ev:SetScript("OnEvent", function()
    for _, element in pairs(IP.elements or {}) do
        if element and element._type == "CallToArms" and element.Update then
            element:Update()
        end
    end
end)

C_Timer.After(4, function()
    for _, element in pairs(IP.elements or {}) do
        if element and element._type == "CallToArms" and element.Update then
            element:Update()
        end
    end
end)