-- FullSteel.lua
-- Warrior ability sound addon with Diablo 2 Barbarian sounds

-- =========================================================================
-- 1. INITIALIZATION & DEFAULTS
-- =========================================================================
local db = {}
local playerGUID = nil
local originalVolume = nil
local restoreTimer = nil
local uiLoaded = false

-- Define defaults here for easy maintenance
local defaults = {
    enabled = true, debug = false,
    charge = true, intercept = true, intervene = true, execute = true,
    battleshout = true, demoshout = true, challengeshout = true, intimidateshout = true,
    chargeVolume = 100, executeVolume = 100, shoutVolume = 100,
    chargeSound = 1, executeSound = 0, battleshoutSound = 0,
    demoshoutSound = 0, challengeshoutSound = 0, intimidateshoutSound = 0
}

local function dprint(...)
    if db.debug then print("FullSteel:", ...) end
end

-- Optimization: Safe Sound Player (Prevents Volume Bugs)
local function PlaySafeSound(soundFile, volumePercent)
    if not soundFile then return end
    volumePercent = volumePercent or 100
    if volumePercent <= 0 then return end

    -- 1. Save original volume if not already tracked
    if not originalVolume then
        originalVolume = tonumber(GetCVar("Sound_SFXVolume")) or 1.0
    end

    -- 2. Set temp volume (Clamped 0-1)
    local newVolume = originalVolume * (volumePercent / 100.0)
    newVolume = math.max(0, math.min(1.0, newVolume))
    SetCVar("Sound_SFXVolume", tostring(newVolume))

    -- 3. Play
    PlaySoundFile(soundFile, "SFX")

    -- 4. Reset Timer (Cancel old one if exists)
    if restoreTimer then restoreTimer:Cancel() end
    restoreTimer = C_Timer.NewTimer(2.0, function()
        if originalVolume then
            SetCVar("Sound_SFXVolume", tostring(originalVolume))
            originalVolume = nil
            restoreTimer = nil
        end
    end)
end

-- =========================================================================
-- 2. SOUND DATA
-- =========================================================================
local chargeSounds = {
    "Interface\\AddOns\\FullSteel\\varian_colossus_smash01.ogg",
}

local lastSoundTime = {}
local soundCooldown = 1.5

local soundGroups = {
    battlecry = {
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\battlecry1.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\battlecry2.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\battlecry3.ogg",
    },
    battleorders = {
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\command1.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\command2.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\command3.ogg",
    },
    battlecommand = {
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\order1.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\order2.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\order3.ogg",
    },
    howl = {
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\howl1.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\howl2.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\howl3.ogg",
    },
    shout = {
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\shout1.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\shout2.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\shout3.ogg",
    },
    taunt = {
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\taunt1.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\taunt2.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\taunt3.ogg",
    },
    warcry = {
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\warcry1.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\warcry2.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\barbarian\\warcry3.ogg",
    },
    corpseexplosion = {
        "Interface\\AddOns\\FullSteel\\skill\\necromancer\\corpseexplodecast.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\necromancer\\corpse_explode_1.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\necromancer\\corpse_explode_2.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\necromancer\\corpse_explode_3.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\necromancer\\corpse_explode_4.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\necromancer\\corpse_explode_5.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\necromancer\\corpse_explode_6.ogg",
    },
    lightningfury = {
        "Interface\\AddOns\\FullSteel\\skill\\amazon\\zeus1.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\amazon\\zeus2.ogg",
        "Interface\\AddOns\\FullSteel\\skill\\amazon\\zeus3.ogg",
    },
}

local shoutSounds = {}
local shoutSoundNames = { [0] = "Random" }

table.insert(shoutSounds, soundGroups.battlecry); shoutSoundNames[#shoutSounds] = "Battle Cry"
table.insert(shoutSounds, soundGroups.battleorders); shoutSoundNames[#shoutSounds] = "Battle Orders"
table.insert(shoutSounds, soundGroups.battlecommand); shoutSoundNames[#shoutSounds] = "Battle Command"
table.insert(shoutSounds, soundGroups.howl); shoutSoundNames[#shoutSounds] = "Howl"
table.insert(shoutSounds, soundGroups.shout); shoutSoundNames[#shoutSounds] = "Shout"
table.insert(shoutSounds, soundGroups.taunt); shoutSoundNames[#shoutSounds] = "Taunt"
table.insert(shoutSounds, soundGroups.warcry); shoutSoundNames[#shoutSounds] = "War Cry"

local executeSounds = {}
local executeSoundNames = { [0] = "Random" }

table.insert(executeSounds, soundGroups.corpseexplosion); executeSoundNames[#executeSounds] = "Corpse Explosion"
table.insert(executeSounds, soundGroups.lightningfury); executeSoundNames[#executeSounds] = "Lightning Fury"

local randomPool = {}
for _, group in pairs(soundGroups) do
    for _, sound in ipairs(group) do table.insert(randomPool, sound) end
end

local executeRandomPool = {}
for _, sound in ipairs(soundGroups.corpseexplosion) do table.insert(executeRandomPool, sound) end
for _, sound in ipairs(soundGroups.lightningfury) do table.insert(executeRandomPool, sound) end

local spellConfig = {
    ["Charge"] = { key = "charge", volume = "chargeVolume", soundKey = "chargeSound", sounds = chargeSounds },
    ["Intercept"] = { key = "intercept", volume = "chargeVolume", soundKey = "chargeSound", sounds = chargeSounds },
    ["Intervene"] = { key = "intervene", volume = "chargeVolume", soundKey = "chargeSound", sounds = chargeSounds },
    ["Execute"] = { key = "execute", volume = "executeVolume", soundKey = "executeSound", sounds = executeSounds, randomPool = executeRandomPool },
    ["Sudden Death"] = { key = "execute", volume = "executeVolume", soundKey = "executeSound", sounds = executeSounds, randomPool = executeRandomPool },
    ["Battle Shout"] = { key = "battleshout", volume = "shoutVolume", soundKey = "battleshoutSound", sounds = shoutSounds, randomPool = randomPool },
    ["Demoralizing Shout"] = { key = "demoshout", volume = "shoutVolume", soundKey = "demoshoutSound", sounds = shoutSounds, randomPool = randomPool },
    ["Challenging Shout"] = { key = "challengeshout", volume = "shoutVolume", soundKey = "challengeshoutSound", sounds = shoutSounds, randomPool = randomPool },
    ["Intimidating Shout"] = { key = "intimidateshout", volume = "shoutVolume", soundKey = "intimidateshoutSound", sounds = shoutSounds, randomPool = randomPool },
}

-- =========================================================================
-- 3. UI GENERATION
-- =========================================================================
function FullSteel_LoadUI()
    local panel = CreateFrame("Frame")
    panel.name = "FullSteel"
    panel.parent = nil
    panel:Hide()

    local scrollFrame = CreateFrame("ScrollFrame", nil, panel, "UIPanelScrollFrameTemplate")
    scrollFrame:SetPoint("TOPLEFT", 3, -4)
    scrollFrame:SetPoint("BOTTOMRIGHT", -27, 4)

    local content = CreateFrame("Frame", nil, scrollFrame)
    content:SetSize(780, 1200)
    scrollFrame:SetScrollChild(content)

    -- Headers
    local title = content:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    title:SetPoint("TOPRIGHT", -20, -16)
    title:SetText("FullSteel")

    local subtitle = content:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    subtitle:SetPoint("TOPRIGHT", title, "BOTTOMRIGHT", 0, -8)
    subtitle:SetText("Plays Varian roar on Charge and D2 Barb Shouts - type /fs")
    subtitle:SetTextColor(0.8, 0.8, 0.8)

    local byline = content:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    byline:SetPoint("TOPRIGHT", subtitle, "BOTTOMRIGHT", 0, -8)
    byline:SetText("by Maggew.com in Philadelphia, USA!")
    byline:SetTextColor(0.8, 0.8, 0.8)

    local paypalTex = content:CreateTexture(nil, "ARTWORK")
    paypalTex:SetTexture("paypal.tga") 
    paypalTex:SetSize(16, 16)
    paypalTex:SetPoint("TOPRIGHT", byline, "BOTTOMRIGHT", 0, -8)

    local paypalText = content:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    paypalText:SetPoint("LEFT", paypalTex, "RIGHT", 4, 0)
    paypalText:SetText("maggew.com/pay")
    paypalText:SetTextColor(0.5, 0.7, 1.0)

    -- UI Helper Functions
    local function CreateAbilityRow(parent, yOffset, label, enableKey, soundKey, sounds, soundNames, volumeKey, randomPool)
        local cb = CreateFrame("CheckButton", nil, parent, "InterfaceOptionsCheckButtonTemplate")
        cb:SetPoint("TOPLEFT", 20, yOffset)
        cb.Text:SetText(label)
        cb.Text:SetWidth(180)
        cb.Text:SetJustifyH("LEFT")
        cb:SetChecked(db[enableKey])
        cb:SetScript("OnClick", function(self)
            db[enableKey] = self:GetChecked()
            FullSteelDB[enableKey] = self:GetChecked()
        end)

        if sounds and #sounds > 1 and soundKey and soundNames then
            local dropdown = CreateFrame("Frame", nil, parent, "UIDropDownMenuTemplate")
            dropdown:SetPoint("LEFT", cb, "RIGHT", 185, -2)
            UIDropDownMenu_SetWidth(dropdown, 140)
            dropdown:EnableMouse(true)
            dropdown:SetScript("OnMouseDown", function() ToggleDropDownMenu(1, nil, dropdown) end)

            UIDropDownMenu_Initialize(dropdown, function(self)
                local randomInfo = UIDropDownMenu_CreateInfo()
                randomInfo.text = "Random"
                randomInfo.func = function()
                    db[soundKey] = 0
                    FullSteelDB[soundKey] = 0
                    UIDropDownMenu_SetText(dropdown, "Random")
                    if randomPool and #randomPool > 0 then
                        local randomSound = randomPool[math.random(1, #randomPool)]
                        local vol = db[volumeKey] or 100
                        PlaySafeSound(randomSound, vol)
                    end
                end
                randomInfo.checked = (db[soundKey] == 0)
                UIDropDownMenu_AddButton(randomInfo)

                for i = 1, #sounds do
                    local info = UIDropDownMenu_CreateInfo()
                    info.text = soundNames[i]
                    info.func = function()
                        db[soundKey] = i
                        FullSteelDB[soundKey] = i
                        UIDropDownMenu_SetText(dropdown, soundNames[i])
                        local soundGroup = sounds[i]
                        if type(soundGroup) == "table" and #soundGroup > 0 then
                             local variant = soundGroup[math.random(1, #soundGroup)]
                             local vol = db[volumeKey] or 100
                             PlaySafeSound(variant, vol)
                        end
                    end
                    info.checked = (db[soundKey] == i)
                    UIDropDownMenu_AddButton(info)
                end
            end)
            UIDropDownMenu_SetText(dropdown, soundNames[db[soundKey]] or "Random")
        end
        return cb
    end

    local function CreateThreeColumnRow(parent, yOffset, label1, key1, label2, key2, label3, key3)
        local function makeCb(lbl, k, x, relativeTo)
            local cb = CreateFrame("CheckButton", nil, parent, "InterfaceOptionsCheckButtonTemplate")
            if relativeTo then cb:SetPoint("LEFT", relativeTo, "RIGHT", x, 0)
            else cb:SetPoint("TOPLEFT", 20, yOffset) end
            cb.Text:SetText(lbl)
            cb:SetChecked(db[k])
            cb:SetScript("OnClick", function(self)
                db[k] = self:GetChecked()
                FullSteelDB[k] = self:GetChecked()
            end)
            return cb
        end
        local cb1 = makeCb(label1, key1, 0, nil)
        local cb2 = makeCb(label2, key2, 120, cb1)
        local cb3 = makeCb(label3, key3, 120, cb2)
    end

    local function CreateVolumeDropdown(parent, yOffset, label, dbKey, testSounds)
        local container = CreateFrame("Frame", nil, parent)
        container:SetPoint("TOPLEFT", 20, yOffset)
        container:SetSize(400, 40)
        
        local labelText = container:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
        labelText:SetPoint("TOPLEFT", 0, 0)
        labelText:SetText(label)

        local dropdownName = "FullSteelVolumeDropdown_" .. dbKey
        local dropdown = CreateFrame("Frame", dropdownName, container, "UIDropDownMenuTemplate")
        dropdown:SetPoint("TOPLEFT", 0, -20)
        UIDropDownMenu_SetWidth(dropdown, 120)

        local button = _G[dropdownName .. "Button"]
        if button then
            button:SetHitRectInsets(0, 0, 0, 0)
            dropdown:EnableMouse(true)
            dropdown:SetScript("OnMouseDown", function() ToggleDropDownMenu(1, nil, dropdown) end)
        end

        local volumeOptions = {0, 25, 50, 75, 100}
        UIDropDownMenu_Initialize(dropdown, function(self)
            for _, vol in ipairs(volumeOptions) do
                local info = UIDropDownMenu_CreateInfo()
                info.text = vol .. "%"
                info.func = function()
                    db[dbKey] = vol
                    FullSteelDB[dbKey] = vol
                    UIDropDownMenu_SetText(dropdown, vol .. "%")
                end
                info.checked = (db[dbKey] == vol)
                UIDropDownMenu_AddButton(info)
            end
        end)
        UIDropDownMenu_SetText(dropdown, (db[dbKey] or 100) .. "%")

        if testSounds then
            local testBtn = CreateFrame("Button", nil, container, "UIPanelButtonTemplate")
            testBtn:SetPoint("LEFT", dropdown, "RIGHT", 10, 2)
            testBtn:SetSize(80, 22)
            testBtn:SetText("Test")
            testBtn:SetScript("OnClick", function()
                local sound
                if type(testSounds[1]) == "table" then
                     local g = testSounds[math.random(1, #testSounds)]
                     sound = g[math.random(1, #g)]
                else
                     sound = testSounds[math.random(1, #testSounds)]
                end
                local vol = db[dbKey] or 100
                PlaySafeSound(sound, vol)
                print("FullSteel: Testing sound at " .. vol .. "%")
            end)
        end
        return container
    end

    -- Build Layout
    local y = -60
    local controlsHeader = content:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    controlsHeader:SetPoint("TOPLEFT", 20, y); controlsHeader:SetText("Addon Controls")
    y = y - 35
    
    local masterToggle = CreateFrame("CheckButton", nil, content, "InterfaceOptionsCheckButtonTemplate")
    masterToggle:SetPoint("TOPLEFT", 20, y)
    masterToggle.Text:SetText("Enable FullSteel (Master Toggle)")
    masterToggle:SetChecked(db.enabled)
    masterToggle:SetScript("OnClick", function(self)
        db.enabled = self:GetChecked()
        FullSteelDB.enabled = self:GetChecked()
        print(db.enabled and "FullSteel: ENABLED" or "FullSteel: DISABLED")
    end)
    
    local masterDesc = content:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    masterDesc:SetPoint("TOPLEFT", masterToggle, "BOTTOMLEFT", 25, -2)
    masterDesc:SetText("Uncheck to completely disable all addon sounds")
    masterDesc:SetTextColor(0.7, 0.7, 0.7)
    y = y - 55

    local resetBtn = CreateFrame("Button", nil, content, "UIPanelButtonTemplate")
    resetBtn:SetPoint("TOPLEFT", 20, y); resetBtn:SetSize(120, 25); resetBtn:SetText("Reset to Defaults")
    resetBtn:SetScript("OnClick", function()
        for k, v in pairs(defaults) do db[k] = v end
        FullSteelDB = db
        ReloadUI()
    end)
    
    local debugCb = CreateFrame("CheckButton", nil, content, "InterfaceOptionsCheckButtonTemplate")
    debugCb:SetPoint("LEFT", resetBtn, "RIGHT", 40, 0)
    debugCb.Text:SetText("Debug Mode")
    debugCb:SetChecked(db.debug)
    debugCb:SetScript("OnClick", function(self)
        db.debug = self:GetChecked()
        FullSteelDB.debug = self:GetChecked()
    end)
    y = y - 70

    local abilityHeader = content:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    abilityHeader:SetPoint("TOPLEFT", 20, y); abilityHeader:SetText("Ability Sounds")
    y = y - 40
    CreateThreeColumnRow(content, y, "Charge", "charge", "Intercept", "intercept", "Intervene", "intervene")
    y = y - 40
    CreateAbilityRow(content, y, "Execute", "execute", "executeSound", executeSounds, executeSoundNames, "executeVolume", executeRandomPool)
    y = y - 40
    CreateAbilityRow(content, y, "Battle Shout", "battleshout", "battleshoutSound", shoutSounds, shoutSoundNames, "shoutVolume", randomPool)
    y = y - 40
    CreateAbilityRow(content, y, "Demoralizing Shout", "demoshout", "demoshoutSound", shoutSounds, shoutSoundNames, "shoutVolume", randomPool)
    y = y - 40
    CreateAbilityRow(content, y, "Challenging Shout", "challengeshout", "challengeshoutSound", shoutSounds, shoutSoundNames, "shoutVolume", randomPool)
    y = y - 40
    CreateAbilityRow(content, y, "Intimidating Shout", "intimidateshout", "intimidateshoutSound", shoutSounds, shoutSoundNames, "shoutVolume", randomPool)
    y = y - 70

    local volumeHeader = content:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    volumeHeader:SetPoint("TOPLEFT", 20, y); volumeHeader:SetText("Volume Controls")
    y = y - 35
    CreateVolumeDropdown(content, y, "Charge/Intercept/Intervene", "chargeVolume", chargeSounds)
    y = y - 55
    CreateVolumeDropdown(content, y, "Execute", "executeVolume", executeSounds)
    y = y - 55
    CreateVolumeDropdown(content, y, "Shouts", "shoutVolume", shoutSounds)

    panel:SetScript("OnShow", function(self) self:SetWidth(820); self:SetHeight(600) end)
    local category = Settings.RegisterCanvasLayoutCategory(panel, panel.name)
    category.ID = panel.name
    Settings.RegisterAddOnCategory(category)

    SLASH_FULLSTEEL1 = "/fullsteel"
    SLASH_FULLSTEEL2 = "/fs"
    SlashCmdList["FULLSTEEL"] = function(msg)
        msg = (msg or ""):lower():match("^%s*(.-)%s*$")
        if msg == "debug" then
            db.debug = not db.debug
            FullSteelDB.debug = db.debug
            print("FullSteel: debug " .. (db.debug and "ON" or "OFF"))
            return
        end
        if msg == "status" then
            print("FullSteel: Current saved settings:")
            print(" executeSound:", db.executeSound)
            print(" battleshoutSound:", db.battleshoutSound)
            return
        end
        Settings.OpenToCategory(category.ID)
    end
end

-- =========================================================================
-- 4. EVENT HANDLING
-- =========================================================================
local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("ADDON_LOADED")
eventFrame:RegisterEvent("PLAYER_LOGIN")
eventFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")

eventFrame:SetScript("OnEvent", function(self, event, arg1, ...)
    -- Handle Init
    if event == "ADDON_LOADED" and arg1 == "FullSteel" then
        FullSteelDB = FullSteelDB or {}
        db = FullSteelDB
        
        -- Apply Defaults
        for k, v in pairs(defaults) do
            if db[k] == nil then db[k] = v end
        end

        if not uiLoaded and FullSteel_LoadUI then
             FullSteel_LoadUI()
             uiLoaded = true
        end
        
        print("|cFF00FF00FullSteel loaded.|r Type /fs to configure.")

    -- Handle Login
    elseif event == "PLAYER_LOGIN" then
        playerGUID = UnitGUID("player")

    -- Handle Combat
    elseif event == "COMBAT_LOG_EVENT_UNFILTERED" then
        if not db.enabled then return end
        
        -- Safe check for GUID (Just in case LOGIN didn't fire yet)
        if not playerGUID then playerGUID = UnitGUID("player") end

        local _, subevent, _, sourceGUID, _, _, _, _, _, _, _, spellId, spellName = CombatLogGetCurrentEventInfo()

        if sourceGUID ~= playerGUID then return end

        local isValidEvent = false
        if subevent == "SPELL_CAST_SUCCESS" then
            isValidEvent = true
        elseif (subevent == "SPELL_DAMAGE" or subevent == "SWING_DAMAGE") and spellName == "Execute" then
            isValidEvent = true
        end

        if not isValidEvent then return end

        if db.debug then print("FullSteel DEBUG:", subevent, spellName) end

        local config = spellConfig[spellName]
        if not config then return end

        if not db[config.key] then return end

        local currentTime = GetTime()
        local lastTime = lastSoundTime[spellName] or 0
        if currentTime - lastTime < soundCooldown then return end
        lastSoundTime[spellName] = currentTime

        local soundIndex = db[config.soundKey]
        local sound
        
        -- Sound Selection
        if not soundIndex or soundIndex == 0 then
             if config.randomPool and #config.randomPool > 0 then
                 sound = config.randomPool[math.random(1, #config.randomPool)]
             end
        else
             local soundGroup = config.sounds[soundIndex]
             if type(soundGroup) == "table" then
                  sound = soundGroup[math.random(1, #soundGroup)]
             else
                  sound = soundGroup
             end
        end

        local vol = db[config.volume] or 100
        PlaySafeSound(sound, vol)
    end
end)
