AddonDiagnostics = AddonDiagnostics or {}
AddonDiagnostics.PerformanceHUD = {}
local PerformanceHUD = AddonDiagnostics.PerformanceHUD

local UPDATE_INTERVAL = 1.0
local REANCHOR_INTERVAL = 2.0
local statusFrame = nil
local fpsText = nil
local homeText = nil
local worldText = nil
local incidentBubble = nil
local incidentBubbleText = nil
local updateElapsed = 0
local reanchorElapsed = 0
local recording = false

local function RoundMetric(value)
    return math.floor((tonumber(value) or 0) + 0.5)
end

local function ApplyFPSColor(fps)
    if fps >= 55 then
        fpsText:SetTextColor(0.117647, 1.0, 0.0)
    else
        if fps >= 40 then
            fpsText:SetTextColor(1.0, 0.823529, 0.0)
        else
            fpsText:SetTextColor(1.0, 0.250980, 0.250980)
        end
    end
end

local function ApplyHomeLatencyColor(ms)
    if ms <= 45 then
        homeText:SetTextColor(0.117647, 1.0, 0.0)
    else
        if ms <= 85 then
            homeText:SetTextColor(1.0, 0.823529, 0.0)
        else
            homeText:SetTextColor(1.0, 0.250980, 0.250980)
        end
    end
end

local function ApplyWorldLatencyColor(ms)
    if ms <= 55 then
        worldText:SetTextColor(0.117647, 1.0, 0.0)
    else
        if ms <= 110 then
            worldText:SetTextColor(1.0, 0.823529, 0.0)
        else
            worldText:SetTextColor(1.0, 0.250980, 0.250980)
        end
    end
end

local function GetObjectiveTrackerFrame()
    if _G then
        return _G.ObjectiveTrackerFrame or _G.ObjectiveTracker or _G.WatchFrame
    end
    return nil
end

local function GetObjectiveTrackerWidth(tracker)
    local width = 0
    if tracker and tracker.GetWidth then
        width = tonumber(tracker:GetWidth()) or 0
    end
    if width < 180 then
        width = 250
    end
    width = math.floor(width)
    if width < 240 then
        width = 240
    end
    if width > 300 then
        width = 300
    end
    return width
end

local function PositionStatusFrame()
    if not statusFrame then
        return
    end

    local tracker = GetObjectiveTrackerFrame()
    if tracker and tracker.GetObjectType then
        statusFrame:ClearAllPoints()
        statusFrame:SetWidth(GetObjectiveTrackerWidth(tracker))
        statusFrame:SetPoint("BOTTOMLEFT", tracker, "TOPLEFT", 0, -1)
        return
    end

    statusFrame:ClearAllPoints()
    statusFrame:SetWidth(250)
    statusFrame:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", -42, -245)
end

local function RefreshAddonUsageDisplay()
    local controller = AddonDiagnostics.SessionController
    if controller and type(controller.RefreshAddonUsage) == "function" then
        controller:RefreshAddonUsage()
    end
end

local function UpdateMetrics()
    local fps = 0
    if type(GetFramerate) == "function" then
        fps = tonumber(GetFramerate()) or 0
    end

    local homeLatency = 0
    local worldLatency = 0
    if type(GetNetStats) == "function" then
        local _, _, latencyHome, latencyWorld = GetNetStats()
        homeLatency = tonumber(latencyHome) or 0
        worldLatency = tonumber(latencyWorld) or 0
    end

    local displayFPS = RoundMetric(fps)
    local displayHome = RoundMetric(homeLatency)
    local displayWorld = RoundMetric(worldLatency)

    fpsText:SetText(string.format("FPS %d", displayFPS))
    homeText:SetText(string.format("H %d ms", displayHome))
    worldText:SetText(string.format("W %d ms", displayWorld))

    ApplyFPSColor(displayFPS)
    ApplyHomeLatencyColor(displayHome)
    ApplyWorldLatencyColor(displayWorld)
    RefreshAddonUsageDisplay()
end

local function OnUpdate(self, elapsed)
    local elapsedValue = tonumber(elapsed) or 0
    updateElapsed = updateElapsed + elapsedValue
    reanchorElapsed = reanchorElapsed + elapsedValue

    if reanchorElapsed >= REANCHOR_INTERVAL then
        reanchorElapsed = 0
        PositionStatusFrame()
    end

    if updateElapsed >= UPDATE_INTERVAL then
        updateElapsed = 0
        UpdateMetrics()
    end
end

local function OnStatusFrameClick()
    if AddonDiagnostics_ToggleWindow then
        AddonDiagnostics_ToggleWindow()
    end
end

local function RefreshIncidentBubbleDisplay()
    if not incidentBubble or not incidentBubbleText then return end
    local store = AddonDiagnostics.IncidentStore
    local unread = 0
    if store and type(store.GetUnreadCount) == "function" then
        unread = math.max(0, tonumber(store:GetUnreadCount()) or 0)
    end
    if unread <= 0 then
        incidentBubble:Hide()
        return
    end
    incidentBubbleText:SetText(string.format("! %d", unread))
    incidentBubble:Show()
end

local function OnIncidentBubbleEnter(self)
    local store = AddonDiagnostics.IncidentStore
    local unread = 0
    if store and type(store.GetUnreadCount) == "function" then
        unread = math.max(0, tonumber(store:GetUnreadCount()) or 0)
    end
    GameTooltip:SetOwner(self, "ANCHOR_LEFT")
    GameTooltip:SetText(string.format("Addon Diagnostics captured %d problem%s. Click to review.", unread, unread == 1 and "" or "s"))
    GameTooltip:Show()
end

local function OnIncidentBubbleLeave()
    GameTooltip:Hide()
end

local function OnIncidentBubbleClick()
    local preview = AddonDiagnostics.ReportPreview
    if preview and type(preview.ShowLatestIncident) == "function" then
        preview:ShowLatestIncident()
        return
    end
    if AddonDiagnostics_ToggleWindow then AddonDiagnostics_ToggleWindow() end
end

local function CreateStatusFrame()
    statusFrame = CreateFrame("Button", "AddonDiagnosticsPerformanceHUD", UIParent)
    statusFrame:SetSize(250, 18)
    statusFrame:SetFrameStrata("MEDIUM")
    statusFrame:SetClampedToScreen(true)
    statusFrame:EnableMouse(true)
    statusFrame:RegisterForClicks("LeftButtonUp")

    local background = statusFrame:CreateTexture(nil, "BACKGROUND")
    background:SetAllPoints(statusFrame)
    background:SetColorTexture(0.20, 0.16, 0.28, 0.70)

    local topLine = statusFrame:CreateTexture(nil, "ARTWORK")
    topLine:SetPoint("TOPLEFT", statusFrame, "TOPLEFT", 0, 0)
    topLine:SetPoint("TOPRIGHT", statusFrame, "TOPRIGHT", 0, 0)
    topLine:SetHeight(1)
    topLine:SetColorTexture(0.84, 0.65, 0.10, 0.95)

    local bottomLine = statusFrame:CreateTexture(nil, "ARTWORK")
    bottomLine:SetPoint("BOTTOMLEFT", statusFrame, "BOTTOMLEFT", 0, 0)
    bottomLine:SetPoint("BOTTOMRIGHT", statusFrame, "BOTTOMRIGHT", 0, 0)
    bottomLine:SetHeight(1)
    bottomLine:SetColorTexture(0.84, 0.65, 0.10, 0.95)

    local hover = statusFrame:CreateTexture(nil, "HIGHLIGHT")
    hover:SetAllPoints(statusFrame)
    hover:SetColorTexture(1.0, 0.9, 0.35, 0.08)

    fpsText = statusFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    fpsText:SetPoint("LEFT", statusFrame, "LEFT", 6, 0)
    fpsText:SetWidth(76)
    fpsText:SetJustifyH("LEFT")

    homeText = statusFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    homeText:SetPoint("CENTER", statusFrame, "CENTER", 0, 0)
    homeText:SetWidth(76)
    homeText:SetJustifyH("CENTER")

    worldText = statusFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    worldText:SetPoint("RIGHT", statusFrame, "RIGHT", -6, 0)
    worldText:SetWidth(80)
    worldText:SetJustifyH("RIGHT")

    incidentBubble = CreateFrame("Button", "AddonDiagnosticsIncidentBubble", UIParent)
    incidentBubble:SetSize(42, 18)
    incidentBubble:SetPoint("RIGHT", statusFrame, "LEFT", -4, 0)
    incidentBubble:SetFrameStrata("MEDIUM")
    incidentBubble:RegisterForClicks("LeftButtonUp")
    local bubbleBackground = incidentBubble:CreateTexture(nil, "BACKGROUND")
    bubbleBackground:SetAllPoints(incidentBubble)
    bubbleBackground:SetColorTexture(0.28, 0.08, 0.08, 0.92)
    local bubbleBorder = incidentBubble:CreateTexture(nil, "BORDER")
    bubbleBorder:SetPoint("TOPLEFT", incidentBubble, "TOPLEFT", 0, 0)
    bubbleBorder:SetPoint("BOTTOMRIGHT", incidentBubble, "BOTTOMRIGHT", 0, 0)
    bubbleBorder:SetColorTexture(0.84, 0.65, 0.10, 0.32)
    incidentBubbleText = incidentBubble:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    incidentBubbleText:SetPoint("CENTER", incidentBubble, "CENTER", 0, 0)
    incidentBubbleText:SetTextColor(1.0, 0.35, 0.25)
    incidentBubble:SetScript("OnEnter", OnIncidentBubbleEnter)
    incidentBubble:SetScript("OnLeave", OnIncidentBubbleLeave)
    incidentBubble:SetScript("OnClick", OnIncidentBubbleClick)
    incidentBubble:Hide()

    statusFrame:SetScript("OnUpdate", OnUpdate)
    statusFrame:SetScript("OnClick", OnStatusFrameClick)

    PositionStatusFrame()
    UpdateMetrics()
    RefreshIncidentBubbleDisplay()
    statusFrame:Show()
end

function PerformanceHUD:SetRecording(isRecording)
    recording = isRecording == true
end

function PerformanceHUD:RefreshIncidentBubble()
    RefreshIncidentBubbleDisplay()
end

function PerformanceHUD:GetFrame()
    return statusFrame
end

CreateStatusFrame()
