local addonName, addonTable = ...

local WipedQoL = LibStub("AceAddon-3.0"):NewAddon(
    addonName,
    "AceConsole-3.0",
    "AceEvent-3.0"
)

addonTable.WipedQoL = WipedQoL

local LDB = LibStub("LibDataBroker-1.1", true)
local LDBIcon = LibStub("LibDBIcon-1.0", true)
local TRANSLATE = addonTable.TRANSLATE or function(msg) return msg end

WipedQoL.defaults = {
    global = {
        debugLocaleOverride = nil,
        knownCharacters = {},
        autoBankGoldExcludedCharacters = {},
        deletedKnownCharacters = {},
        expansionVendorBlacklist = {},
        customSounds = {},
    },
    profile = {
        debugEnabled = false,
        addonColor = {
            mode = "class",
        },
        minimap = {
            hide = false,
        },
        window = {
            activeTab = "general",
            point = "CENTER",
            relativePoint = "CENTER",
            x = 0,
            y = 0,
            width = 700,
            height = 410,
        },
        modules = {
            autoBankGold = {
                enabled = false,
                targetGold = 10000,
            },
            warboundBankItems = {
                enabled = false,
            },
            expansionVendor = {
                enabled = true,
                anchorSide = "LEFT",
            },
            hideRaidFrameManager = false,
            achievementNavigation = {
                enabled = false,
            },
            questAutomation = {
                enabled = false,
                modifier = "SHIFT",
            },
            autoSignUp = {
                enabled = false,
                modifier = "SHIFT",
            },
            healthMacro = {
                includeClassHealingSpell = false,
                classSpells = {},
                classSpellDefaultsInitialized = {},
            },
            mountSound = {
                enabled = false,
                sound = "WipedQoL: Ante Up",
            },
            mountAnimation = {
                enabled = false,
            },
            deathSound = {
                enabled = false,
                sound = "WipedQoL: Garnixgemacht",
                random = false,
                randomSoundsInitialized = false,
                randomSoundsVersion = 0,
                randomSounds = {},
            },
            groupDeathSound = {
                enabled = false,
                sound = "WipedQoL: Konygebony",
                random = false,
                randomSoundsInitialized = false,
                randomSoundsVersion = 0,
                randomSounds = {},
            },
            keystoneCompletionSound = {
                enabled = false,
                sound = "WipedQoL: Ante Up",
                random = false,
                randomSoundsInitialized = false,
                randomSoundsVersion = 0,
                randomSounds = {},
            },
            autoLootRoll = {
                enabled = false,
                mode = "pass",
                legacyOnly = true,
            },
            raidLootHistory = {
                enabled = false,
            },
            topAccentBar = {
                enabled = true,
            },
            queueIndicator = {
                enabled = true,
                scale = 1,
                dock = "CENTER",
                ellesmereMinimap = false,
            },
            lootToasts = {
                enabled = false,
                unlocked = false,
                scale = 1,
                point = "BOTTOM",
                relativePoint = "BOTTOM",
                x = 0,
                y = 260,
            },
            lootRolls = {
                scale = 1,
                point = "CENTER",
                relativePoint = "CENTER",
                x = 0,
                y = 0,
            },
            bonusRolls = {
                scale = 1,
                point = "CENTER",
                relativePoint = "CENTER",
                x = 310,
                y = 0,
            },
            achievementAlerts = {
                scale = 1,
                point = "CENTER",
                relativePoint = "CENTER",
                x = 0,
                y = 180,
            },
            dungeonCompletionAlerts = {
                scale = 1,
                point = "CENTER",
                relativePoint = "CENTER",
                x = 0,
                y = 280,
            },
            challengeModeCompletion = {
                scale = 1,
                point = "TOP",
                relativePoint = "TOP",
                x = 0,
                y = -120,
            },
            monthlyActivityAlerts = {
                scale = 1,
                point = "CENTER",
                relativePoint = "CENTER",
                x = 0,
                y = 380,
            },
            datapanel = {
                enabled = false,
                locked = true,
                point = "TOP",
                relativePoint = "TOP",
                x = 0,
                y = 0,
                clock = {
                    enabled = true,
                    format = "24",
                },
                durability = {
                    enabled = true,
                },
                lootSpec = {
                    enabled = true,
                },
                autoLootRoll = {
                    enabled = false,
                },
                combatPotion = {
                    enabled = false,
                },
                fps = {
                    enabled = true,
                    fixed = true,
                    point = "TOP",
                    relativePoint = "TOP",
                    x = 0,
                    y = -28,
                },
            },
            weeklyTaskReminder = {
                enabled = false,
                autoHideCompleted = false,
                hiddenByCompleted = false,
                locked = false,
                attachToQuestTracker = false,
                questTrackerDock = "RIGHT",
                questTrackerHorizontalOffset = 0,
                questTrackerVerticalOffset = 0,
                point = "CENTER",
                relativePoint = "CENTER",
                x = 360,
                y = 0,
                width = 320,
                tasks = {},
                weekKey = nil,
            },
        },
    },
}

function WipedQoL:OnInitialize()
    self.db = LibStub("AceDB-3.0"):New("WipedQoLDB", self.defaults, true)

    local savedProfiles = _G.WipedQoLDB and _G.WipedQoLDB.profiles
    if type(savedProfiles) == "table" then
        for _, profile in pairs(savedProfiles) do
            if type(profile) == "table" and type(profile.modules) == "table" then
                profile.modules.battleNetToast = nil
            end
        end
    end

    self:SetupMinimapButton()
    self:RegisterChatCommand("wipedqol", "HandleSlashCommand")
    self:RegisterChatCommand("wqol", "HandleSlashCommand")
end

function WipedQoL:OnEnable()
    if self.RegisterKnownCharacter then
        self:RegisterKnownCharacter()
    end

    self:RegisterEvent("PLAYER_REGEN_DISABLED", "HandleCombatStarted")
    self:RegisterEvent("PLAYER_REGEN_ENABLED", "HandleCombatEnded")

    if self.ApplyRaidFrameManagerVisibility then
        self:ApplyRaidFrameManagerVisibility()
    end

    if self.SetupAutoBankGold then
        self:SetupAutoBankGold()
    end
    if self.SetupExpansionVendor then
        self:SetupExpansionVendor()
    end

    if self.SetupSounds then
        self:SetupSounds()
    end
    if self.SetupQuestAutomation then
        self:SetupQuestAutomation()
    end
    if self.SetupAchievementNavigation then
        self:SetupAchievementNavigation()
    end
    if self.SetupAutoSignUp then
        self:SetupAutoSignUp()
    end

    if self.InitializeLootToastMover then
        self:InitializeLootToastMover()
    end
    if self.InitializeRaidLootHistorySkin then
        self:InitializeRaidLootHistorySkin()
    end
    if self.InitializeQueueIndicator then
        self:InitializeQueueIndicator()
    end

    if self.SetupHealthMacro then
        self:SetupHealthMacro()
    end

    if self.SetupDatapanel then
        self:SetupDatapanel()
    end

    if self.SetupWeeklyTaskReminder then
        self:SetupWeeklyTaskReminder()
    end

    if self:IsDebugEnabled() then
        C_Timer.After(0.2, function()
            if self.ShowMainWindow then
                self:ShowMainWindow()
            end
        end)
    end
end

function WipedQoL:IsInCombat()
    return InCombatLockdown and InCombatLockdown() == true
end

function WipedQoL:HandleCombatStarted()
    self.mainWindowWasShownBeforeCombat = self:IsMainWindowShown()

    if self.CloseDatapanelMenus then
        self:CloseDatapanelMenus()
    end
    if self.CloseLootMoverAnchorsForCombat then
        self:CloseLootMoverAnchorsForCombat()
    end
    if self.RefreshDatapanelCombatPotion then
        self:RefreshDatapanelCombatPotion(true)
    end

    if self.mainWindowWasShownBeforeCombat and self.HideMainWindow then
        self:HideMainWindow()
    end
end

function WipedQoL:HandleCombatEnded()
    if self.RefreshPendingDatapanelLayout then
        self:RefreshPendingDatapanelLayout()
    end

    if self.RefreshDatapanelCombatPotion then
        self:RefreshDatapanelCombatPotion(true)
    end
    if not self.mainWindowWasShownBeforeCombat then
        return
    end

    self.mainWindowWasShownBeforeCombat = nil
    if self.ShowMainWindow then
        self:ShowMainWindow()
    end
end

function WipedQoL:PrintUsage()
    self:PrintDebug(TRANSLATE("/wqol - show window"))
    self:PrintDebug(TRANSLATE("/wqol debug on - enable debug mode"))
    self:PrintDebug(TRANSLATE("/wqol debug off - disable debug mode"))
    self:PrintDebug(TRANSLATE("/wqol minimap - toggle minimap button"))
    if self:IsDebugEnabled() then
        self:PrintDebug(TRANSLATE("/wqol locale en - use English after the next /reload"))
        self:PrintDebug(TRANSLATE("/wqol locale de - use German after the next /reload"))
        self:PrintDebug(TRANSLATE("/wqol locale reset - use client locale again after the next /reload"))
        self:PrintDebug(TRANSLATE("/wqol testdata on - add debug test data"))
        self:PrintDebug(TRANSLATE("/wqol testdata off - remove debug test data"))
    end
end

function WipedQoL:HandleSlashCommand(input)
    input = strtrim((input or ""):lower())
    local command, value = strsplit(" ", input, 2)
    value = value and strtrim(value) or nil

    if command == "debug" then
        if value == "on" or value == "1" or value == "true" then
            self:SetDebugEnabled(true)
        elseif value == "off" or value == "0" or value == "false" then
            self:SetDebugEnabled(false)
        else
            self:PrintDebug(self:IsDebugEnabled() and TRANSLATE("Debug mode is enabled.") or TRANSLATE("Debug mode is disabled."))
            self:PrintDebug(TRANSLATE("Use /wqol debug on or /wqol debug off."))
        end
        return
    end

    if command == "locale" then
        if not self:IsDebugEnabled() then
            return
        end

        if value == "de" or value == "dede" or value == "deutsch" or value == "german" then
            self:SetDebugLocaleOverride("deDE")
            self:PrintDebug(TRANSLATE("Locale override saved: German will load after the next /reload."))
        elseif value == "en" or value == "enus" or value == "english" then
            self:SetDebugLocaleOverride("enUS")
            self:PrintDebug(TRANSLATE("Locale override saved: English will load after the next /reload."))
        elseif value == "reset" or value == "auto" or value == "clear" then
            self:SetDebugLocaleOverride(nil)
            self:PrintDebug(TRANSLATE("Locale override cleared: client locale will be used again after the next /reload."))
        else
            self:PrintDebug(TRANSLATE("Use /wqol locale en, /wqol locale de or /wqol locale reset."))
        end
        return
    end

    if command == "testdata" then
        if not self:IsDebugEnabled() then
            return
        end

        if value == "on" or value == "1" or value == "true" then
            if self.SetDebugTestDataEnabled then
                self:SetDebugTestDataEnabled(true)
            end
        elseif value == "off" or value == "0" or value == "false" or value == "clear" then
            if self.SetDebugTestDataEnabled then
                self:SetDebugTestDataEnabled(false)
            end
        else
            self:PrintDebug(TRANSLATE("Use /wqol testdata on or /wqol testdata off."))
        end
        return
    end

    if command == "minimap" then
        self:SetMinimapHidden(not self:IsMinimapHidden())
        return
    end

    if command == "help" or command == "?" then
        self:PrintUsage()
        return
    end

    self:ToggleMainWindow()
end

function WipedQoL:IsDebugEnabled()
    return self.db and self.db.profile and self.db.profile.debugEnabled == true
end

function WipedQoL:SetDebugEnabled(enabled)
    if not self.db or not self.db.profile then
        return
    end

    self.db.profile.debugEnabled = enabled and true or false
    if self.mainWindow and self.mainWindow.debugReloadButton then
        self.mainWindow.debugReloadButton:SetShown(self.db.profile.debugEnabled)
    end
    self:PrintDebug(self.db.profile.debugEnabled and TRANSLATE("Debug mode enabled. The window will open automatically after reload.") or TRANSLATE("Debug mode disabled."))

end

function WipedQoL:PrintDebug(message, ...)
    if not self:IsDebugEnabled() then
        return
    end

    if select("#", ...) > 0 then
        message = string.format(message, ...)
    end

    self:Print(message)
end

function WipedQoL:DebugLog(message, ...)
    if not self:IsDebugEnabled() then
        return
    end

    if select("#", ...) > 0 then
        message = string.format(message, ...)
    end

    self:PrintDebug(string.format("[Debug] %s", tostring(message)))
end

function WipedQoL:GetDebugLocaleOverride()
    return self.db and self.db.global and self.db.global.debugLocaleOverride or nil
end

function WipedQoL:SetDebugLocaleOverride(locale)
    if not self.db or not self.db.global then
        return
    end

    if locale ~= "deDE" and locale ~= "enUS" then
        locale = nil
    end

    self.db.global.debugLocaleOverride = locale

    if addonTable.SetActiveLocaleOverride then
        addonTable.SetActiveLocaleOverride(locale)
    end

    if self.RefreshLocale then
        self:RefreshLocale()
    end
end

function WipedQoL:SetupMinimapButton()
    if not LDB or not LDBIcon or self.minimapObject then
        return
    end

    self.minimapObject = LDB:NewDataObject("WipedQoL", {
        type = "launcher",
        text = "WipedQoL",
        icon = "Interface\\Icons\\INV_Misc_Gear_01",
        OnClick = function(_, button)
            if button == "LeftButton" then
                self:ToggleMainWindow()
            end
        end,
        OnTooltipShow = function(tooltip)
            tooltip:AddLine("WipedQoL")
            tooltip:AddLine(TRANSLATE("Left click: Show window"), 1, 1, 1)
        end,
    })

    LDBIcon:Register("WipedQoL", self.minimapObject, self.db.profile.minimap)
end
