-------------------------
-- AiB Combat Timer Display
-------------------------

AiB = AiB or {}

local FONT_PATH = AiB.Config and AiB.Config.FONTS.PRIMARY or "Fonts\\ARIALN.TTF"

-- Helper: resolve effective color (class color or custom)
local function GetEffectiveColor(db, rKey, gKey, bKey, classColorKey)
    if db[classColorKey] then
        local _, className = UnitClass("player")
        local c = RAID_CLASS_COLORS and RAID_CLASS_COLORS[className]
        if c then return c.r, c.g, c.b end
    end
    return db[rKey] or 1, db[gKey] or 0.8, db[bKey] or 0
end

-- Helper: make a frame draggable
local function MakeDraggable(frame, db)
    frame:SetMovable(true)
    frame:RegisterForDrag("LeftButton")
    frame:SetScript("OnDragStart", function(self)
        if db.unlock then self:StartMoving() end
    end)
    frame:SetScript("OnDragStop", function(self)
        self:StopMovingOrSizing()
        local point, _, _, x, y = self:GetPoint()
        db.point = point
        db.x     = math.floor(x + 0.5)
        db.y     = math.floor(y + 0.5)
    end)
end

-- Helper: create a resize handle
local function CreateResizeHandle(frame, db, onResize)
    frame:SetResizable(true)

    local handle = CreateFrame("Frame", nil, frame)
    handle:SetSize(16, 16)
    handle:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0)
    handle:EnableMouse(true)

    local tex = handle:CreateTexture(nil, "OVERLAY")
    tex:SetAllPoints()
    tex:SetColorTexture(0.6, 0, 0, 0.9)

    handle:SetScript("OnMouseDown", function(self, button)
        if button == "LeftButton" then
            frame:StartSizing("BOTTOMRIGHT")
        end
    end)
    handle:SetScript("OnMouseUp", function()
        frame:StopMovingOrSizing()
        db.width  = math.floor(frame:GetWidth()  + 0.5)
        db.height = math.floor(frame:GetHeight() + 0.5)
        if onResize then onResize() end
    end)

    return handle
end

-- Helper: instance check
local function IsInstanceCheckPassed(db)
    if not db.instanceOnly then return true end
    local inInstance, instanceType = IsInInstance()
    return inInstance and instanceType ~= "none"
end

-------------------------
-- Timer Frame
-------------------------
local timerFrame = CreateFrame("Frame", "AiB_CombatTimerDisplay", UIParent, "BackdropTemplate")
timerFrame:SetSize(400, 100)
timerFrame:SetPoint("CENTER", UIParent, "CENTER", 0, -200)
timerFrame:Hide()

local timerText = timerFrame:CreateFontString(nil, "OVERLAY")
timerText:SetPoint("CENTER", timerFrame, "CENTER", 0, 0)
timerText:SetJustifyH("CENTER")
timerText:SetJustifyV("MIDDLE")
timerText:SetWordWrap(false)
timerText:SetFont(FONT_PATH, 32, "OUTLINE")
timerText:SetText("COMBAT: 0:00")

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

-- Cached DB reference
local cachedDb = nil
local function GetCachedDb()
    if not cachedDb then
        cachedDb = AiB.db and AiB.db.profile and AiB.db.profile.combatTimer
    end
    return cachedDb
end
local function InvalidateDbCache()
    cachedDb = nil
end

-- Update font size to fit frame
function timerFrame:UpdateTextSize()
    local db = AiB.db and AiB.db.profile and AiB.db.profile.combatTimer
    if not db then return end

    local fontPath    = AiB.Config and AiB.Config.FONTS.PRIMARY or FONT_PATH
    local frameWidth  = timerFrame:GetWidth()
    local frameHeight = timerFrame:GetHeight()

    local currentText = timerText:GetText() or "COMBAT: 0:00"
    local textLength  = string.len(currentText)

    local fontSizeFromHeight   = math.floor(frameHeight * 0.35)
    local usableWidth          = frameWidth * 0.50
    local estimatedCharWidth   = 0.55
    local maxFontSizeFromWidth = math.floor(usableWidth / (textLength * estimatedCharWidth))

    local scaledFontSize = math.min(fontSizeFromHeight, maxFontSizeFromWidth)
    scaledFontSize = math.max(10, math.min(72, scaledFontSize))

    if not timerText:SetFont(fontPath, scaledFontSize, "OUTLINE") then
        timerText:SetFont(FONT_PATH, scaledFontSize, "OUTLINE")
    end
end

-- Full display update
function timerFrame:UpdateDisplay()
    local db = AiB.db and AiB.db.profile and AiB.db.profile.combatTimer
    if not db then return end

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

    timerFrame:EnableMouse(db.unlock)

    if db.unlock then
        timerFrame:SetBackdrop({
            bgFile   = "Interface\\Tooltips\\UI-Tooltip-Background",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = true, tileSize = 16, edgeSize = 16,
            insets = { left = 4, right = 4, top = 4, bottom = 4 }
        })
        timerFrame:SetBackdropColor(0.1, 0.1, 0.1, 0.8)
        timerFrame:SetBackdropBorderColor(0.6, 0, 0, 1) -- AiB accent red
        if resizeHandle then resizeHandle:Show() end
        timerFrame:Show()

    elseif db.showBackground then
        timerFrame:SetBackdrop({ bgFile = "Interface\\Tooltips\\UI-Tooltip-Background" })
        timerFrame:SetBackdropColor(0, 0, 0, 0.8)
        if resizeHandle then resizeHandle:Hide() end
        if not inCombat and (not db.stickyTimer or not IsInstanceCheckPassed(db)) then
            timerFrame:Hide()
        end
    else
        timerFrame:SetBackdrop(nil)
        if resizeHandle then resizeHandle:Hide() end
        if not inCombat and (not db.stickyTimer or not IsInstanceCheckPassed(db)) then
            timerFrame:Hide()
        end
    end

    if not timerFrame.initialized then
        timerFrame:ClearAllPoints()
        local point = db.point or "CENTER"
        timerFrame:SetPoint(point, UIParent, point, db.x or 0, db.y or -200)
        timerFrame:SetSize(db.width or 400, db.height or 100)
        timerFrame.initialized = true
    end

    -- Text color
    local r, g, b = GetEffectiveColor(db, "colorR", "colorG", "colorB", "useClassColor")
    timerText:SetTextColor(r, g, b)

    -- Build time string
    local elapsed
    if inCombat then
        elapsed = GetTime() - combatStartTime
    elseif db.stickyTimer and lastCombatDuration > 0 then
        elapsed = lastCombatDuration
    else
        elapsed = 0
    end
    local minutes      = math.floor(elapsed / 60)
    local seconds      = math.floor(elapsed % 60)
    local centiseconds = math.floor((elapsed % 1) * 100)
    local timeStr      = string.format("%d:%02d.%02d", minutes, seconds, centiseconds)

    local text
    if db.hidePrefix then
        text = timeStr
    elseif db.combatText then
        text = db.combatText
            :gsub("{m}",  minutes)
            :gsub("{s}",  string.format("%02d", seconds))
            :gsub("{cs}", string.format("%02d", centiseconds))
    else
        text = "COMBAT: " .. timeStr
    end

    timerText:SetText(text)
    self:UpdateTextSize()
    timerText:Show()
end

-- OnUpdate ticker (0.05s = 20x/s für flüssige Hundertstel)
local acc = 0
timerFrame:SetScript("OnUpdate", function(self, elapsed)
    acc = acc + elapsed
    if acc >= 0.05 then
        acc = 0
        local db = GetCachedDb()
        if inCombat
            or (db and db.unlock)
            or (db and db.stickyTimer and lastCombatDuration > 0 and IsInstanceCheckPassed(db))
        then
            self:UpdateDisplay()
        end
    end
end)

-------------------------
-- Event Handling
-------------------------
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 = AiB.db and AiB.db.profile and AiB.db.profile.combatTimer
    if not db then return end

    if event == "PLAYER_LOGIN" then
        InvalidateDbCache()

        db.width  = db.width  or 400
        db.height = db.height or 100
        db.point  = db.point  or "CENTER"
        db.x      = db.x      or 0
        db.y      = db.y      or -200

        MakeDraggable(timerFrame, db)
        resizeHandle = CreateResizeHandle(timerFrame, db, function()
            timerFrame:UpdateTextSize()
        end)

        timerFrame.initialized = false
        timerFrame:UpdateDisplay()

        -- Register for settings refresh
        AiB.Combat = AiB.Combat or {}
        AiB.Combat.RefreshTimer = function()
            InvalidateDbCache()
            timerFrame:UpdateDisplay()
        end

    elseif event == "PLAYER_REGEN_DISABLED" and db.enabled then
        -- Instance-only check
        if db.instanceOnly then
            local inInstance, instanceType = IsInInstance()
            if not inInstance or instanceType == "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

            -- Chat report
            local db2 = AiB.db and AiB.db.profile and AiB.db.profile.combatTimer
            if db2 and db2.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 Stunden", h, m, s)
                elseif m > 0 then
                    timeText = string.format("%d:%02d Minuten", m, s)
                else
                    timeText = string.format("%d Sekunden", math.floor(duration))
                end

                print("|cFFFF0000AiB|r Kampfdauer: |cffffa900" .. timeText .. "|r")
            end
        end

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

AiB.CombatTimerDisplay = timerFrame

function timerFrame:RefreshSettings()
    InvalidateDbCache()
    self:UpdateDisplay()
end
