UptimeTrackerDB = UptimeTrackerDB or { totalCombat = 0, totalActive = 0 }
local currentFightActive = 0
local currentFightStart = 0
local isCombat = false
local activeStartTime = 0
local ticker -- Variable to hold our ticker reference

-- 1. Create the UI Frame (Layout remains the same)
local f = CreateFrame("Frame", "UptimeTrackerFrame", UIParent, "BackdropTemplate")
f:SetSize(160, 95)
f:SetPoint("CENTER")
f:SetMovable(true)
f:EnableMouse(true)
f:RegisterForDrag("LeftButton")
f:SetScript("OnDragStart", f.StartMoving)
f:SetScript("OnDragStop", f.StopMovingOrSizing)

f:SetBackdrop({
    bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
    edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
    tile = true, tileSize = 16, edgeSize = 16,
    insets = { left = 4, right = 4, top = 4, bottom = 4 }
})
f:SetBackdropColor(0, 0, 0, 0.8)

local title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
title:SetPoint("TOP", 0, -10)
title:SetText("UPTIME TRACKER")

local lastFightText = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
lastFightText:SetPoint("TOPLEFT", 15, -30)
lastFightText:SetText("Last: 0.0%")

local avgText = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
avgText:SetPoint("TOPLEFT", 15, -45)
avgText:SetText("Avg: 0.0%")

local resetBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
resetBtn:SetSize(60, 22)
resetBtn:SetPoint("BOTTOM", 0, 10)
resetBtn:SetText("Reset")
resetBtn:SetScript("OnClick", function()
    UptimeTrackerDB = { totalCombat = 0, totalActive = 0 }
    lastFightText:SetText("Last: 0.0%")
    avgText:SetText("Avg: 0.0%")
    print("|cFF00FF00UptimeTracker:|r Data cleared.")
end)

-- 2. Logic Helpers
local function GetGCD()
    local spellCooldownInfo = C_Spell.GetSpellCooldown(61304)
    return spellCooldownInfo and spellCooldownInfo.startTime, spellCooldownInfo and spellCooldownInfo.duration
end

local function UpdateDisplay()
    local now = GetTime()
    local totalElapsedCombat = now - currentFightStart
    local sessionActive = currentFightActive
    if activeStartTime > 0 then
        sessionActive = sessionActive + (now - activeStartTime)
    end

    local livePct = (totalElapsedCombat > 0) and (sessionActive / totalElapsedCombat) * 100 or 0
    lastFightText:SetText(string.format("Live: %.1f%%", math.min(livePct, 100)))

    local overallCombat = UptimeTrackerDB.totalCombat + sessionActive
    local overallActive = UptimeTrackerDB.totalActive + sessionActive
    local overallAvg = (overallCombat > 0) and (overallActive / overallCombat) * 100 or 0
    avgText:SetText(string.format("Average: %.1f%%", math.min(overallAvg, 100)))
end

local function IsPlayerActive()
    local name = UnitName("player")
    
    -- 1. Check for standard Casts (Non-channeled)
    local casting = UnitCastingInfo("player")
    if casting then return true, "CASTING" end
    
    -- 2. Check for Channels (Includes Empowered spells)
    -- UnitChannelInfo returns info for both regular and empowered channels
    local channeling = UnitChannelInfo("player")
    if channeling then return true, "CHANNELING" end
    
    -- 3. Check for GCD
    -- We check spell ID 61304 (the internal GCD tracker)
    local gcdInfo = C_Spell.GetSpellCooldown(61304)
    if gcdInfo and gcdInfo.duration > 0 and (GetTime() < (gcdInfo.startTime + gcdInfo.duration)) then
        return true, "GCD"
    end
    
    return false, "IDLE"
end

-- 3. The Ticker Callback
local function OnTick()
    if not isCombat then return end
    
    UpdateDisplay();
end

-- 4. Event Handler
f:SetScript("OnEvent", function(self, event, ...)
    local now = GetTime()

    if event == "PLAYER_REGEN_DISABLED" then
        isCombat = true
        currentFightStart = now
        currentFightActive = 0
        activeStartTime = 0
        lastFightText:SetTextColor(0, 1, 0)
        
        -- Start the 100ms ticker
        if ticker then ticker:Cancel() end
        ticker = C_Timer.NewTicker(0.1, OnTick)

    elseif event == "PLAYER_REGEN_ENABLED" then
        isCombat = false
        if ticker then ticker:Cancel() end
        
        local duration = now - currentFightStart
        if activeStartTime > 0 then
            currentFightActive = currentFightActive + (now - activeStartTime)
            activeStartTime = 0
        end

        if duration > 1 then
            UptimeTrackerDB.totalCombat = UptimeTrackerDB.totalCombat + duration
            UptimeTrackerDB.totalActive = UptimeTrackerDB.totalActive + currentFightActive
            
            local lastPercent = (currentFightActive / duration) * 100
            lastFightText:SetTextColor(1, 1, 1)
            lastFightText:SetText(string.format("Last: %.1f%%", math.min(lastPercent, 100)))
            UpdateDisplay()
        end

    elseif isCombat and (event == "SPELL_UPDATE_COOLDOWN" or event == "UNIT_SPELLCAST_START") then
        local startTime, duration = GetGCD()
        
        if activeStartTime == 0 and duration and duration > 0 then
            activeStartTime = now
            local castTime = (event == "UNIT_SPELLCAST_START") and select(5, ...) or (duration * 1000)
            
            C_Timer.After(castTime / 1000, function()
                if activeStartTime > 0 then
                    currentFightActive = currentFightActive + (GetTime() - activeStartTime)
                    activeStartTime = 0
                end
            end)
        end
    elseif event == "PLAYER_LOGIN" then
        UpdateDisplay()
    end
end)

f:RegisterEvent("PLAYER_REGEN_DISABLED")
f:RegisterEvent("PLAYER_REGEN_ENABLED")
f:RegisterEvent("SPELL_UPDATE_COOLDOWN")
f:RegisterUnitEvent("UNIT_SPELLCAST_START", "player")
f:RegisterEvent("PLAYER_LOGIN")
