-- GetBorderColor helper

local function GetBorderColor(db)
    if not db then return 0, 207/255, 1.0 end
    if db.borderUseClassColor then
        local cc = RAID_CLASS_COLORS and RAID_CLASS_COLORS[select(2, UnitClass("player"))]
        if cc then return cc.r, cc.g, cc.b end
    end
    local r = db.borderColorR or 0
    local g = db.borderColorG or (207/255)
    local b = db.borderColorB or 1.0
    return r, g, b
end

local addonName, ns = ...
local L = ns.L
local W = ns.Widgets

-- ============================================================================
-- BrightQoL – Combat Timer Display
-- Compact slot-style frame matching Movement Alert aesthetics.
-- ============================================================================

local SLOT_HEIGHT  = 30
local SLOT_ICON    = 22
local ICON_PATH    = "Interface\\Icons\\Ability_Warrior_BattleShout"

local inCombat           = false
local combatStartTime    = 0
local lastCombatDuration = 0

-- ---------------------------------------------------------------------------
-- Frame + children
-- ---------------------------------------------------------------------------
local timerFrame = CreateFrame("Frame", "BrightQoL_CombatTimerDisplay", UIParent, "BackdropTemplate")
timerFrame:SetSize(200, SLOT_HEIGHT)
timerFrame:SetPoint("CENTER", UIParent, "CENTER", 0, -200)
timerFrame:SetBackdrop({
    bgFile   = [[Interface\Buttons\WHITE8x8]],
    edgeFile = [[Interface\Buttons\WHITE8x8]],
    edgeSize = 1,
    insets   = { left = 1, right = 1, top = 1, bottom = 1 },
})
timerFrame:SetBackdropColor(0.05, 0.05, 0.08, 0.85)
do local _r,_g,_b = GetBorderColor(BrightQoL.combatTimer); timerFrame:SetBackdropBorderColor(_r,_g,_b, 0.5) end
timerFrame:Hide()

local slotIcon = timerFrame:CreateTexture(nil, "ARTWORK")
slotIcon:SetSize(SLOT_ICON, SLOT_ICON)
slotIcon:SetPoint("LEFT", timerFrame, "LEFT", 4, 0)
slotIcon:SetTexture(ICON_PATH)
slotIcon:SetTexCoord(0.08, 0.92, 0.08, 0.92)

local labelText = timerFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
labelText:SetPoint("TOPLEFT", timerFrame, "TOPLEFT", 4 + 22 + 5, -3)
labelText:SetTextColor(1, 0.6, 0.2, 1)
labelText:SetText("Combat Timer")

local timerText = timerFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
timerText:SetPoint("BOTTOMLEFT", timerFrame, "BOTTOMLEFT", 4 + 22 + 5, 3)
timerText:SetText("0:00")

-- ---------------------------------------------------------------------------
-- Helpers
-- ---------------------------------------------------------------------------
local cachedDb = nil
local function GetDB()
    if not cachedDb then cachedDb = BrightQoL and BrightQoL.combatTimer end
    return cachedDb
end
local function InvalidateDB() cachedDb = nil end

local function IsInstanceCheckPassed(db)
    if not db.instanceOnly then return true end
    local inInst, instType = IsInInstance()
    return inInst and instType ~= "none"
end

local function FormatTime(elapsed, db)
    local m = math.floor(elapsed / 60)
    local s = math.floor(elapsed % 60)
    if db and db.hidePrefix then
        return string.format("%d:%02d", m, s)
    elseif db and db.combatText then
        return db.combatText:gsub("{m}", m):gsub("{s}", string.format("%02d", s))
    end
    return string.format("%d:%02d", m, s)
end

-- ---------------------------------------------------------------------------
-- Apply backdrop / border — SetBackdrop(nil) for true removal
-- ---------------------------------------------------------------------------
local BRIGHT = "Interface\\AddOns\\BrightQoL\\Assets\\Fonts\\Bright.ttf"

local function ApplyVisuals(db)
    local wantBg  = db.showBackdrop ~= false
    local wantBrd = db.showBorder   ~= false
    if not wantBg and not wantBrd then
        timerFrame:SetBackdrop(nil)
    else
        timerFrame:SetBackdrop({
            bgFile   = wantBg  and [[Interface\Buttons\WHITE8x8]] or nil,
            edgeFile = wantBrd and [[Interface\Buttons\WHITE8x8]] or nil,
            edgeSize = wantBrd and 1 or 0,
            insets   = { left = 1, right = 1, top = 1, bottom = 1 },
        })
        if wantBg  then timerFrame:SetBackdropColor(0.05, 0.05, 0.08, 0.85) end
        if wantBrd then do local _r,_g,_b = GetBorderColor(BrightQoL.combatTimer); timerFrame:SetBackdropBorderColor(_r,_g,_b, 0.5) end end
    end
end

local function ApplyScale(db)
    local sh = db.slotHeight or 30
    local si = math.max(10, math.floor(sh * 0.73))
    local fs = math.max(8,  math.floor(sh * 0.37))
    timerFrame:SetHeight(sh)
    slotIcon:SetSize(si, si)
    labelText:SetFont(BRIGHT, fs, "")
    timerText:SetFont(BRIGHT, fs - 1, "")
    -- Reanchor texts vertically proportional to slot height
    labelText:ClearAllPoints()
    labelText:SetPoint("TOPLEFT", timerFrame, "TOPLEFT", 4 + 22 + 5, -3)
    timerText:ClearAllPoints()
    timerText:SetPoint("BOTTOMLEFT", timerFrame, "BOTTOMLEFT", 4 + 22 + 5, 3)
end

-- ---------------------------------------------------------------------------
-- UpdateDisplay
-- ---------------------------------------------------------------------------
function timerFrame:UpdateDisplay()
    local db = GetDB()
    if not db then return end

    if not db.enabled then
        timerFrame:Hide()
        return
    end

    -- Position (once per init)
    if not timerFrame.initialized then
        timerFrame:ClearAllPoints()
        local pt = db.point or "CENTER"
        timerFrame:SetPoint(pt, UIParent, pt, db.x or 0, db.y or -200)
        timerFrame.initialized = true
    end

    timerFrame:SetWidth(db.width or 200)
    timerFrame:EnableMouse(db.unlock)
    ApplyScale(db)
    ApplyVisuals(db)

    -- Visibility
    local shouldShow = db.unlock
        or inCombat
        or (db.stickyTimer and lastCombatDuration > 0 and IsInstanceCheckPassed(db))
    timerFrame:SetShown(shouldShow)
    if not shouldShow then return end

    -- Label / timer text positioning handled by ApplyScale; just hide label if hidePrefix
    if db.hidePrefix then
        labelText:Hide()
    else
        labelText:Show()
    end

    -- Timer value + colour
    local r, g, b = W.GetEffectiveColor(db, "colorR", "colorG", "colorB", "useClassColor")
    timerText:SetTextColor(r, g, b, 1)

    local elapsed
    if inCombat then
        elapsed = GetTime() - combatStartTime
    elseif db.stickyTimer and lastCombatDuration > 0 then
        elapsed = lastCombatDuration
    else
        elapsed = 0
    end
    timerText:SetText(FormatTime(elapsed, db))
end

-- ---------------------------------------------------------------------------
-- OnUpdate (1 Hz tick)
-- ---------------------------------------------------------------------------
local acc = 0
timerFrame:SetScript("OnUpdate", ns.PerfMonitor:Wrap("Combat Timer", function(self, elapsed)
    acc = acc + elapsed
    if acc >= 1 then
        acc = 0
        local db = GetDB()
        if inCombat or (db and db.unlock) or (db and db.stickyTimer and lastCombatDuration > 0 and IsInstanceCheckPassed(db)) then
            self:UpdateDisplay()
        end
    end
end))

-- ---------------------------------------------------------------------------
-- Events
-- ---------------------------------------------------------------------------
local loader = CreateFrame("Frame")
loader:RegisterEvent("PLAYER_LOGIN")
loader:RegisterEvent("PLAYER_REGEN_DISABLED")
loader:RegisterEvent("PLAYER_REGEN_ENABLED")

loader:SetScript("OnEvent", function(self, event)
    local db = GetDB()
    if not db then return end

    if event == "PLAYER_LOGIN" then
        InvalidateDB()
        W.MakeDraggable(timerFrame, { db = db })
        timerFrame.initialized = false
        timerFrame:UpdateDisplay()

        ns.SettingsIO:RegisterRefresh("combatTimer", function()
            InvalidateDB()
            timerFrame.initialized = false
            timerFrame:UpdateDisplay()
        end)

    elseif event == "PLAYER_REGEN_DISABLED" and db.enabled then
        if db.instanceOnly then
            local inInst, instType = IsInInstance()
            if not inInst or instType == "none" then return end
        end
        inCombat = true
        combatStartTime = GetTime()
        timerFrame:Show()
        timerFrame:UpdateDisplay()

    elseif event == "PLAYER_REGEN_ENABLED" then
        if inCombat then
            local duration = GetTime() - combatStartTime
            lastCombatDuration = duration

            if db.chatReport ~= false then
                local h = math.floor(duration / 3600)
                local m = math.floor((duration % 3600) / 60)
                local s = math.floor(duration % 60)
                local timeText
                if h > 0 then
                    timeText = string.format("%d:%02d:%02d hours", h, m, s)
                elseif m > 0 then
                    timeText = string.format("%d:%02d minutes", m, s)
                else
                    timeText = string.format("%d seconds", duration)
                end
                ns:Log(L["COMBATTIMER_CHAT_MSG"] .. " |cff00cfff" .. timeText .. "|r")
            end
        end

        inCombat = false
        if not db.unlock and (not db.stickyTimer or not IsInstanceCheckPassed(db)) then
            timerFrame:Hide()
        elseif db.stickyTimer and lastCombatDuration > 0 and IsInstanceCheckPassed(db) then
            timerFrame:UpdateDisplay()
        end
    end
end)

ns.CombatTimerDisplay = timerFrame

function timerFrame:RefreshSettings()
    InvalidateDB()
    timerFrame.initialized = false
    timerFrame:UpdateDisplay()
end
