local _, addonTable = ...
local WipedQoL = addonTable.WipedQoL
local UI = addonTable.UI
local TRANSLATE = addonTable.TRANSLATE or function(msg) return msg end

local DOCK_OPTIONS = {
    { "TOPLEFT", "TOP", "TOPRIGHT" },
    { "LEFT", "CENTER", "RIGHT" },
    { "BOTTOMLEFT", "BOTTOM", "BOTTOMRIGHT" },
}

local function CreateDockButton(parent)
    local button = CreateFrame("Button", nil, parent)
    button:SetSize(18, 18)

    button.dot = button:CreateTexture(nil, "ARTWORK")
    button.dot:SetPoint("CENTER")
    button.dot:SetColorTexture(0.55, 0.55, 0.55, 0.85)

    function button:SetActive(active)
        local r, g, b = UI.GetClassColor()
        self.dot:SetSize(active and 10 or 6, active and 10 or 6)
        if active then
            self.dot:SetColorTexture(r, g, b, 1)
        else
            self.dot:SetColorTexture(0.55, 0.55, 0.55, 0.85)
        end
    end

    button:SetScript("OnEnter", function(self)
        if not self:IsEnabled() then
            return
        end
        self.dot:SetAlpha(1)
    end)
    button:SetScript("OnLeave", function(self)
        self.dot:SetAlpha(1)
    end)
    button:SetActive(false)
    return button
end

WipedQoL:RegisterTabBuilder("skinning", function(addon, parent)
    local hasEllesmereMinimap = addon.IsEllesmereMinimapActive
        and addon:IsEllesmereMinimapActive()
    local frame = CreateFrame("Frame", nil, parent)
    local scrollFrame = CreateFrame("ScrollFrame", nil, frame)
    scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0)
    scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -18, 0)
    scrollFrame:EnableMouseWheel(true)
    if scrollFrame.SetClipsChildren then
        scrollFrame:SetClipsChildren(true)
    end

    local scrollChild = CreateFrame("Frame", nil, scrollFrame)
    scrollChild:SetHeight(hasEllesmereMinimap and 422 or 390)
    scrollFrame:SetScrollChild(scrollChild)

    local scrollbar = CreateFrame("Slider", nil, frame, "BackdropTemplate")
    scrollbar:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -2, -4)
    scrollbar:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -2, 4)
    scrollbar:SetWidth(10)
    scrollbar:SetOrientation("VERTICAL")
    scrollbar:SetValueStep(18)
    scrollbar:SetHitRectInsets(-5, -5, 0, 0)
    UI.SkinFrame(scrollbar, { light = true })
    scrollbar:SetThumbTexture("Interface\\Buttons\\WHITE8X8")
    local scrollbarThumb = scrollbar:GetThumbTexture()
    if scrollbarThumb then
        scrollbarThumb:SetSize(10, 34)
        UI.SetAddonColor(scrollbarThumb, "SetVertexColor")
    end

    local function RefreshScrollRange()
        local viewportHeight = scrollFrame:GetHeight() or 0
        local contentHeight = scrollChild:GetHeight() or 0
        local maxScroll = math.max(contentHeight - viewportHeight, 0)
        local current = math.min(scrollbar:GetValue() or 0, maxScroll)

        scrollChild:SetWidth(math.max(scrollFrame:GetWidth() or 1, 1))
        scrollbar:SetMinMaxValues(0, maxScroll)
        scrollbar:SetValue(current)
        scrollbar:SetShown(maxScroll > 0)
        scrollFrame:SetVerticalScroll(current)
    end

    scrollbar:SetScript("OnValueChanged", function(_, value)
        scrollFrame:SetVerticalScroll(value or 0)
    end)
    scrollFrame:SetScript("OnMouseWheel", function(_, delta)
        local minValue, maxValue = scrollbar:GetMinMaxValues()
        local value = scrollbar:GetValue() or minValue
        scrollbar:SetValue(math.max(minValue, math.min(maxValue, value - (delta * 36))))
    end)
    scrollFrame:SetScript("OnSizeChanged", RefreshScrollRange)

    local queueSection = UI.CreateSection(
        scrollChild,
        TRANSLATE("Queue indicator"),
        TRANSLATE("Replaces Blizzard's queue eye with another indicator.")
    )
    queueSection:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 14, -14)
    queueSection:SetPoint("TOPRIGHT", scrollChild, "TOPRIGHT", -14, -14)
    queueSection:SetHeight(hasEllesmereMinimap and 206 or 174)

    local queueCheckbox = UI.CreateSectionToggle(queueSection, function()
        return addon:IsQueueIndicatorEnabled()
    end, function(value)
        addon:SetQueueIndicatorEnabled(value)
    end)

    local queueScaleLabel = UI.CreateLabel(queueSection, TRANSLATE("Scale"), 11)
    queueScaleLabel:SetPoint("TOPLEFT", queueSection.description, "BOTTOMLEFT", 0, -14)

    local queueScaleSlider = CreateFrame("Slider", nil, queueSection, "BackdropTemplate")
    queueScaleSlider:SetSize(180, 10)
    queueScaleSlider:SetPoint("LEFT", queueScaleLabel, "RIGHT", 10, 0)
    queueScaleSlider:SetOrientation("HORIZONTAL")
    queueScaleSlider:SetMinMaxValues(50, 100)
    queueScaleSlider:SetValueStep(1)
    if queueScaleSlider.SetObeyStepOnDrag then
        queueScaleSlider:SetObeyStepOnDrag(true)
    end
    queueScaleSlider:SetHitRectInsets(0, 0, -8, -8)
    UI.SkinFrame(queueScaleSlider, { light = true })
    queueScaleSlider:SetThumbTexture("Interface\\Buttons\\WHITE8X8")
    local queueScaleThumb = queueScaleSlider:GetThumbTexture()
    if queueScaleThumb then
        queueScaleThumb:SetSize(8, 16)
        UI.SetAddonColor(queueScaleThumb, "SetVertexColor")
    end

    local queueScaleValue = UI.CreateLabel(queueSection, "", 11)
    queueScaleValue:SetPoint("LEFT", queueScaleSlider, "RIGHT", 8, 0)
    queueScaleValue:SetWidth(38)
    queueScaleSlider:SetScript("OnValueChanged", function(self, value)
        local percent = math.floor((value or 100) + 0.5)
        queueScaleValue:SetText(string.format("%d%%", percent))
        if not self._wqolRefreshing then
            addon:SetQueueIndicatorScale(percent / 100)
        end
    end)

    local queueTestButton = CreateFrame("Button", nil, queueSection, "UIPanelButtonTemplate")
    queueTestButton:SetSize(92, 24)
    queueTestButton:SetText(TRANSLATE("Preview"))
    queueTestButton:SetScript("OnClick", function()
        addon:ShowQueueIndicatorTest()
    end)
    UI.SkinButton(queueTestButton)

    local queueResetButton = CreateFrame("Button", nil, queueSection, "UIPanelButtonTemplate")
    queueResetButton:SetSize(82, 24)
    queueResetButton:SetText(TRANSLATE("Reset"))
    queueResetButton:SetScript("OnClick", function()
        addon:ResetQueueIndicator()
    end)
    UI.SkinButton(queueResetButton)

    local queueDockLabel = UI.CreateLabel(queueSection, string.format("%s:", TRANSLATE("Dock")), 11)
    queueDockLabel:SetPoint("TOPLEFT", queueScaleLabel, "BOTTOMLEFT", 0, -22)
    queueDockLabel:SetTextColor(0.78, 0.78, 0.78)

    local queueDockGrid = CreateFrame("Frame", nil, queueSection)
    queueDockGrid:SetSize(54, 54)
    queueDockGrid:SetPoint("TOPLEFT", queueDockLabel, "TOPRIGHT", 10, 8)
    local queueDockButtons = {}
    for row, values in ipairs(DOCK_OPTIONS) do
        for column, value in ipairs(values) do
            local button = CreateDockButton(queueDockGrid)
            button:SetPoint("TOPLEFT", queueDockGrid, "TOPLEFT", (column - 1) * 18, -((row - 1) * 18))
            button:SetScript("OnClick", function()
                addon:SetQueueIndicatorDock(value)
            end)
            queueDockButtons[value] = button
        end
    end

    queueResetButton:SetPoint("TOPLEFT", queueDockGrid, "TOPRIGHT", 28, 0)
    queueTestButton:SetPoint("TOPLEFT", queueResetButton, "BOTTOMLEFT", 0, -7)

    local ellesmereCheckbox
    if hasEllesmereMinimap then
        ellesmereCheckbox = UI.CreateCheckBox(
            queueSection,
            TRANSLATE("Integrate into the EllesmereUI minimap button row"),
            function()
                return addon:IsEllesmereQueueIndicatorEnabled()
            end,
            function(value)
                addon:SetEllesmereQueueIndicatorEnabled(value)
            end
        )
        ellesmereCheckbox:SetPoint("BOTTOMLEFT", queueSection, "BOTTOMLEFT", 10, 7)
    end

    function addon:RefreshQueueIndicatorSkinningUI()
        local enabled = addon:IsQueueIndicatorEnabled()
        local ellesmereEnabled = hasEllesmereMinimap
            and addon:IsEllesmereQueueIndicatorEnabled()
        local percent = math.floor((addon:GetQueueIndicatorScale() * 100) + 0.5)
        if queueCheckbox and queueCheckbox.Refresh then
            queueCheckbox.Refresh()
        end
        queueScaleSlider._wqolRefreshing = true
        queueScaleSlider:SetValue(percent)
        queueScaleSlider._wqolRefreshing = false
        queueScaleValue:SetText(string.format("%d%%", percent))
        queueScaleLabel:SetTextColor(enabled and 0.78 or 0.38, enabled and 0.78 or 0.38, enabled and 0.78 or 0.38)
        queueScaleValue:SetTextColor(enabled and 0.82 or 0.42, enabled and 0.82 or 0.42, enabled and 0.82 or 0.42)
        queueScaleSlider:SetAlpha(enabled and 1 or 0.45)
        queueScaleSlider:EnableMouse(enabled)
        for value, button in pairs(queueDockButtons) do
            button:SetActive(value == addon:GetQueueIndicatorDock())
            button:SetAlpha(enabled and not ellesmereEnabled and 1 or 0.45)
            button:EnableMouse(enabled and not ellesmereEnabled)
        end
        queueDockLabel:SetTextColor(
            enabled and not ellesmereEnabled and 0.78 or 0.38,
            enabled and not ellesmereEnabled and 0.78 or 0.38,
            enabled and not ellesmereEnabled and 0.78 or 0.38
        )
        for _, button in ipairs({ queueResetButton, queueTestButton }) do
            button:SetAlpha(enabled and 1 or 0.45)
            button:EnableMouse(enabled)
        end
        if ellesmereCheckbox then
            ellesmereCheckbox:Refresh()
            ellesmereCheckbox:SetAlpha(enabled and 1 or 0.45)
            ellesmereCheckbox:EnableMouse(enabled)
        end
    end

    addon:RefreshQueueIndicatorSkinningUI()

    local raidLootHistorySection = UI.CreateSection(
        scrollChild,
        TRANSLATE("Raid loot window"),
        TRANSLATE("Skins the raid loot history opened with /loot. Enabling or disabling takes effect after reloading the UI.")
    )
    raidLootHistorySection:SetPoint("TOPLEFT", queueSection, "BOTTOMLEFT", 0, -12)
    raidLootHistorySection:SetPoint("TOPRIGHT", queueSection, "BOTTOMRIGHT", 0, -12)
    raidLootHistorySection:SetHeight(98)

    local raidLootHistoryCheckbox = UI.CreateSectionToggle(raidLootHistorySection, function()
        return addon:IsRaidLootHistorySkinEnabled()
    end, function(value)
        addon:SetRaidLootHistorySkinEnabled(value)
    end)

    local raidLootHistoryReloadButton = CreateFrame("Button", nil, raidLootHistorySection, "UIPanelButtonTemplate")
    raidLootHistoryReloadButton:SetSize(72, 24)
    raidLootHistoryReloadButton:SetPoint("TOPLEFT", raidLootHistorySection.description, "BOTTOMLEFT", 0, -10)
    raidLootHistoryReloadButton:SetText("/reload")
    raidLootHistoryReloadButton:SetScript("OnClick", ReloadUI)
    UI.SkinButton(raidLootHistoryReloadButton)

    function addon:RefreshRaidLootHistorySkinningUI()
        raidLootHistoryCheckbox:Refresh()
        raidLootHistoryReloadButton:SetShown(addon.raidLootHistorySkinReloadSuggested == true)
    end

    local topAccentSection = UI.CreateSection(
        scrollChild,
        TRANSLATE("Top accent bar"),
        TRANSLATE("Shows the same top accent bar in the raid loot and Weekly Task Reminder windows.")
    )
    topAccentSection:SetPoint("TOPLEFT", raidLootHistorySection, "BOTTOMLEFT", 0, -12)
    topAccentSection:SetPoint("TOPRIGHT", raidLootHistorySection, "BOTTOMRIGHT", 0, -12)
    topAccentSection:SetHeight(58)

    local topAccentCheckbox = UI.CreateSectionToggle(topAccentSection, function()
        return addon:IsTopAccentBarEnabled()
    end, function(value)
        addon:SetTopAccentBarEnabled(value)
    end)

    local function RefreshTopAccentBarState()
        topAccentCheckbox:Refresh()
    end

    function addon:RefreshTopAccentBarSkinningUI()
        RefreshTopAccentBarState()
    end

    addon:RefreshRaidLootHistorySkinningUI()
    RefreshTopAccentBarState()
    RefreshScrollRange()
    return frame
end)
