local _, ns = ...

local MINIMAP_ICON = "Interface\\Icons\\INV_Misc_Book_17"
local optionsPanel
local minimapButton

local function SetCheckboxLabel(checkButton, text)
    local label = checkButton.Text
    if not label and checkButton.GetName and checkButton:GetName() then
        label = _G[checkButton:GetName() .. "Text"]
    end
    if label then label:SetText(text) end
end

local function UpdateMinimapPosition()
    if not minimapButton or not ns.db then return end
    local angle = math.rad(tonumber(ns.db.minimapAngle) or 225)
    local radius = ((Minimap and Minimap:GetWidth() or 140) * 0.5) + 10
    minimapButton:ClearAllPoints()
    minimapButton:SetPoint("CENTER", Minimap, "CENTER", math.cos(angle) * radius, math.sin(angle) * radius)
end

function ns:UpdateMinimapButton()
    if not minimapButton or not self.db then return end
    minimapButton:SetShown(self.db.showMinimapButton ~= false)
    UpdateMinimapPosition()
end

function ns:InitializeMinimapButton()
    if minimapButton or not Minimap then
        self:UpdateMinimapButton()
        return
    end

    minimapButton = CreateFrame("Button", "MemoriesOfAzerothMinimapButton", Minimap)
    minimapButton:SetSize(31, 31)
    minimapButton:SetFrameStrata("MEDIUM")
    minimapButton:SetFrameLevel(Minimap:GetFrameLevel() + 8)
    minimapButton:RegisterForClicks("LeftButtonUp", "RightButtonUp")
    minimapButton:RegisterForDrag("LeftButton")

    local background = minimapButton:CreateTexture(nil, "BACKGROUND")
    background:SetTexture("Interface\\Minimap\\UI-Minimap-Background")
    background:SetSize(20, 20)
    background:SetPoint("TOPLEFT", 7, -5)

    local icon = minimapButton:CreateTexture(nil, "ARTWORK")
    icon:SetTexture(MINIMAP_ICON)
    icon:SetSize(18, 18)
    icon:SetPoint("TOPLEFT", 7, -6)
    icon:SetTexCoord(0.07, 0.93, 0.07, 0.93)

    local mask = minimapButton:CreateMaskTexture()
    mask:SetTexture("Interface\\CHARACTERFRAME\\TempPortraitAlphaMask", "CLAMPTOBLACKADDITIVE", "CLAMPTOBLACKADDITIVE")
    mask:SetAllPoints(icon)
    icon:AddMaskTexture(mask)

    local border = minimapButton:CreateTexture(nil, "OVERLAY")
    border:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
    border:SetSize(53, 53)
    border:SetPoint("TOPLEFT")

    local highlight = minimapButton:CreateTexture(nil, "HIGHLIGHT")
    highlight:SetTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
    highlight:SetBlendMode("ADD")
    highlight:SetSize(24, 24)
    highlight:SetPoint("CENTER")

    minimapButton:SetScript("OnClick", function(_, button)
        if button == "RightButton" then ns:OpenSettings() else ns:Toggle() end
    end)
    minimapButton:SetScript("OnEnter", function(button)
        GameTooltip:SetOwner(button, "ANCHOR_LEFT")
        GameTooltip:SetText("Memories of Azeroth")
        GameTooltip:AddLine("Left-click to open the cinematic library.", 1, 1, 1)
        GameTooltip:AddLine("Right-click for settings.", 0.78, 0.78, 0.78)
        GameTooltip:Show()
    end)
    minimapButton:SetScript("OnLeave", function() GameTooltip:Hide() end)
    minimapButton:SetScript("OnDragStart", function(button)
        button:SetScript("OnUpdate", function()
            if not ns.db then return end
            local scale = UIParent:GetEffectiveScale()
            local cursorX, cursorY = GetCursorPosition()
            local centerX, centerY = Minimap:GetCenter()
            cursorX, cursorY = cursorX / scale, cursorY / scale
            ns.db.minimapAngle = math.deg(math.atan2(cursorY - centerY, cursorX - centerX))
            UpdateMinimapPosition()
        end)
    end)
    minimapButton:SetScript("OnDragStop", function(button) button:SetScript("OnUpdate", nil) end)
    minimapButton:SetScript("OnHide", function(button) button:SetScript("OnUpdate", nil) end)

    self:UpdateMinimapButton()
end

function ns:InitializeOptions()
    if optionsPanel then return end

    optionsPanel = CreateFrame("Frame")
    optionsPanel.name = "Memories of Azeroth"

    local title = optionsPanel:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    title:SetPoint("TOPLEFT", 16, -16)
    title:SetText("Memories of Azeroth")

    local subtitle = optionsPanel:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    subtitle:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8)
    subtitle:SetText("Browse and replay World of Warcraft's pre-rendered cinematics.")

    local commandsTitle = optionsPanel:CreateFontString(nil, "ARTWORK", "GameFontNormal")
    commandsTitle:SetPoint("TOPLEFT", subtitle, "BOTTOMLEFT", 0, -24)
    commandsTitle:SetText("Slash commands")

    local commands = optionsPanel:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
    commands:SetPoint("TOPLEFT", commandsTitle, "BOTTOMLEFT", 0, -8)
    commands:SetJustifyH("LEFT")
    commands:SetText("/cutscenes, /cin, /moa  —  Open or close the library.\n/cutscenes <movie ID>  —  Preview a known movie directly.")

    local minimapCheck = CreateFrame("CheckButton", nil, optionsPanel, "InterfaceOptionsCheckButtonTemplate")
    minimapCheck:SetPoint("TOPLEFT", commands, "BOTTOMLEFT", -4, -28)
    SetCheckboxLabel(minimapCheck, "Show minimap button")
    minimapCheck:SetScript("OnClick", function(button)
        ns.db.showMinimapButton = button:GetChecked() and true or false
        ns:UpdateMinimapButton()
    end)

    local subtitleCheck = CreateFrame("CheckButton", nil, optionsPanel, "InterfaceOptionsCheckButtonTemplate")
    subtitleCheck:SetPoint("TOPLEFT", minimapCheck, "BOTTOMLEFT", 0, -8)
    SetCheckboxLabel(subtitleCheck, "Show subtitles in movies played by this addon")
    subtitleCheck:SetScript("OnClick", function(button)
        ns.db.showSubtitles = button:GetChecked() and true or false
    end)

    optionsPanel:SetScript("OnShow", function()
        minimapCheck:SetChecked(not ns.db or ns.db.showMinimapButton ~= false)
        subtitleCheck:SetChecked(not ns.db or ns.db.showSubtitles ~= false)
    end)

    if Settings and Settings.RegisterCanvasLayoutCategory then
        local category = Settings.RegisterCanvasLayoutCategory(optionsPanel, optionsPanel.name)
        Settings.RegisterAddOnCategory(category)
        ns.settingsCategoryID = category.GetID and category:GetID() or category.ID
    elseif InterfaceOptions_AddCategory then
        InterfaceOptions_AddCategory(optionsPanel)
    end
end

function ns:OpenSettings()
    if not optionsPanel then self:InitializeOptions() end
    if Settings and Settings.OpenToCategory and self.settingsCategoryID then
        Settings.OpenToCategory(self.settingsCategoryID)
    elseif InterfaceOptionsFrame_OpenToCategory and optionsPanel then
        InterfaceOptionsFrame_OpenToCategory(optionsPanel)
        InterfaceOptionsFrame_OpenToCategory(optionsPanel)
    end
end
