local _AddonName, _EchoRaidTools = ...;


local module = _EchoRaidTools:GetModule("todo-list")

local version = 11



local function realmIncludedName(unit)
    local name, realm = UnitNameUnmodified(unit)

    if not realm then
        realm = GetNormalizedRealmName()
    end

    if not realm or not name then return end
    return string.format("%s-%s", name, realm)
end

local function setupFreshInstall()
    EchoRaidToolsDB.TodoList = {}
    EchoRaidToolsDB.TodoList.moduleEnabled = true
    EchoRaidToolsDB.TodoList.characters = {}
    EchoRaidToolsDB.TodoList.userMods = {}
    EchoRaidToolsDB.TodoList.adminOverrides = {}
    EchoRaidToolsDB.TodoList.display = {}
    EchoRaidToolsDB.TodoList.display.hideOnComplete = false
    EchoRaidToolsDB.TodoList.display.anchors = { frame = "WorldMapFrame", sourcePoint = "TOPLEFT", destPoint = "TOPRIGHT", offsetX = 50, offsetY = 0 }
    EchoRaidToolsDB.TodoList.display.size = { width = 400, height = 200, scale = 1 }
    EchoRaidToolsDB.TodoList.display.barSettings = {
        texture = "Gradient",
        font = "Expressway MonoNum",
        height = 20,
        colour = {
            0,
            1,
            0.98823535442352,
            1
        },
        progressTextColour = {
            1, 1, 1, 1
        },
        textColour = {
            1, 1, 1, 1
        },
        padding = 1,
        progressTextFontSize = 12,
        textFontSize = 12,
        bgColour = {
            0, 0, 0, 0.5
        },
    }
end

local function migrate()
    local savedVarsVersion = EchoRaidToolsDB.TodoList and EchoRaidToolsDB.TodoList.version or 0
    if savedVarsVersion < 6 then
        setupFreshInstall()
        EchoRaidToolsDB.TodoList.version = 6
        migrate()
    elseif savedVarsVersion < 7 then
        EchoRaidToolsDB.TodoList.display.bgColour = { 0, 0, 0, 0.5 }
        EchoRaidToolsDB.TodoList.version = 7
        migrate()
    elseif savedVarsVersion < 9 then
        EchoRaidToolsDB.TodoList.loadCondition = {
            combatType = "never", -- never | encounter | combat
            groupType = "never",  -- never | raid | party
        }
        EchoRaidToolsDB.TodoList.version = 9
        migrate()
    elseif savedVarsVersion < 10 then
        EchoRaidToolsDB.TodoList.display.barSettings.padding = 1
        EchoRaidToolsDB.TodoList.display.barSettings.textFontSize = 12
        EchoRaidToolsDB.TodoList.display.barSettings.progressTextFontSize = 12
        EchoRaidToolsDB.TodoList.display.barSettings.bgColour = {
            0, 0, 0, 0.5
        }
        EchoRaidToolsDB.TodoList.version = 10
        migrate()
    elseif savedVarsVersion < 11 then
        EchoRaidToolsDB.TodoList.display.anchors.strata = "HIGH"
        EchoRaidToolsDB.TodoList.version = 11
    end
end

function module:LoadSettings()
    local v = EchoRaidToolsDB.TodoList and EchoRaidToolsDB.TodoList.version
    if v ~= version then
        migrate()
    end
    local charName = realmIncludedName("player")
    if charName then
        EchoRaidToolsDB.TodoList.characters[charName] = true
    end
end

---@return table | nil
function module:GetAdminOverridesForMod(uid)
    if not uid then return end


    return EchoRaidToolsDB.TodoList.adminOverrides[uid]
end

---comment
---@param identifier string
---@param fieldTable table
---@param value number | string
function module:SetAdminOverride(identifier, fieldTable, value)
    EchoRaidToolsDB.TodoList.adminOverrides[identifier] = EchoRaidToolsDB.TodoList.adminOverrides[identifier] or {}


    table.insert(EchoRaidToolsDB.TodoList.adminOverrides[identifier],
        {
            fieldTable = fieldTable, -- todo rename path?
            value = value
        }
    )
end

function module:ResetAdminOverridesForMod(uid)
    EchoRaidToolsDB.TodoList.adminOverrides[uid] = nil
end

---@return table
function module:GetUserMods()
    local t = {}
    for i, modData in pairs(EchoRaidToolsDB.TodoList.userMods) do
        table.insert(t, module:DeepCopy(modData))
    end

    table.sort(t, function(a, b)
        local aIndex = a.index or math.huge
        local bIndex = b.index or math.huge

        return aIndex < bIndex or aIndex == bIndex and a.identifier < b.identifier
    end)
    return t
end

---@return table | nil
function module:GetUserMod(id)
    if not id then return end
    return EchoRaidToolsDB.TodoList.userMods[id]
end

function module:SaveModField(state, fieldTable, value)
    --print("set value", value, "in", unpack(fieldTable))
    if state.isDefaultMod then
        module:SetAdminOverride(state.identifier, fieldTable, value)
    else
        state.identifier = state.identifier or module.GenerateUid()
        EchoRaidToolsDB.TodoList.userMods[state.identifier] = EchoRaidToolsDB.TodoList.userMods[state.identifier] or
            { identifier = state.identifier }

        module:SetField(EchoRaidToolsDB.TodoList.userMods[state.identifier], fieldTable, value)
    end
end

function module:SaveUserMod(state)
    state.identifier = state.identifier or module.GenerateUid()
    EchoRaidToolsDB.TodoList.userMods[state.identifier] = state
    --module:ReloadModFromStorage(state.identifier)
end

function module:RemoveUserMod(identifier)
    if not identifier then return end
    module:RemoveMod(identifier)
    EchoRaidToolsDB.TodoList.userMods[identifier] = nil
    -- module:ReloadModFromStorage(identifier)
end

function module:GetDisplayInfo()
    local t = module:DeepCopy(EchoRaidToolsDB.TodoList.display)
    return t
end

function module.GetModuleState()
    return EchoRaidToolsDB.TodoList.moduleEnabled
end

function module.ToggleModuleState()
    EchoRaidToolsDB.TodoList.moduleEnabled = not EchoRaidToolsDB.TodoList.moduleEnabled
    module.updateLoadConditions()
end

function module:GetDefaultBarOptions()
    local displayInfo = module:GetDisplayInfo()
    return {
        { fieldTable = { "height" },               value = displayInfo.barSettings.height },
        { fieldTable = { "text" },                 value = displayInfo.barSettings.text },
        { fieldTable = { "font" },                 value = displayInfo.barSettings.font },
        { fieldTable = { "min" },                  value = 0 },
        { fieldTable = { "colour" },               value = displayInfo.barSettings.colour },
        { fieldTable = { "progressTextColour" },   value = displayInfo.barSettings.progressTextColour },
        { fieldTable = { "textColour" },           value = displayInfo.barSettings.textColour },
        { fieldTable = { "texture" },              value = displayInfo.barSettings.texture },
        { fieldTable = { "hideOnComplete" },       value = displayInfo.hideOnComplete },
        { fieldTable = { "progressTextFontSize" }, value = displayInfo.barSettings.progressTextFontSize },
        { fieldTable = { "textFontSize" },         value = displayInfo.barSettings.textFontSize },
        { fieldTable = { "bgColour" },             value = displayInfo.barSettings.bgColour },
    }
end

function module:applyDefaultFieldsToState(state)
    local options = module:GetDefaultBarOptions()
    for i, option in ipairs(options) do
        if module:GetField(state, option.fieldTable) == nil then
            module:SetField(state, option.fieldTable, module:DeepCopy(option.value))
        end
    end
end

function module:UpdateSetting(path, value)
    module:SetField(EchoRaidToolsDB.TodoList, path, value)
    module.display:updateDisplaySettings()
    module:ReloadAllModsFromStorage()
    module.updateLoadConditions()
    --TODO, make this smart and reload only what's necessary
end

function module:GetSetting(path)
    return module:GetField(EchoRaidToolsDB.TodoList, path)
end
