local NS = rawget(_G, "MCDVoiceCooldownNS") or {}
_G.MCDVoiceCooldownNS = NS

NS.OptionsController = NS.OptionsController or {}
local Controller = NS.OptionsController

local L = NS.L or function(key, ...)
    if select("#", ...) > 0 then
        return string.format(tostring(key), ...)
    end
    return tostring(key)
end

local Utils = NS.Utils or {}
local CollectionStore = NS.CollectionStore or {}

local function TrimText(value)
    if Utils.TrimText then
        return Utils.TrimText(value)
    end
    return tostring(value or ""):match("^%s*(.-)%s*$")
end

local function GetApi()
    return NS.API
end

local function EnsureBloodlustConfigTable()
    local db = MCDVoiceCooldownDB
    if type(db) ~= "table" then
        db = {}
        MCDVoiceCooldownDB = db
    end

    if type(db.bloodlustConfig) ~= "table" then
        db.bloodlustConfig = {}
    end
    if type(db.bloodlustConfig.customSoundPaths) ~= "table" then
        db.bloodlustConfig.customSoundPaths = { "", "", "", "", "" }
    end

    return db.bloodlustConfig
end

local function ParseGroupKey(key)
    if type(CollectionStore.ParseGroupKey) == "function" then
        return CollectionStore.ParseGroupKey(key)
    end
    local classID, specID, groupID = tostring(key or ""):match("^group:(%-?%d+):(%-?%d+):(.+)$")
    return tonumber(classID) or 0, tonumber(specID) or 0, tostring(groupID or "")
end

local function EnsureCollectionScope(classID, specID)
    if type(CollectionStore.EnsureCollectionScope) == "function" then
        return CollectionStore.EnsureCollectionScope(classID, specID)
    end
    return nil
end

function Controller:LoadBloodlustConfig(aceOptions)
    local state = aceOptions:GetState()
    local cfg = EnsureBloodlustConfigTable()
    state.entryType = "bloodlust"
    state.bloodlustPaths = state.bloodlustPaths or {}

    for i = 1, 5 do
        state.bloodlustPaths[i] = aceOptions:NormalizeSoundPath(cfg.customSoundPaths[i] or "")
    end
end

function Controller:GetBloodlustSummary(aceOptions)
    local state = aceOptions:GetState()
    local paths = state.bloodlustPaths
    if type(paths) ~= "table" then
        self:LoadBloodlustConfig(aceOptions)
        paths = state.bloodlustPaths
    end

    local count = 0
    for i = 1, 5 do
        if TrimText(paths[i] or "") ~= "" then
            count = count + 1
        end
    end

    return L("MSG_BLOODLUST_SUMMARY", count)
end

function Controller:SaveBloodlustConfig(aceOptions)
    local api = GetApi()
    local state = aceOptions:GetState()
    local cfg = EnsureBloodlustConfigTable()
    local paths = type(state.bloodlustPaths) == "table" and state.bloodlustPaths or {}

    cfg.customSoundPaths = cfg.customSoundPaths or {}
    for i = 1, 5 do
        cfg.customSoundPaths[i] = aceOptions:NormalizeSoundPath(paths[i] or "")
    end

    state.bloodlustPaths = {}
    for i = 1, 5 do
        state.bloodlustPaths[i] = cfg.customSoundPaths[i]
    end

    if api and type(api.RebuildBloodlustConfig) == "function" then
        api.RebuildBloodlustConfig()
    end
    if api and type(api.RefreshPanel) == "function" then
        api.RefreshPanel()
    end

    print("[MCD-CVA] " .. L("MSG_BLOODLUST_SAVED"))
    return true
end

function Controller:GetCurrentScopeSummary(aceOptions)
    local api = GetApi()
    local state = aceOptions:GetState()
    if not api then
        return ""
    end

    local className = api.ResolveClassName(state.classID)
    local specName = api.ResolveSpecName(state.classID, state.specID)
    return L("MSG_CURRENT_EDIT_SCOPE", className, specName)
end

function Controller:ApplyStateToWidgets()
    if NS.UI and NS.UI.EditorFrame and NS.UI.EditorFrame.frame and NS.UI.EditorFrame.frame.IsShown and NS.UI.EditorFrame.frame:IsShown() then
        NS.UI.EditorFrame:Refresh()
    end
    return true
end

function Controller:OpenEditorPopup()
    if NS.UI and NS.UI.MainFrame and type(NS.UI.MainFrame.Open) == "function" then
        return NS.UI.MainFrame:Open()
    end
    return false
end

function Controller:ToggleCollectionCollapsed(groupKey)
    local classID, specID, groupID = ParseGroupKey(groupKey)
    if classID < 0 or specID < 0 or tostring(groupID or "") == "" then
        return false
    end

    local scope = EnsureCollectionScope(classID, specID)
    local group = scope and scope.groups and scope.groups[tostring(groupID)]
    if type(group) ~= "table" then
        return false
    end

    group.collapsed = not (group.collapsed == true)
    return true
end

function Controller:Initialize(aceOptions)
    aceOptions.initialized = true
    aceOptions.available = true
    aceOptions.AceGUI = nil
    aceOptions.frameWidget = nil
    return true
end

function Controller:Open()
    if NS.UI and NS.UI.MainFrame and type(NS.UI.MainFrame.Open) == "function" then
        return NS.UI.MainFrame:Open()
    end
    return false
end

function Controller:CreateWindow(aceOptions)
    aceOptions.frameWidget = nil
    return self:Open()
end

function Controller:RefreshSavedList()
    if NS.UI and NS.UI.MainFrame and NS.UI.MainFrame.savedList and type(NS.UI.MainFrame.savedList.Refresh) == "function" then
        NS.UI.MainFrame.savedList:Refresh()
        return true
    end
    return false
end

function Controller:RefreshUI()
    if NS.UI and NS.UI.MainFrame and NS.UI.MainFrame.frame and type(NS.UI.MainFrame.Refresh) == "function" then
        NS.UI.MainFrame:Refresh()
    end
    if NS.UI and NS.UI.EditorFrame and NS.UI.EditorFrame.frame and NS.UI.EditorFrame.frame.IsShown and NS.UI.EditorFrame.frame:IsShown() and type(NS.UI.EditorFrame.Refresh) == "function" then
        NS.UI.EditorFrame:Refresh()
    end
    return true
end

local AceOptions = NS.AceOptions or {}
NS.AceOptions = AceOptions

function AceOptions:LoadBloodlustConfig()
    return Controller:LoadBloodlustConfig(self)
end

function AceOptions:GetBloodlustSummary()
    return Controller:GetBloodlustSummary(self)
end

function AceOptions:SaveBloodlustConfig()
    return Controller:SaveBloodlustConfig(self)
end

function AceOptions:TestBloodlustConfig()
    if NS.TestController and type(NS.TestController.TestBloodlustConfig) == "function" then
        return NS.TestController:TestBloodlustConfig(self)
    end
end

function AceOptions:GetCurrentScopeSummary()
    return Controller:GetCurrentScopeSummary(self)
end

function AceOptions:LoadSelectedEntry()
    if NS.EntryStore and type(NS.EntryStore.LoadSelectedEntry) == "function" then
        return NS.EntryStore:LoadSelectedEntry(self)
    end
end

function AceOptions:AutofillFromSpellId()
    if NS.EntryStore and type(NS.EntryStore.AutofillFromSpellId) == "function" then
        return NS.EntryStore:AutofillFromSpellId(self)
    end
end

function AceOptions:AutofillFromTalentId()
    if NS.EntryStore and type(NS.EntryStore.AutofillFromTalentId) == "function" then
        return NS.EntryStore:AutofillFromTalentId(self)
    end
end

function AceOptions:SaveEntry()
    if NS.EntryStore and type(NS.EntryStore.SaveEntry) == "function" then
        return NS.EntryStore:SaveEntry(self)
    end
end

function AceOptions:DeleteSelectedEntry(suppressRefresh)
    if NS.EntryStore and type(NS.EntryStore.DeleteSelectedEntry) == "function" then
        return NS.EntryStore:DeleteSelectedEntry(self, suppressRefresh)
    end
end

function AceOptions:TestCurrent()
    if NS.TestController and type(NS.TestController.TestCurrent) == "function" then
        return NS.TestController:TestCurrent(self)
    end
end

function AceOptions:SyncStateFromWidgets()
    if NS.OptionsState and type(NS.OptionsState.SyncStateFromWidgets) == "function" then
        return NS.OptionsState:SyncStateFromWidgets(self)
    end
end

function AceOptions:ApplyStateToWidgets()
    return Controller:ApplyStateToWidgets(self)
end

function AceOptions:OpenEditorPopup()
    return Controller:OpenEditorPopup(self)
end

function AceOptions:ToggleCollectionCollapsed(groupKey)
    return Controller:ToggleCollectionCollapsed(groupKey)
end

function AceOptions:Initialize()
    return Controller:Initialize(self)
end

function AceOptions:Open()
    return Controller:Open(self)
end

function AceOptions:CreateWindow()
    return Controller:CreateWindow(self)
end

function AceOptions:RefreshSavedList()
    return Controller:RefreshSavedList(self)
end

function AceOptions:RefreshUI()
    return Controller:RefreshUI(self)
end
