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

local QUEST_TRACKER_DOCK_OPTIONS = {
    { value = "TOP", label = "Top" },
    { value = "BOTTOM", label = "Bottom" },
    { value = "LEFT", label = "Left" },
    { value = "RIGHT", label = "Right" },
}
local OFFSET_MIN = -200
local OFFSET_MAX = 200

local function NormalizeOffset(value)
    return math.max(OFFSET_MIN, math.min(math.floor((tonumber(value) or 0) + 0.5), OFFSET_MAX))
end

local function SetMuted(control, muted)
    if not control then
        return
    end

    control:SetAlpha(muted and 0.45 or 1)
    control:EnableMouse(not muted)
    if control.label then
        control.label:SetTextColor(muted and 0.45 or 0.92, muted and 0.45 or 0.92, muted and 0.45 or 0.92)
    end
end

local function SetLabelEnabled(label, enabled)
    if label then
        label:SetTextColor(enabled and 0.78 or 0.38, enabled and 0.78 or 0.38, enabled and 0.78 or 0.38)
    end
end

local function SetControlEnabled(control, enabled)
    if not control then
        return
    end

    control:SetAlpha(enabled and 1 or 0.45)
    control:EnableMouse(enabled)
    if control.SetTextColor then
        local color = enabled and 1 or 0.45
        control:SetTextColor(color, color, color, 1)
    end
    if not enabled and control.ClearFocus and control.HasFocus and control:HasFocus() then
        control:ClearFocus()
    end
end

local function CreateOffsetSlider(parent, width)
    local slider = CreateFrame("Slider", nil, parent, "BackdropTemplate")
    slider:SetSize(width or 170, 10)
    slider:SetOrientation("HORIZONTAL")
    slider:SetMinMaxValues(OFFSET_MIN, OFFSET_MAX)
    slider:SetValueStep(1)
    if slider.SetObeyStepOnDrag then
        slider:SetObeyStepOnDrag(true)
    end
    if UI and UI.SkinFrame then
        UI.SkinFrame(slider, { light = true })
    end

    slider:SetThumbTexture("Interface\\Buttons\\WHITE8X8")
    local thumb = slider:GetThumbTexture()
    if thumb then
        thumb:SetSize(8, 18)
        UI.SetAddonColor(thumb, "SetVertexColor", 1, 0.95)
    end

    return slider
end

local function CreateOffsetInput(parent, getter, setter)
    local input
    input = UI.CreateEditBox(parent, function()
        return tostring(getter() or 0)
    end, function(value)
        local offset = NormalizeOffset(value)
        setter(offset)
        input:SetText(tostring(getter() or offset))
    end)
    input:SetSize(42, 22)
    input:SetMaxLetters(4)
    input:SetJustifyH("CENTER")
    input:SetTextInsets(4, 4, 0, 0)
    input:SetScript("OnEscapePressed", function(self)
        self:SetText(tostring(getter() or 0))
        self:ClearFocus()
    end)
    return input
end

local function CreateTextButton(parent, width, label)
    local button = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    button:SetSize(width or 120, 26)
    button:SetText(label)
    if UI and UI.SkinButton then
        UI.SkinButton(button)
    end
    return button
end

local function CreateAddTaskBox(parent)
    local box = CreateFrame("EditBox", nil, parent, "InputBoxTemplate")
    box:SetAutoFocus(false)
    box:SetTextInsets(8, 8, 0, 0)
    box:SetHeight(26)
    if UI and UI.ApplyFont then
        UI.ApplyFont(box, 12, "")
    end
    if box.Left then box.Left:Hide() end
    if box.Middle then box.Middle:Hide() end
    if box.Right then box.Right:Hide() end
    if UI and UI.SkinFrame then
        UI.SkinFrame(box, { light = true })
    end

    local border = {}
    border.top = box:CreateTexture(nil, "OVERLAY")
    border.bottom = box:CreateTexture(nil, "OVERLAY")
    border.left = box:CreateTexture(nil, "OVERLAY")
    border.right = box:CreateTexture(nil, "OVERLAY")

    border.top:SetPoint("TOPLEFT", box, "TOPLEFT", 0, 0)
    border.top:SetPoint("TOPRIGHT", box, "TOPRIGHT", 0, 0)
    border.top:SetHeight(1)

    border.bottom:SetPoint("BOTTOMLEFT", box, "BOTTOMLEFT", 0, 0)
    border.bottom:SetPoint("BOTTOMRIGHT", box, "BOTTOMRIGHT", 0, 0)
    border.bottom:SetHeight(1)

    border.left:SetPoint("TOPLEFT", box, "TOPLEFT", 0, 0)
    border.left:SetPoint("BOTTOMLEFT", box, "BOTTOMLEFT", 0, 0)
    border.left:SetWidth(1)

    border.right:SetPoint("TOPRIGHT", box, "TOPRIGHT", 0, 0)
    border.right:SetPoint("BOTTOMRIGHT", box, "BOTTOMRIGHT", 0, 0)
    border.right:SetWidth(1)

    for _, edge in pairs(border) do
        edge:SetTexture("Interface\\Buttons\\WHITE8X8")
        UI.SetAddonColor(edge, "SetVertexColor", 1, 0.95)
    end

    return box
end

local function CreatePlusButton(parent)
    local button = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    button:SetSize(28, 26)
    button:SetText("")
    if UI and UI.SkinButton then
        UI.SkinButton(button)
    end

    button.plus = button:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    button.plus:SetPoint("CENTER", button, "CENTER", 0, 0)
    button.plus:SetText("+")
    if UI and UI.ApplyFont then
        UI.ApplyFont(button.plus, 16, "")
    end

    return button
end

WipedQoL:RegisterTabBuilder("weeklyTasks", function(addon, parent)
    local frame = CreateFrame("Frame", nil, parent)
    local settings = addon:GetWeeklyTaskReminderSettings()
    local enabledCheckbox
    local lockCheckbox
    local attachCheckbox
    local autoHideCheckbox
    local dockLabel
    local dockDropdown
    local horizontalOffsetLabel
    local horizontalOffsetSlider
    local horizontalOffsetValue
    local verticalOffsetLabel
    local verticalOffsetSlider
    local verticalOffsetValue
    local resetButton
    local addBox
    local addButton
    local autoHideHint

    local function RefreshState()
        settings = addon:GetWeeklyTaskReminderSettings()
        local reminderEnabled = settings.enabled == true
        local questTrackerAttached = settings.attachToQuestTracker == true
        local dockControlsEnabled = reminderEnabled and questTrackerAttached
        if enabledCheckbox and enabledCheckbox.Refresh then
            enabledCheckbox.Refresh()
        end
        if lockCheckbox and lockCheckbox.Refresh then
            lockCheckbox.Refresh()
            SetMuted(lockCheckbox, not reminderEnabled or questTrackerAttached)
        end
        if attachCheckbox and attachCheckbox.Refresh then
            attachCheckbox.Refresh()
            SetMuted(attachCheckbox, not reminderEnabled)
        end
        if autoHideCheckbox and autoHideCheckbox.Refresh then
            autoHideCheckbox.Refresh()
            SetMuted(autoHideCheckbox, not reminderEnabled)
        end
        SetLabelEnabled(autoHideHint, reminderEnabled)
        SetLabelEnabled(dockLabel, dockControlsEnabled)
        if dockDropdown then
            dockDropdown:SetAlpha(dockControlsEnabled and 1 or 0.45)
            if dockDropdown._wqolClickOverlay then
                dockDropdown._wqolClickOverlay:EnableMouse(dockControlsEnabled)
            end
            if dockDropdown.RefreshText then
                dockDropdown.RefreshText()
            end
        end
        SetLabelEnabled(horizontalOffsetLabel, dockControlsEnabled)
        if horizontalOffsetSlider then
            local offset = addon:GetWeeklyTaskReminderQuestTrackerHorizontalOffset()
            horizontalOffsetSlider._wqolRefreshing = true
            horizontalOffsetSlider:SetValue(offset)
            horizontalOffsetSlider._wqolRefreshing = false
            horizontalOffsetSlider:SetAlpha(dockControlsEnabled and 1 or 0.45)
            horizontalOffsetSlider:EnableMouse(dockControlsEnabled)
            if horizontalOffsetValue then
                horizontalOffsetValue:SetText(tostring(offset))
                SetControlEnabled(horizontalOffsetValue, dockControlsEnabled)
            end
        end
        SetLabelEnabled(verticalOffsetLabel, dockControlsEnabled)
        if verticalOffsetSlider then
            local offset = addon:GetWeeklyTaskReminderQuestTrackerVerticalOffset()
            verticalOffsetSlider._wqolRefreshing = true
            verticalOffsetSlider:SetValue(offset)
            verticalOffsetSlider._wqolRefreshing = false
            verticalOffsetSlider:SetAlpha(dockControlsEnabled and 1 or 0.45)
            verticalOffsetSlider:EnableMouse(dockControlsEnabled)
            if verticalOffsetValue then
                verticalOffsetValue:SetText(tostring(offset))
                SetControlEnabled(verticalOffsetValue, dockControlsEnabled)
            end
        end
        SetControlEnabled(resetButton, reminderEnabled)
        SetControlEnabled(addBox, reminderEnabled)
        SetControlEnabled(addButton, reminderEnabled)
        if not reminderEnabled and addBox and addBox.HasFocus and addBox:HasFocus() then
            addBox:ClearFocus()
        end
    end

    function addon:RefreshWeeklyTaskReminderOptionsUI()
        RefreshState()
    end

    local reminderSection = UI.CreateSection(
        frame,
        TRANSLATE("Weekly Task Reminder"),
        TRANSLATE("Shows a separate checklist window for recurring weekly tasks.")
    )
    reminderSection:SetPoint("TOPLEFT", frame, "TOPLEFT", 14, -14)
    reminderSection:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -14, -14)
    reminderSection:SetHeight(204)

    enabledCheckbox = UI.CreateSectionToggle(reminderSection, function()
        return settings.enabled == true
    end, function(value)
        addon:SetWeeklyTaskReminderEnabled(value)
        RefreshState()
    end)

    lockCheckbox = UI.CreateCheckBox(reminderSection, TRANSLATE("Lock reminder window"), function()
        return settings.locked == true
    end, function(value)
        addon:SetWeeklyTaskReminderLocked(value)
        RefreshState()
    end)
    lockCheckbox:SetPoint("TOPLEFT", reminderSection.description, "BOTTOMLEFT", 0, -10)
    lockCheckbox:SetSize(250, 24)

    attachCheckbox = UI.CreateCheckBox(reminderSection, TRANSLATE("Attach to quest tracker"), function()
        return settings.attachToQuestTracker == true
    end, function(value)
        addon:SetWeeklyTaskReminderAttachToQuestTracker(value)
        RefreshState()
    end)
    attachCheckbox:SetPoint("TOPLEFT", lockCheckbox, "BOTTOMLEFT", 0, -8)
    attachCheckbox:SetSize(250, 24)

    dockLabel = UI.CreateLabel(reminderSection, string.format("%s:", TRANSLATE("Position")), 12)
    dockLabel:SetPoint("LEFT", attachCheckbox, "LEFT", 280, 0)
    dockLabel:SetTextColor(0.78, 0.78, 0.78)

    dockDropdown = UI.CreateDropdown(reminderSection, 112, QUEST_TRACKER_DOCK_OPTIONS, function()
        return addon:GetWeeklyTaskReminderQuestTrackerDock()
    end, function(value)
        addon:SetWeeklyTaskReminderQuestTrackerDock(value)
        RefreshState()
    end)
    dockDropdown:SetPoint("LEFT", dockLabel, "RIGHT", -12, 0)

    horizontalOffsetLabel = UI.CreateLabel(reminderSection, string.format("%s:", TRANSLATE("Horizontal offset")), 12)
    horizontalOffsetLabel:SetPoint("TOPLEFT", attachCheckbox, "BOTTOMLEFT", 0, -12)
    horizontalOffsetLabel:SetWidth(112)
    horizontalOffsetLabel:SetTextColor(0.78, 0.78, 0.78)

    horizontalOffsetSlider = CreateOffsetSlider(reminderSection, 112)
    horizontalOffsetSlider:SetPoint("LEFT", horizontalOffsetLabel, "RIGHT", 8, 0)
    horizontalOffsetSlider:SetScript("OnValueChanged", function(self, value)
        local offset = NormalizeOffset(value)
        if horizontalOffsetValue then
            horizontalOffsetValue:SetText(tostring(offset))
        end
        if self._wqolRefreshing then
            return
        end
        addon:SetWeeklyTaskReminderQuestTrackerHorizontalOffset(offset)
    end)

    horizontalOffsetValue = CreateOffsetInput(reminderSection, function()
        return addon:GetWeeklyTaskReminderQuestTrackerHorizontalOffset()
    end, function(offset)
        addon:SetWeeklyTaskReminderQuestTrackerHorizontalOffset(offset)
        RefreshState()
    end)
    horizontalOffsetValue:SetPoint("LEFT", horizontalOffsetSlider, "RIGHT", 8, 0)

    verticalOffsetLabel = UI.CreateLabel(reminderSection, string.format("%s:", TRANSLATE("Vertical offset")), 12)
    verticalOffsetLabel:SetPoint("LEFT", horizontalOffsetValue, "RIGHT", 20, 0)
    verticalOffsetLabel:SetWidth(100)
    verticalOffsetLabel:SetTextColor(0.78, 0.78, 0.78)

    verticalOffsetSlider = CreateOffsetSlider(reminderSection, 112)
    verticalOffsetSlider:SetPoint("LEFT", verticalOffsetLabel, "RIGHT", 8, 0)
    verticalOffsetSlider:SetScript("OnValueChanged", function(self, value)
        local offset = NormalizeOffset(value)
        if verticalOffsetValue then
            verticalOffsetValue:SetText(tostring(offset))
        end
        if self._wqolRefreshing then
            return
        end
        addon:SetWeeklyTaskReminderQuestTrackerVerticalOffset(offset)
    end)

    verticalOffsetValue = CreateOffsetInput(reminderSection, function()
        return addon:GetWeeklyTaskReminderQuestTrackerVerticalOffset()
    end, function(offset)
        addon:SetWeeklyTaskReminderQuestTrackerVerticalOffset(offset)
        RefreshState()
    end)
    verticalOffsetValue:SetPoint("LEFT", verticalOffsetSlider, "RIGHT", 8, 0)

    autoHideCheckbox = UI.CreateCheckBox(reminderSection, TRANSLATE("Auto-hide when all tasks are done"), function()
        return settings.autoHideCompleted == true
    end, function(value)
        addon:SetWeeklyTaskReminderAutoHideCompleted(value)
        RefreshState()
    end)
    autoHideCheckbox:SetPoint("TOPLEFT", horizontalOffsetLabel, "BOTTOMLEFT", 0, -10)
    autoHideCheckbox:SetSize(300, 24)

    autoHideHint = UI.CreateLabel(reminderSection, TRANSLATE("Window stays open while you are on the Reminder tab."), 10)
    autoHideHint:SetPoint("TOPLEFT", autoHideCheckbox.label, "BOTTOMLEFT", 0, -1)
    autoHideHint:SetPoint("RIGHT", reminderSection, "RIGHT", -12, 0)
    autoHideHint:SetTextColor(0.78, 0.78, 0.78)
    autoHideHint:SetJustifyH("LEFT")

    local resetSection = UI.CreateSection(
        frame,
        TRANSLATE("Weekly reset"),
        TRANSLATE("Progress is reset automatically with the weekly reset.")
    )
    resetSection:SetPoint("TOPLEFT", reminderSection, "BOTTOMLEFT", 0, -12)
    resetSection:SetPoint("TOPRIGHT", reminderSection, "BOTTOM", -6, -12)
    resetSection:SetHeight(112)

    resetButton = CreateTextButton(resetSection, 152, TRANSLATE("Reset progress"))
    resetButton:SetPoint("TOPLEFT", resetSection.description, "BOTTOMLEFT", 0, -14)
    resetButton:SetScript("OnClick", function()
        addon:ResetWeeklyTaskReminderProgress()
        RefreshState()
    end)

    local addSection = UI.CreateSection(
        frame,
        TRANSLATE("Add task"),
        ""
    )
    addSection:SetPoint("TOPLEFT", resetSection, "TOPRIGHT", 12, 0)
    addSection:SetPoint("TOPRIGHT", reminderSection, "BOTTOMRIGHT", 0, -12)
    addSection:SetHeight(112)

    addBox = CreateAddTaskBox(addSection)
    addBox:SetPoint("TOPLEFT", addSection.title, "BOTTOMLEFT", 0, -18)
    addBox:SetPoint("RIGHT", addSection, "RIGHT", -50, 0)

    addButton = CreatePlusButton(addSection)
    addButton:SetPoint("LEFT", addBox, "RIGHT", 8, 0)

    local function AddFromInput()
        if addon:AddWeeklyTask(addBox:GetText()) then
            addBox:SetText("")
            addBox:ClearFocus()
            RefreshState()
        end
    end

    addBox:SetScript("OnEnterPressed", AddFromInput)
    addBox:SetScript("OnEscapePressed", function(self)
        self:ClearFocus()
    end)
    addButton:SetScript("OnClick", AddFromInput)

    RefreshState()
    return frame
end)
