TargetMarkerAssistant = TargetMarkerAssistant or {}
TMA_Config_Mark = TMA_Config_Mark or {}

local Module = TMA_Config_Mark
local SAY_PREVIEW_ICON_TEXTURE = "Interface\\AddOns\\TargetMarkerAssistant\\Art\\Icon\\SayIcon.png"

function Module.Create(ctx)
    local ui = ctx.ui
    local L = ctx.L
    local page = ctx.markerPage
    local module = {}

    local function CreateSectionLabel(parent, text, width) return ui.CreateSectionLabel(ctx, parent, text, width) end
    local function CreateFieldLabel(parent, text, width) return ui.CreateFieldLabel(ctx, parent, text, width) end
    local function CreateDescription(parent, text, width, style) return ui.CreateDescription(ctx, parent, text, width, style) end
    local function CreateHintDescription(parent, text, width) return ui.CreateHintDescription(ctx, parent, text, width) end
    local function CreateSectionRule(parent, anchor, width) return ui.CreateSectionRule(ctx, parent, anchor, width) end
    local function ConfigureCheckText(check, width) return ui.ConfigureCheckText(ctx, check, width) end

    local function GetMarkerDropdownText(idx)
        local markerName = L["MARKER_0"]
        for name, markerIndex in pairs(ctx.nameToIndex) do
            if markerIndex == idx then
                markerName = name
                break
            end
        end
        return (ctx.markerTextures[idx] or "") .. " " .. markerName
    end

    local markerSection = CreateSectionLabel(page, L["SECTION_MARKER"], ctx.formSectionWidth)
    markerSection:SetPoint("TOPLEFT", page, "TOPLEFT", ctx.formLeftX, ctx.formTopY)
    local markerRule = CreateSectionRule(page, markerSection, ctx.formSectionWidth)
    ui.CreateColumnDivider(ctx, page, "TargetMarkerAssistantMarkerColumnDivider")

    local clearFocusCheck = CreateFrame("CheckButton", "TargetMarkerAssistantClearFocusCheckbox", page, "InterfaceOptionsCheckButtonTemplate")
    clearFocusCheck:SetPoint("TOPLEFT", markerRule, "BOTTOMLEFT", ctx.SECTION_CONTENT_LEFT_INSET, -ctx.SECTION_RULE_CONTENT_GAP)
    clearFocusCheck.Text:SetText(L["CLEAR_FOCUS_DESC"])
    ConfigureCheckText(clearFocusCheck, ctx.formSectionWidth - 30)
    clearFocusCheck:SetScript("OnClick", function(self)
        TargetMarkerAssistantDB.allowClearFocus = self:GetChecked()
        ctx.InitAll()
    end)

    local clearFocusDesc = CreateDescription(page, L["DESC_CLEAR_FOCUS"], ctx.formDescriptionWidth)
    clearFocusDesc:SetPoint("TOPLEFT", clearFocusCheck.Text, "BOTTOMLEFT", 0, -ctx.TEXT_DESCRIPTION_GAP)

    local markCheck = CreateFrame("CheckButton", "TargetMarkerAssistantEnableMarkingCheckbox", page, "InterfaceOptionsCheckButtonTemplate")
    markCheck:SetPoint("TOPLEFT", clearFocusCheck, "BOTTOMLEFT", 0, -ctx.CHECKBOX_BLOCK_GAP)
    markCheck.Text:SetText(L["ENABLE_MARKING_DESC"])
    ConfigureCheckText(markCheck, ctx.formSectionWidth - 30)
    markCheck:SetScript("OnClick", function(self)
        TargetMarkerAssistantDB.enableMarking = self:GetChecked()
        ctx.InitAll()
    end)

    local markDesc = CreateDescription(page, L["DESC_MARK_TARGET"], ctx.formDescriptionWidth)
    markDesc:SetPoint("TOPLEFT", markCheck.Text, "BOTTOMLEFT", 0, -ctx.TEXT_DESCRIPTION_GAP)

    local markerDropdownLabel = CreateFieldLabel(page, L["TARGET_MARKER_FIELD"])
    markerDropdownLabel:SetPoint("TOPLEFT", markCheck, "BOTTOMLEFT", 0, -ctx.CHECKBOX_BLOCK_GAP)

    local markerDropdown = CreateFrame("DropdownButton", "TargetMarkerAssistantMarkerDropdown", page, "WowStyle1DropdownTemplate")
    markerDropdown:SetPoint("RIGHT", markerDropdownLabel, "LEFT", ctx.formSectionWidth - ctx.formInlineDropdownRightInset - ctx.SECTION_CONTENT_LEFT_INSET, 0)
    markerDropdown:SetWidth(ctx.formInlineDropdownWidth)
    ui.SetupRadioDropdown(markerDropdown, "MENU_TARGETMARKERASSISTANT_MARKER", function()
        return GetMarkerDropdownText(TargetMarkerAssistantDB.selectedMarker or 0)
    end, function()
        return TargetMarkerAssistantDB.selectedMarker
    end, function(value)
        TargetMarkerAssistantDB.selectedMarker = value
    end, function()
        local items = {}
        for _, name in ipairs(ctx.optionsOrder) do
            local idx = ctx.nameToIndex[name]
            items[#items + 1] = {
                text = (ctx.markerTextures[idx] or "") .. " " .. name,
                value = idx,
            }
        end
        return items
    end, function()
        ctx.InitAll()
        module.UpdateAnnounceMessagePreview()
    end)

    local announceSection = CreateSectionLabel(page, L["SECTION_ANNOUNCE"], ctx.formSectionWidth)
    announceSection:SetPoint("TOPLEFT", page, "TOPLEFT", ctx.formRightX, ctx.formTopY)
    local announceRule = CreateSectionRule(page, announceSection, ctx.formSectionWidth)

    local announceCheck = CreateFrame("CheckButton", "TargetMarkerAssistantEnableAnnounceCheckbox", page, "InterfaceOptionsCheckButtonTemplate")
    announceCheck:SetPoint("TOPLEFT", announceRule, "BOTTOMLEFT", ctx.SECTION_CONTENT_LEFT_INSET, -ctx.SECTION_RULE_CONTENT_GAP)
    announceCheck.Text:SetText(L["ENABLE_ANNOUNCE_DESC"])
    ConfigureCheckText(announceCheck, ctx.formSectionWidth - 30)
    announceCheck:SetScript("OnClick", function(self)
        TargetMarkerAssistantDB.enableAnnounce = self:GetChecked()
        ctx.InitAll()
    end)

    local announceDesc = CreateDescription(page, L["DESC_MARK_ANNOUNCE"], ctx.formDescriptionWidth)
    announceDesc:SetPoint("TOPLEFT", announceCheck.Text, "BOTTOMLEFT", 0, -ctx.TEXT_DESCRIPTION_GAP)

    local announceChannelLabel = CreateFieldLabel(page, L["ANNOUNCE_CHANNEL"])
    announceChannelLabel:SetPoint("TOPLEFT", announceCheck, "BOTTOMLEFT", 0, -ctx.CHECKBOX_BLOCK_GAP)

    local announceChannelDropdown = CreateFrame("DropdownButton", "TargetMarkerAssistantAnnounceChannelDropdown", page, "WowStyle1DropdownTemplate")
    announceChannelDropdown:SetPoint("RIGHT", announceChannelLabel, "LEFT", ctx.formSectionWidth - ctx.formInlineDropdownRightInset - ctx.SECTION_CONTENT_LEFT_INSET, 0)
    announceChannelDropdown:SetWidth(ctx.formInlineDropdownWidth)
    ui.SetupRadioDropdown(announceChannelDropdown, "MENU_TARGETMARKERASSISTANT_ANNOUNCE_CHANNEL", function()
        return ctx.GetAnnounceChannelText(TargetMarkerAssistantDB.announceChannel)
    end, function()
        return TargetMarkerAssistantDB.announceChannel
    end, function(value)
        TargetMarkerAssistantDB.announceChannel = value
    end, function()
        return ctx.GetAnnounceChannelItems()
    end, function()
        ctx.InitAll()
        module.UpdateAnnounceMessagePreview()
    end)

    local announceChannelHint = CreateHintDescription(page, L["DESC_MARK_ANNOUNCE_CHANNEL_FALLBACK"], ctx.formDescriptionWidth)
    announceChannelHint:SetPoint("TOPLEFT", announceChannelLabel, "BOTTOMLEFT", 0, -ctx.CONTROL_DESCRIPTION_GAP)

    local announceMessageLabel = CreateFieldLabel(page, L["ANNOUNCE_MESSAGE"])
    announceMessageLabel:SetPoint("TOPLEFT", announceChannelHint, "BOTTOMLEFT", 0, -ctx.FIELD_BLOCK_GAP)
    announceMessageLabel:SetWidth(260)

    local announceMessageWidth = ctx.formDescriptionWidth

    local announceMessageBox = CreateFrame("EditBox", "TargetMarkerAssistantAnnounceMessageBox", page, "InputBoxTemplate")
    announceMessageBox:SetSize(announceMessageWidth, 24)
    announceMessageBox:SetPoint("TOPLEFT", announceMessageLabel, "BOTTOMLEFT", 3, -ctx.LABEL_CONTROL_GAP)
    announceMessageBox:SetAutoFocus(false)
    announceMessageBox:SetMaxLetters(120)
    ui.StyleEditBox(announceMessageBox)
    announceMessageBox:SetScript("OnEnterPressed", function(self)
        TargetMarkerAssistantDB.announceMessage = self:GetText()
        self:ClearFocus()
        module.UpdateAnnounceMessagePreview()
        ctx.InitAll()
    end)
    announceMessageBox:SetScript("OnEditFocusLost", function(self)
        TargetMarkerAssistantDB.announceMessage = self:GetText()
        module.UpdateAnnounceMessagePreview()
        ctx.InitAll()
    end)
    announceMessageBox:SetScript("OnTextChanged", function(self)
        module.UpdateAnnounceMessagePreview(self:GetText())
    end)

    local announcePreviewFrame = CreateFrame("Frame", "TargetMarkerAssistantAnnouncePreviewFrame", page, "BackdropTemplate")
    announcePreviewFrame:SetHeight(34)
    local announceMessageVisualFrame = announceMessageBox.TMA_InputFrame or announceMessageBox
    announcePreviewFrame:SetPoint("TOPLEFT", announceMessageVisualFrame, "BOTTOMLEFT", 0, -ctx.CONTROL_DESCRIPTION_GAP)
    announcePreviewFrame:SetPoint("TOPRIGHT", announceMessageVisualFrame, "BOTTOMRIGHT", 0, -ctx.CONTROL_DESCRIPTION_GAP)
    ui.StylePreviewFrame(announcePreviewFrame)

    local announcePreviewIcon = announcePreviewFrame:CreateTexture(nil, "ARTWORK")
    announcePreviewIcon:SetSize(18, 18)
    announcePreviewIcon:SetPoint("LEFT", announcePreviewFrame, "LEFT", 10, 0)
    announcePreviewIcon:SetTexture(SAY_PREVIEW_ICON_TEXTURE)

    local announceMessageDesc = CreateDescription(announcePreviewFrame, "", announceMessageWidth - 44)
    announceMessageDesc:SetPoint("TOPLEFT", announcePreviewFrame, "TOPLEFT", 34, 0)
    announceMessageDesc:SetPoint("BOTTOMRIGHT", announcePreviewFrame, "BOTTOMRIGHT", -10, 0)
    announceMessageDesc:SetWordWrap(false)
    if announceMessageDesc.SetJustifyV then
        announceMessageDesc:SetJustifyV("MIDDLE")
    end

    function module.UpdateAnnounceMessagePreview(messageOverride)
        local message = messageOverride
        if message == nil and announceMessageBox then
            message = announceMessageBox:GetText()
        end

        announceMessageDesc:SetText(ctx.FormatAnnouncePreviewMessage(message, TargetMarkerAssistantDB.selectedMarker or 0))
    end

    local hotkeySection = CreateSectionLabel(page, L["SECTION_HOTKEY"], ctx.formSectionWidth)
    local hotkeySectionAnchor = ui.CreateColumnAnchor(page, ctx.formLeftX, markerDropdownLabel, "BOTTOM", -ctx.SECTION_BLOCK_GAP)
    hotkeySection:SetPoint("TOPLEFT", hotkeySectionAnchor, "TOPLEFT", 0, 0)
    local hotkeyRule = CreateSectionRule(page, hotkeySection, ctx.formSectionWidth)

    local hotkeyDesc = CreateDescription(page, L["DESC_HOTKEY"], ctx.formDescriptionWidth)
    hotkeyDesc:SetPoint("TOPLEFT", hotkeyRule, "BOTTOMLEFT", ctx.SECTION_CONTENT_LEFT_INSET, -ctx.SECTION_RULE_CONTENT_GAP)

    local hotkeyDropdownRightOffset = ctx.formSectionWidth - ctx.formInlineDropdownRightInset - ctx.SECTION_CONTENT_LEFT_INSET

    local modLabel = CreateFieldLabel(page, L["MODIFIER_KEY"])
    modLabel:SetPoint("TOPLEFT", hotkeyDesc, "BOTTOMLEFT", 0, -ctx.FIELD_BLOCK_GAP)

    local btnLabel = CreateFieldLabel(page, L["MOUSE_BUTTON"])
    btnLabel:SetPoint("TOPLEFT", modLabel, "BOTTOMLEFT", 0, -ctx.HOTKEY_ROW_GAP)

    local modDropdown = CreateFrame("DropdownButton", "TargetMarkerAssistantModDropdown", page, "WowStyle1DropdownTemplate")
    modDropdown:SetPoint("RIGHT", modLabel, "LEFT", hotkeyDropdownRightOffset, 2)
    modDropdown:SetWidth(ctx.formInlineDropdownWidth)
    ui.SetupRadioDropdown(modDropdown, "MENU_TARGETMARKERASSISTANT_MODIFIER", function()
        return TargetMarkerAssistantDB.modifier
    end, function()
        return TargetMarkerAssistantDB.modifier
    end, function(value)
        TargetMarkerAssistantDB.modifier = value
    end, function()
        local items = {}
        for _, mod in ipairs({ "shift", "alt", "ctrl" }) do
            items[#items + 1] = { text = mod, value = mod }
        end
        return items
    end, ctx.InitAll)

    local buttons = {
        { text = L["LEFT_BUTTON"], v = "1" },
        { text = L["MIDDLE_BUTTON"], v = "3" },
        { text = L["RIGHT_BUTTON"], v = "2" },
        { text = L["BUTTON_4"], v = "4" },
        { text = L["BUTTON_5"], v = "5" },
    }
    local function GetMouseButtonText(value)
        for _, btn in ipairs(buttons) do
            if btn.v == value then
                return btn.text
            end
        end
        return L["LEFT_BUTTON"]
    end

    local btnDropdown = CreateFrame("DropdownButton", "TargetMarkerAssistantBtnDropdown", page, "WowStyle1DropdownTemplate")
    btnDropdown:SetPoint("RIGHT", btnLabel, "LEFT", hotkeyDropdownRightOffset, 2)
    btnDropdown:SetWidth(ctx.formInlineDropdownWidth)
    ui.SetupRadioDropdown(btnDropdown, "MENU_TARGETMARKERASSISTANT_MOUSE_BUTTON", function()
        return GetMouseButtonText(TargetMarkerAssistantDB.mouseButton)
    end, function()
        return TargetMarkerAssistantDB.mouseButton
    end, function(value)
        TargetMarkerAssistantDB.mouseButton = value
    end, function()
        local items = {}
        for _, btn in ipairs(buttons) do
            items[#items + 1] = { text = btn.text, value = btn.v }
        end
        return items
    end, ctx.InitAll)

    function module.Refresh()
        clearFocusCheck:SetChecked(TargetMarkerAssistantDB.allowClearFocus)
        markCheck:SetChecked(TargetMarkerAssistantDB.enableMarking)
        announceCheck:SetChecked(TargetMarkerAssistantDB.enableAnnounce)
        announceMessageBox:SetText(TargetMarkerAssistantDB.announceMessage or L["ANNOUNCE_DEFAULT_MESSAGE"])
        ui.RefreshDropdown(markerDropdown)
        ui.RefreshDropdown(announceChannelDropdown)
        module.UpdateAnnounceMessagePreview()
        ui.RefreshDropdown(modDropdown)
        ui.RefreshDropdown(btnDropdown)
        ui.FitScrollContentToViewport(ctx.markerScrollFrame, page)
    end

    return module
end
