-- cmarker Options Panel
-- Settings panel accessible via Interface > AddOns > cmarker

local myname, ns = ...
local myfullname = C_AddOns.GetAddOnMetadata(myname, "Title")

-- ============================================================================
-- Font Strings Helper
-- ============================================================================
local function makeFontString(frame, label, indented)
    local text = frame:CreateFontString(nil, "OVERLAY", indented and "GameFontNormalSmall" or "GameFontNormal")
    text:SetJustifyH("LEFT")
    text:SetText(label)
    if indented then
        text:SetPoint("LEFT", frame, 52, 0)
    else
        text:SetPoint("LEFT", frame, 17, 0)
    end
    text:SetPoint("RIGHT", frame, "CENTER", -85, 0)
    return text
end

local function makeTitle(parent, text)
    local title = CreateFrame("Frame", nil, parent)
    title.Text = makeFontString(title, text)
    title:SetSize(280, 26)
    title:SetPoint("RIGHT", parent)
    return title
end

-- ============================================================================
-- Checkbox Helper
-- ============================================================================
local makeCheckbox
do
    local function checkboxGetValue(self)
        return CharacterMarkerDB[self.key]
    end
    
    local function checkboxSetChecked(self)
        self:SetChecked(self:GetValue())
    end
    
    local function checkboxSetValue(self, checked)
        CharacterMarkerDB[self.key] = checked
        if self.callback then
            self.callback(self.key, checked)
        end
    end
    
    local function checkboxOnClick(self)
        local checked = self:GetChecked()
        PlaySound(checked and SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON or SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF)
        self:SetValue(checked)
    end
    
    local function checkboxOnEnter(self)
        if self.tooltipText then
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, true)
        end
        if self.tooltipRequirement then
            GameTooltip:AddLine(self.tooltipRequirement, 1.0, 1.0, 1.0, true)
            GameTooltip:Show()
        end
    end
    
    function makeCheckbox(parent, key, label, description, callback)
        local frame = CreateFrame("Frame", nil, parent)
        local check = CreateFrame("CheckButton", nil, frame, "InterfaceOptionsCheckButtonTemplate")
        
        check.key = key
        check.callback = callback
        check.GetValue = checkboxGetValue
        check.SetValue = checkboxSetValue
        
        check:SetScript("OnShow", checkboxSetChecked)
        check:SetScript("OnClick", checkboxOnClick)
        check:SetScript("OnEnter", checkboxOnEnter)
        check:SetScript("OnLeave", GameTooltip_Hide)
        
        check.tooltipText = label
        check.tooltipRequirement = description
        check:SetPoint("LEFT", frame, "CENTER", -90, 0)
        frame.Check = check
        
        frame.Text = makeFontString(frame, label, true)
        frame:SetPoint("RIGHT", parent)
        frame:SetSize(280, 26)
        
        return frame
    end
end

-- ============================================================================
-- Slider Helper
-- ============================================================================
local function makeSlider(parent, key, label, minValue, maxValue, step, formatter, callback, indented)
    local frame = CreateFrame("Frame", nil, parent)
    
    frame.Slider = CreateFrame("Slider", nil, frame)
    frame.Slider:SetObeyStepOnDrag(true)
    frame.Slider:SetOrientation("HORIZONTAL")
    
    frame.Slider.Left = frame.Slider:CreateTexture()
    frame.Slider.Left:SetPoint("LEFT")
    
    frame.Slider.Right = frame.Slider:CreateTexture()
    frame.Slider.Right:SetPoint("RIGHT")
    
    frame.Slider.Middle = frame.Slider:CreateTexture()
    frame.Slider.Middle:SetPoint("TOPLEFT", frame.Slider.Left, "TOPRIGHT")
    frame.Slider.Middle:SetPoint("TOPRIGHT", frame.Slider.Right, "TOPLEFT")
    
    frame.Slider.Thumb = frame.Slider:CreateTexture()
    frame.Slider:SetThumbTexture(frame.Slider.Thumb)
    frame.Slider:SetSize(200, 19)
    
    frame.Slider.Left:SetAtlas("Minimal_SliderBar_Left", true)
    frame.Slider.Right:SetAtlas("Minimal_SliderBar_Right", true)
    frame.Slider.Middle:SetAtlas("_Minimal_SliderBar_Middle", true)
    frame.Slider.Thumb:SetAtlas("Minimal_SliderBar_Button", true)
    
    formatter = formatter or function(value)
        return string.format("%.0f", value)
    end
    
    frame.FormatValue = function(self, value)
        frame.RightText:SetText(formatter(value))
        frame.RightText:Show()
    end
    
    frame.Slider:SetScript("OnValueChanged", function(slider, value)
        frame:FormatValue(value)
        CharacterMarkerDB[key] = value
        if callback then
            callback(key, value)
        end
    end)
    
    frame.Slider:SetScript("OnMouseDown", function(slider)
        if slider:IsEnabled() then
            PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
        end
    end)
    
    frame.OnStepperClicked = function(self, forward)
        local value = self.Slider:GetValue()
        if forward then
            self.Slider:SetValue(value + self.Slider:GetValueStep())
        else
            self.Slider:SetValue(value - self.Slider:GetValueStep())
        end
        PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
    end
    
    frame.Back = CreateFrame("Button", nil, frame)
    frame.Back:SetSize(11, 19)
    frame.Back:SetPoint("RIGHT", frame.Slider, "LEFT", -4, 0)
    frame.Back.Background = frame.Back:CreateTexture(nil, "BACKGROUND")
    frame.Back.Background:SetPoint("CENTER")
    frame.Back:SetScript("OnClick", function()
        frame:OnStepperClicked(false)
    end)
    
    frame.Forward = CreateFrame("Button", nil, frame)
    frame.Forward:SetSize(11, 19)
    frame.Forward:SetPoint("LEFT", frame.Slider, "RIGHT", 4, 0)
    frame.Forward.Background = frame.Forward:CreateTexture(nil, "BACKGROUND")
    frame.Forward.Background:SetPoint("CENTER")
    frame.Forward:SetScript("OnClick", function()
        frame:OnStepperClicked(true)
    end)
    
    frame.Back.Background:SetAtlas("Minimal_SliderBar_Button_Left", true)
    frame.Forward.Background:SetAtlas("Minimal_SliderBar_Button_Right", true)
    
    frame.RightText = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    frame.RightText:SetPoint("LEFT", frame.Slider, "RIGHT", 25, 0)
    
    frame.Slider:SetWidth(250)
    frame.Slider:SetPoint("LEFT", frame, "CENTER", -80, 3)
    
    frame.Text = makeFontString(frame, label, indented)
    frame:SetSize(280, 26)
    
    frame:SetScript("OnShow", function(self)
        if self.initialized then
            return
        end
        
        local value = CharacterMarkerDB[key]
        local steps = (step and (maxValue - minValue) / step) or 100
        
        self.Slider:SetMinMaxValues(minValue, maxValue)
        self.Slider:SetValueStep((maxValue - minValue) / steps)
        self.Slider:SetValue(value)
        self:FormatValue(value)
        
        self.initialized = true
    end)
    
    frame:SetPoint("RIGHT", parent)
    
    return frame
end

-- ============================================================================
-- Checkbox List Helper
-- ============================================================================
local function makeCheckboxList(parent, checkboxes, previous, callback)
    for _, data in ipairs(checkboxes) do
        if data then
            local control
            if data[1] then
                control = makeCheckbox(parent, data[1], data[2], data[3], callback)
            else
                control = makeTitle(parent, data[2])
            end
            control:SetPoint("TOPLEFT", previous, "BOTTOMLEFT", 0, -4)
            previous = control
        end
    end
    return previous
end

-- ============================================================================
-- Config Panel Helper
-- ============================================================================
local function makeConfigPanel(name, parent)
    local frame = CreateFrame("Frame")
    
    -- Guardar un snapshot de los valores actuales para cancelar si es necesario
    local savedValues = {
        enabled = CharacterMarkerDB.enabled,
        size = CharacterMarkerDB.size,
        yOffset = CharacterMarkerDB.yOffset,
        onlyCombat = CharacterMarkerDB.onlyCombat,
        autoOffset = CharacterMarkerDB.autoOffset,
    }
    
    frame.OnCommit = function(self)
        -- Los cambios ya se guardan automáticamente en CharacterMarkerDB
        -- Este callback confirma los cambios
    end
    
    frame.OnDefault = function(self)
        -- Resetear a valores por defecto
        CharacterMarkerDB.enabled = true
        CharacterMarkerDB.size = 47
        CharacterMarkerDB.yOffset = 0
        CharacterMarkerDB.onlyCombat = false
        CharacterMarkerDB.autoOffset = true
        -- Refrescar las controles
        if frame.OnRefresh then
            frame:OnRefresh()
        end
    end
    
    frame.OnRefresh = function(self)
        -- Refrescar todos los controles con los valores actuales
        -- (Los controles se actualizarán automáticamente)
    end
    
    local category, layout
    if parent then
        local parentcategory = Settings.GetCategory(parent)
        category, layout = Settings.RegisterCanvasLayoutSubcategory(parentcategory, frame, name)
    else
        category, layout = Settings.RegisterCanvasLayoutCategory(frame, name)
        Settings.RegisterAddOnCategory(category)
    end
    
    layout:AddAnchorPoint("TOPLEFT", 10, -10)
    layout:AddAnchorPoint("BOTTOMRIGHT", -10, 10)
    
    frame:Hide()
    
    return frame, category
end

-- ============================================================================
-- Setup Config
-- ============================================================================
local categoryID

local CreateOptionsPanel
function CreateOptionsPanel()
    local function refreshPosition(_, value)
        if _G.CharacterMarkerFrame_RepositionMarker then
            _G.CharacterMarkerFrame_RepositionMarker()
        end
    end
    
    local function callbackEnabled(key, value)
        if value then
            if CharacterMarkerDB.onlyCombat and not InCombatLockdown() then return end
            if _G.CharacterMarkerFrame_Enable then
                _G.CharacterMarkerFrame_Enable()
            end
        else
            if _G.CharacterMarkerFrame_Disable then
                _G.CharacterMarkerFrame_Disable()
            end
        end
    end
    
    local function callbackCombatOnly(key, value)
        if value and not InCombatLockdown() then
            if _G.CharacterMarkerFrame_Disable then
                _G.CharacterMarkerFrame_Disable()
            end
        elseif not value and CharacterMarkerDB.enabled then
            if _G.CharacterMarkerFrame_Enable then
                _G.CharacterMarkerFrame_Enable()
            end
        end
    end
    
    local function callbackAutoOffset(key, value)
        if value then
            -- Cuando se activa auto offset, resetear el offset manual a 0
            CharacterMarkerDB.yOffset = 0
            if _G.CharacterMarkerFrame_StartZoomTicker then
                _G.CharacterMarkerFrame_StartZoomTicker()
            end
        else
            if _G.CharacterMarkerFrame_StopZoomTicker then
                _G.CharacterMarkerFrame_StopZoomTicker()
            end
        end
        refreshPosition()
    end
    
    -- Main panel
    local frame, category = makeConfigPanel(myfullname)
    categoryID = category:GetID()
    
    local title = makeTitle(frame, "cmarker Settings - CharacterMarker ")
    title:SetPoint("TOPLEFT", frame)
    
    -- Crear checkboxes manualmente con callbacks específicos
    local enabledCheckbox = makeCheckbox(frame, "enabled", "Enable CharacterMarker", "Toggle the arrow marker on/off", callbackEnabled)
    enabledCheckbox:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -4)
    
    local combatCheckbox = makeCheckbox(frame, "onlyCombat", "Combat only", "Only show marker while in combat", callbackCombatOnly)
    combatCheckbox:SetPoint("TOPLEFT", enabledCheckbox, "BOTTOMLEFT", 0, -4)
    
    local autoCheckbox = makeCheckbox(frame, "autoOffset", "Auto offset (zoom-based)", "Adjust position based on camera zoom", callbackAutoOffset)
    autoCheckbox:SetPoint("TOPLEFT", combatCheckbox, "BOTTOMLEFT", 0, -4)
    
    local last = autoCheckbox
    
    -- Size slider
    local sizeSlider = makeSlider(
        frame, "size", "Size",
        10, 200, 1,
        function(value)
            return string.format("%.0f", value)
        end,
        function(key, value)
            if _G.CharacterMarkerFrame_ResizeMarker then
                _G.CharacterMarkerFrame_ResizeMarker()
            end
        end,
        false
    )
    sizeSlider:SetPoint("TOPLEFT", last, "BOTTOMLEFT", 0, -4)
    
    -- Position offset slider
    local offsetSlider = makeSlider(
        frame, "yOffset", "Vertical Offset",
        -200, 200, 1,
        function(value)
            return string.format("%.0f", value)
        end,
        refreshPosition,
        false
    )
    offsetSlider:SetPoint("TOPLEFT", sizeSlider, "BOTTOMLEFT", 0, -4)
    
    -- Reset button
    local resetBtn = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
    resetBtn:SetSize(160, 22)
    resetBtn:SetPoint("TOPLEFT", offsetSlider, "BOTTOMLEFT", 0, -16)
    resetBtn:SetText("Reset to Defaults")
    resetBtn:SetScript("OnClick", function(self)
        -- Resetear todos los valores en la base de datos
        CharacterMarkerDB.enabled = true
        CharacterMarkerDB.size = 47
        CharacterMarkerDB.yOffset = 0
        CharacterMarkerDB.onlyCombat = false
        CharacterMarkerDB.autoOffset = true
        
        -- Actualizar los checkboxes (acceder al CheckButton interno)
        enabledCheckbox.Check:SetChecked(true)
        combatCheckbox.Check:SetChecked(false)
        autoCheckbox.Check:SetChecked(true)
        
        -- Actualizar los sliders
        sizeSlider.Slider:SetValue(47)
        offsetSlider.Slider:SetValue(0)
        
        -- Ejecutar los callbacks para aplicar los cambios
        callbackEnabled("enabled", true)
        callbackCombatOnly("onlyCombat", false)
        callbackAutoOffset("autoOffset", true)

    end)
    
    -- Info note
    local note = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    note:SetPoint("BOTTOMLEFT", frame, 10, 10)
    note:SetTextColor(0.6, 0.8, 1)
    note:SetText("Changes are applied immediately. Use the reset button to restore defaults.")
end

-- ============================================================================
-- Initialization
-- ============================================================================
local optFrame = CreateFrame("Frame")
optFrame:RegisterEvent("PLAYER_LOGIN")
optFrame:SetScript("OnEvent", function(self, event)
    if event == "PLAYER_LOGIN" then
        C_Timer.After(0.5, function()
            if Settings and Settings.RegisterCanvasLayoutCategory then
                CreateOptionsPanel()
            end
        end)
        self:UnregisterEvent("PLAYER_LOGIN")
    end
end)

-- EOF
