local _, Addon = ...

local Options = {}
Addon.Options = Options

local frame
local updating = false
local sliders = {}
local checks = {}

local function MakeButton(parent, text, width, onClick)
    local button = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    button:SetSize(width, 24)
    button:SetText(text)
    button:SetScript("OnClick", onClick)
    return button
end

local function MakeSectionLabel(parent, text, x, y)
    local label = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    label:SetPoint("TOPLEFT", x, y)
    label:SetText(text)
    return label
end

local function MakeSlider(key, parent, labelText, x, y, width, minimum, maximum, step, onChange, formatter)
    local label = parent:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    label:SetPoint("TOPLEFT", x, y)
    label:SetText(labelText)

    local valueText = parent:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    valueText:SetPoint("TOPRIGHT", parent, "TOPLEFT", x + width, y)
    valueText:SetJustifyH("RIGHT")

    local slider = CreateFrame("Slider", nil, parent, "OptionsSliderTemplate")
    slider:SetPoint("TOPLEFT", x, y - 18)
    slider:SetSize(width, 16)
    slider:SetMinMaxValues(minimum, maximum)
    slider:SetValueStep(step)
    slider:SetObeyStepOnDrag(true)
    if slider.Text then
        slider.Text:Hide()
    end
    if slider.Low then
        slider.Low:SetText(tostring(minimum))
    end
    if slider.High then
        slider.High:SetText(tostring(maximum))
    end

    slider.valueText = valueText
    slider.formatter = formatter or tostring
    slider.step = step
    slider:SetScript("OnValueChanged", function(self, value)
        local rounded = math.floor((value / self.step) + 0.5) * self.step
        self.valueText:SetText(self.formatter(rounded))
        if not updating then
            onChange(rounded)
        end
    end)
    sliders[key] = slider
    return slider
end

local function MakeCheck(key, parent, text, x, y, onClick)
    local check = CreateFrame("CheckButton", nil, parent, "UICheckButtonTemplate")
    check:SetPoint("TOPLEFT", x, y)
    check.Text:SetText(text)
    check.Text:SetTextColor(1, 1, 1)
    check:SetScript("OnClick", function(self)
        if not updating then
            onClick(self:GetChecked())
        end
    end)
    checks[key] = check
    return check
end

local function ApplyProfile(profile)
    if Addon.UI:ApplyProfile(profile) then
        Options:Refresh()
    end
end

local function CreateOptionsFrame()
    frame = CreateFrame("Frame", "MapaEnMiniaturaOptionsFrame", UIParent, "BackdropTemplate")
    frame:SetSize(540, 620)
    frame:SetPoint("CENTER")
    frame:SetFrameStrata("DIALOG")
    frame:SetFrameLevel(80)
    frame:SetClampedToScreen(true)
    frame:SetToplevel(true)
    frame:SetMovable(true)
    frame:EnableMouse(true)
    frame:SetBackdrop({
        bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
        tile = true,
        tileSize = 32,
        edgeSize = 24,
        insets = { left = 7, right = 7, top = 7, bottom = 7 },
    })
    frame:SetBackdropColor(0.015, 0.015, 0.025, 0.98)
    frame:Hide()

    local titleBar = CreateFrame("Frame", nil, frame)
    titleBar:SetPoint("TOPLEFT", 12, -10)
    titleBar:SetPoint("TOPRIGHT", -36, -10)
    titleBar:SetHeight(28)
    titleBar:EnableMouse(true)
    titleBar:RegisterForDrag("LeftButton")
    titleBar:SetScript("OnDragStart", function()
        frame:StartMoving()
    end)
    titleBar:SetScript("OnDragStop", function()
        frame:StopMovingOrSizing()
    end)

    local title = titleBar:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    title:SetPoint("LEFT", 8, 0)
    title:SetText("Mapa en Miniatura")

    local closeButton = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
    closeButton:SetPoint("TOPRIGHT", -3, -3)
    closeButton:SetScript("OnClick", function()
        frame:Hide()
    end)

    local description = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    description:SetPoint("TOPLEFT", 28, -48)
    description:SetPoint("TOPRIGHT", -28, -48)
    description:SetJustifyH("LEFT")
    description:SetText("Los cambios se aplican inmediatamente y quedan guardados para el próximo inicio.")

    MakeSectionLabel(frame, "Perfiles rápidos", 30, -76)
    local normalButton = MakeButton(frame, "Normal", 112, function()
        ApplyProfile("normal")
    end)
    normalButton:SetPoint("TOPLEFT", 30, -96)
    local compactButton = MakeButton(frame, "Compacto", 112, function()
        ApplyProfile("compacto")
    end)
    compactButton:SetPoint("LEFT", normalButton, "RIGHT", 8, 0)
    local miniButton = MakeButton(frame, "Mini", 112, function()
        ApplyProfile("mini")
    end)
    miniButton:SetPoint("LEFT", compactButton, "RIGHT", 8, 0)

    MakeSectionLabel(frame, "Forma del mapa", 30, -135)
    local squareButton = MakeButton(frame, "Cuadrado", 112, function()
        Addon.UI:SetShape("square")
        Options:Refresh()
    end)
    squareButton:SetPoint("TOPLEFT", 30, -155)
    local circleButton = MakeButton(frame, "Circular", 112, function()
        Addon.UI:SetShape("circle")
        Options:Refresh()
    end)
    circleButton:SetPoint("LEFT", squareButton, "RIGHT", 8, 0)

    MakeSlider("size", frame, "Tamaño del mapa", 30, -205, 210, 120, 650, 10, function(value)
        local minimum = Addon.db.shape == "circle" and Addon.MIN_SIZE or Addon.MIN_SQUARE_SIZE
        Addon.db.size = Addon:Clamp(value, minimum, Addon.MAX_SIZE)
        Addon.UI:SetSize(Addon.db.size)
    end)
    MakeSlider("icons", frame, "Tamaño de iconos", 300, -205, 210, 18, 48, 1, function(value)
        Addon.db.addonButtonSize = value
        Addon.AddonButtons:Layout()
    end)

    MakeSlider("alpha", frame, "Opacidad", 30, -267, 210, 35, 100, 5, function(value)
        Addon.db.alpha = value / 100
        Addon.UI:SetAlpha(Addon.db.alpha)
    end, function(value)
        return value .. "%"
    end)
    MakeSlider("gap", frame, "Separación de iconos", 300, -267, 210, 0, 30, 1, function(value)
        Addon.db.addonButtonDistance = value
        Addon.AddonButtons:Layout()
    end)

    MakeSlider("border", frame, "Grosor del marco", 30, -329, 210, 0, 16, 1, function(value)
        Addon.UI:SetBorderSize(value)
    end)
    MakeSlider("columns", frame, "Columnas preferidas", 300, -329, 210, 1, 8, 1, function(value)
        Addon.db.addonHubColumns = value
        Addon.AddonButtons:Layout()
    end)

    MakeSlider("arrow", frame, "Tamaño de tu flecha", 30, -391, 210, 8, 40, 1, function(value)
        Addon.db.playerArrowSize = value
        Addon.Markers:SetPlayerArrowSize(value)
    end)

    MakeSectionLabel(frame, "Comportamiento", 30, -446)
    MakeCheck("replace", frame, "Reemplazar el minimapa original", 26, -466, function(value)
        Addon.UI:SetReplacementMode(value, true)
        Options:Refresh()
    end)
    MakeCheck("hub", frame, "Mostrar el botón de addons", 286, -466, function(value)
        Addon.UI:SetAddonButtonsShown(value)
    end)
    MakeCheck("lock", frame, "Bloquear el mapa y los botones", 26, -496, function(value)
        Addon.db.locked = not not value
    end)
    MakeCheck("bosses", frame, "Mostrar jefes de mazmorra", 286, -496, function(value)
        Addon.Markers:SetBossesShown(value)
    end)

    local resetButtons = MakeButton(frame, "Recolocar botones", 150, function()
        Addon.AddonButtons:ResetAnchor()
    end)
    resetButtons:SetPoint("BOTTOMLEFT", 30, 24)

    local resetAll = MakeButton(frame, "Restablecer todo", 150, function()
        Addon.UI:ResetSettings()
        Options:Refresh()
    end)
    resetAll:SetPoint("LEFT", resetButtons, "RIGHT", 10, 0)

    local help = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    help:SetPoint("BOTTOMLEFT", 30, 61)
    help:SetText("Ctrl + rueda: tamaño  |  Shift + arrastrar: mover mapa")
    help:SetTextColor(0.55, 0.75, 1)

    frame:SetScript("OnShow", function()
        Options:Refresh()
    end)
    table.insert(UISpecialFrames, frame:GetName())
end

function Options:Refresh()
    if not frame then
        return
    end

    updating = true
    local minimumSize = Addon.db.shape == "circle" and Addon.MIN_SIZE or Addon.MIN_SQUARE_SIZE
    sliders.size:SetMinMaxValues(minimumSize, Addon.MAX_SIZE)
    if sliders.size.Low then
        sliders.size.Low:SetText(tostring(minimumSize))
    end
    sliders.size:SetValue(Addon.db.size)
    sliders.alpha:SetValue(math.floor((Addon.db.alpha * 100) + 0.5))
    sliders.border:SetValue(Addon.db.borderSize)
    sliders.arrow:SetValue(Addon.db.playerArrowSize)
    sliders.icons:SetValue(Addon.db.addonButtonSize)
    sliders.gap:SetValue(Addon.db.addonButtonDistance)
    sliders.columns:SetValue(Addon.db.addonHubColumns)
    checks.replace:SetChecked(Addon.db.replaceMinimap)
    checks.hub:SetChecked(Addon.db.showAddonButtons)
    checks.lock:SetChecked(Addon.db.locked)
    checks.bosses:SetChecked(Addon.db.showBosses)
    updating = false
end

function Options:Toggle()
    if not frame then
        CreateOptionsFrame()
    end
    frame:SetShown(not frame:IsShown())
end

function Options:Open()
    if not frame then
        CreateOptionsFrame()
    end
    frame:Show()
end
