-------------------------
-- AiB Combat Alert 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 0, db[gKey] or 1, db[bKey] or 0
end

-- Helper: make a frame draggable, saves point/x/y to db
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

-------------------------
-- Alert Frame
-------------------------
local alertFrame = CreateFrame("Frame", "AiB_CombatAlertDisplay", UIParent, "BackdropTemplate")
alertFrame:SetSize(300, 80)
alertFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 200)
alertFrame:Hide()

-- Animations
local fadeInAnim  = alertFrame:CreateAnimationGroup()
local fadeIn      = fadeInAnim:CreateAnimation("Alpha")
fadeIn:SetFromAlpha(0)
fadeIn:SetToAlpha(1)
fadeIn:SetDuration(0.4)

local holdAnim = alertFrame:CreateAnimationGroup()
local hold     = holdAnim:CreateAnimation("Alpha")
hold:SetFromAlpha(1)
hold:SetToAlpha(1)
hold:SetDuration(1.7)

local fadeOutAnim = alertFrame:CreateAnimationGroup()
local fadeOut     = fadeOutAnim:CreateAnimation("Alpha")
fadeOut:SetFromAlpha(1)
fadeOut:SetToAlpha(0)
fadeOut:SetDuration(0.4)

fadeInAnim:SetScript("OnFinished",  function() holdAnim:Play() end)
holdAnim:SetScript("OnFinished",    function() fadeOutAnim:Play() end)
fadeOutAnim:SetScript("OnFinished", function() alertFrame:Hide() end)

-- Text
local alertText = alertFrame:CreateFontString(nil, "OVERLAY")
alertText:SetPoint("CENTER", alertFrame, "CENTER", 0, 0)
alertText:SetJustifyH("CENTER")
alertText:SetJustifyV("MIDDLE")
alertText:SetWordWrap(false)
alertText:SetFont(FONT_PATH, 32, "OUTLINE")

local txtColor = { r = 0, g = 1, b = 0 }

local function ApplyColor()
    alertText:SetTextColor(txtColor.r, txtColor.g, txtColor.b, 1)
end

-- SOUNDKIT-Mapping (muss mit aib_combat_settings.lua übereinstimmen)
local COMBAT_SOUNDS = {
    [0] = nil,
    [1] = "AUCTION_WINDOW_OPEN",
    [2] = "READY_CHECK",
    [3] = "TELL_MESSAGE",
    [4] = "RAID_WARNING",
    [5] = "ACHIEVEMENT_MENU_OPEN",
    [9] = "PVP_ENTER_QUEUE",
}

-- Audio playback
local function PlayCombatAudio(prefix)
    local db = AiB.db and AiB.db.profile and AiB.db.profile.combatAlert
    if not db then return end

    local audioMode = db[prefix .. "AudioMode"] or "none"
    if audioMode == "none" then return end

    if audioMode == "sound" then
        local soundId  = db[prefix .. "SoundId"] or 0
        local soundkit = COMBAT_SOUNDS[soundId]
        if soundkit and SOUNDKIT[soundkit] then
            PlaySound(SOUNDKIT[soundkit], "Master")
        end
    elseif audioMode == "tts" then
        local ttsMessage = db[prefix .. "TtsMessage"]
        local ttsVolume  = db[prefix .. "TtsVolume"]  or 50
        local ttsRate    = db[prefix .. "TtsRate"]    or 0
        local ttsVoiceID = db[prefix .. "TtsVoiceID"] or 0
        if ttsMessage and ttsMessage ~= "" then
            C_VoiceChat.SpeakText(ttsVoiceID, ttsMessage, ttsRate, ttsVolume, true)
        end
    end
end

-- Resize handle (created after PLAYER_LOGIN)
local resizeHandle

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

    local frameWidth  = alertFrame:GetWidth()
    local frameHeight = alertFrame:GetHeight()

    local currentText = alertText:GetText() or (db.enterText or "++ Combat")
    local textLength  = string.len(currentText)

    local fontSizeFromHeight     = math.floor(frameHeight * 0.35)
    local usableWidth            = frameWidth * 0.85
    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))

    local fontPath = AiB.Config and AiB.Config.FONTS.PRIMARY or FONT_PATH
    if not alertText:SetFont(fontPath, scaledFontSize, "OUTLINE") then
        alertText:SetFont(FONT_PATH, scaledFontSize, "OUTLINE")
    end

    ApplyColor()
end

-- Full display update (called from settings)
function alertFrame:UpdateDisplay()
    local db = AiB.db and AiB.db.profile and AiB.db.profile.combatAlert
    if not db then return end

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

    alertFrame:EnableMouse(db.unlock)

    if db.unlock then
        alertFrame: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 }
        })
        alertFrame:SetBackdropColor(0.1, 0.1, 0.1, 0.8)
        alertFrame:SetBackdropBorderColor(0.6, 0, 0, 1) -- AiB accent red
        if resizeHandle then resizeHandle:Show() end
        alertFrame:SetAlpha(1)

        alertText:SetText(db.enterText or "++ Combat")
        txtColor.r, txtColor.g, txtColor.b = GetEffectiveColor(db, "enterR", "enterG", "enterB", "enterUseClassColor")
        ApplyColor()
        alertFrame:Show()
    else
        alertFrame:SetBackdrop(nil)
        if resizeHandle then resizeHandle:Hide() end
        alertFrame:Hide()
    end

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

    self:UpdateTextSize()
end

-- Show a timed alert
local function ShowAlert(text, r, g, b)
    local db = AiB.db and AiB.db.profile and AiB.db.profile.combatAlert
    if not db or not db.enabled or db.unlock then return end

    alertFrame:ClearAllPoints()
    local point = db.point or "CENTER"
    alertFrame:SetPoint(point, UIParent, point, db.x or 0, db.y or 200)
    alertFrame:SetSize(db.width or 300, db.height or 80)

    alertText:SetText(text)
    txtColor.r, txtColor.g, txtColor.b = r, g, b
    ApplyColor()

    fadeInAnim:Stop()
    holdAnim:Stop()
    fadeOutAnim:Stop()

    alertFrame:SetAlpha(0)
    alertFrame:Show()
    alertFrame:UpdateTextSize()

    fadeInAnim:Play()
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.combatAlert
    if not db then return end

    if event == "PLAYER_LOGIN" then
        -- Apply defaults if missing
        db.width  = db.width  or 300
        db.height = db.height or 80
        db.point  = db.point  or "CENTER"
        db.x      = db.x      or 0
        db.y      = db.y      or 200

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

        alertFrame.initialized = false
        alertFrame:UpdateDisplay()

        -- Register for settings refresh
        AiB.Combat = AiB.Combat or {}
        AiB.Combat.RefreshAlert = function()
            alertFrame:UpdateDisplay()
        end

    elseif event == "PLAYER_REGEN_DISABLED" then
        if db.enabled then
            local r, g, b = GetEffectiveColor(db, "enterR", "enterG", "enterB", "enterUseClassColor")
            ShowAlert(db.enterText or "++ Combat", r, g, b)
            PlayCombatAudio("enter")
        end

    elseif event == "PLAYER_REGEN_ENABLED" then
        if db.enabled then
            local r, g, b = GetEffectiveColor(db, "leaveR", "leaveG", "leaveB", "leaveUseClassColor")
            ShowAlert(db.leaveText or "-- Combat", r, g, b)
            PlayCombatAudio("leave")
        end
    end
end)

AiB.CombatAlertDisplay = alertFrame
