local addonName, SinsToolkit = ...

SinsToolkit.UI = SinsToolkit.UI or {}
SinsToolkit.UI.Pages = SinsToolkit.UI.Pages or {}

local PageBase = SinsToolkit.UI.Pages.Base or {}
local Helpers = SinsToolkit.UI.Pages.Helpers or {}
local Page = {}
setmetatable(Page, { __index = PageBase })
SinsToolkit.UI.Pages.UIErrors = Page
Page.density = Helpers.GetDefaultDensity and Helpers.GetDefaultDensity() or "compact"

function Page:Create(CreateScrollablePage, Window, CreateWrappedText)
    local getGV = Helpers.GetGV
    local setGV = Helpers.SetGV

    local errorsPage = Helpers.CreateContentPage(Window, "UI Errors")
    local errHeader = Window:CreateSectionHeader(errorsPage, "UI Errors")
    CreateWrappedText(errorsPage, {"TOPLEFT", errHeader, "BOTTOMLEFT", 0, -8}, 720, "Choose which red UI error messages Sin's Toolkit should block. Checked messages are blocked and sorted to the top; unchecked messages are allowed through normally.", "GameFontHighlightSmall")
    local cbErrEnable = Window:CreateCheckbox(errorsPage, "Enable UI Error Filtering", getGV("hideOutOfRangeErrors"), setGV("hideOutOfRangeErrors"), "Enable or disable the filtering of UI error messages entirely.")
    cbErrEnable:SetPoint("TOPLEFT", errHeader, "BOTTOMLEFT", 0, -50)
    local errSearch = Window:CreateEditBox(errorsPage, "Search Errors", 260, 24, function() return Window.errorSearchString or "" end, function(v) Window.errorSearchString = v; if Window.RefreshUIErrorsList then Window:RefreshUIErrorsList() end end, "Filter the error list below. Text updates dynamically.")
    errSearch:SetPoint("TOPLEFT", cbErrEnable, "BOTTOMLEFT", 4, -24)
    local errListBg = CreateFrame("Frame", nil, errorsPage, "BackdropTemplate")
    errListBg:SetPoint("TOPLEFT", errSearch, "BOTTOMLEFT", -4, -14)
    errListBg:SetPoint("BOTTOMRIGHT", errorsPage, "BOTTOMRIGHT", -12, 8)
    Helpers.ApplyListBackdrop(errListBg, 0.05, 0.05, 0.05, 0.85, 0.35, 0.18, 0.55, 1)
    local errScroll = CreateFrame("ScrollFrame", nil, errListBg, "UIPanelScrollFrameTemplate")
    errScroll:SetPoint("TOPLEFT", 4, -4)
    errScroll:SetPoint("BOTTOMRIGHT", -28, 4)
    local errScrollChild = CreateFrame("Frame", nil, errScroll)
    errScrollChild:SetSize(580, 1)
    errScroll:SetScrollChild(errScrollChild)
    local errButtons = {}
    local uiErrorCache
    local function GetStandaloneUIErrors()
        if uiErrorCache then return uiErrorCache end
        uiErrorCache = {}
        local grouped = {}
        if GetGameMessageInfo then
            for i = 1, 1600 do
                local key = GetGameMessageInfo(i)
                local text = key and _G[key]
                if key and key:match("^ERR_") and text and text ~= "" then
                    local entry = grouped[text]
                    if not entry then
                        entry = { key = key, keys = {}, text = text, search = (key .. " " .. text):lower() }
                        grouped[text] = entry
                        uiErrorCache[#uiErrorCache + 1] = entry
                    end
                    entry.keys[#entry.keys + 1] = key
                end
            end
        end
        table.sort(uiErrorCache, function(a, b) return a.text < b.text end)
        return uiErrorCache
    end
    local function IsErrorBlocked(entry)
        local blocked = SinsToolkitDB and SinsToolkitDB.blockedUIErrors
        if not blocked then return false end
        for _, key in ipairs(entry.keys) do
            if blocked[key] == true then return true end
        end
        return false
    end
    function Window:RefreshUIErrorsList()
        for _, button in ipairs(errButtons) do button:Hide() end
        local search = (Window.errorSearchString or ""):lower()
        local filtered = {}
        for _, entry in ipairs(GetStandaloneUIErrors()) do
            if search == "" or entry.search:find(search, 1, true) then
                filtered[#filtered + 1] = entry
            end
        end
        table.sort(filtered, function(a, b)
            local aBlocked, bBlocked = IsErrorBlocked(a), IsErrorBlocked(b)
            if aBlocked ~= bBlocked then return aBlocked end
            return a.text < b.text
        end)
        local y = 0
        for i, entry in ipairs(filtered) do
            if i > 120 then break end
            local cb = errButtons[i]
            if not cb then
                cb = nil
                cb = Window:CreateCheckbox(errScrollChild, "", function() return cb and cb.entry and IsErrorBlocked(cb.entry) end, function(value)
                    if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
                    SinsToolkitDB.blockedUIErrors = SinsToolkitDB.blockedUIErrors or {}
                    if cb and cb.entry then
                        for _, key in ipairs(cb.entry.keys) do SinsToolkitDB.blockedUIErrors[key] = value or nil end
                    end
                    if SinsToolkit.TriggerUpdate then SinsToolkit.TriggerUpdate("blockedUIErrors") end
                    Window:RefreshUIErrorsList()
                end)
                errButtons[i] = cb
            end
            cb.entry = entry
            cb:SetPoint("TOPLEFT", 0, y)
            local label = _G[cb:GetName() .. "Text"]
            if label then label:SetText(entry.text) end
            cb:SetChecked(IsErrorBlocked(entry))
            cb:Show()
            y = y - 28
        end
        errScrollChild:SetHeight(math.max(1, -y))
    end
    errorsPage.OnShowCallback = function() Window:RefreshUIErrorsList() end

    self.frame = errorsPage
    return errorsPage
end

Page:Register("UI Errors")

return Page
