local _, ns = ...
local Theme = ns.Theme

ns.Minimap = {}
local MinimapModule = ns.Minimap

local function getMinimapFrame()
    return _G.Minimap
end

local DEFAULT_ICON_PATH = "Interface\\AddOns\\AzerothAngler\\Media\\generated\\emblem_round"
local ICON_SIZE = 26
local ICON_CROP = 0.05
local ICON_OFFSET_X = 2
local ICON_OFFSET_Y = -1

local function getMinimapIconTexturePath()
    local profile = ns.DB and ns.DB.profile and ns.DB.profile.minimap or nil
    local path = profile and profile.iconTexture or nil
    -- Ignore stale paths pointing at the old uncropped logo art.
    if path and path ~= "" and not path:find("AzerothAnglerLogo", 1, true) then
        return path
    end
    return DEFAULT_ICON_PATH
end

local function applyMinimapIconTexture(texture)
    if not texture then return end
    -- GetTexture() always returns what you set, so fallback chains don't work.
    -- Use the path directly with explicit .png extension.
    local path = getMinimapIconTexturePath()
    -- If the stored path already has an extension, use as-is; otherwise append .png
    if not path:find("%.[a-zA-Z]+$") then
        path = path .. ".png"
    end
    texture:SetTexture(path)
end

-- Half the 31px button width, so the inner edge sits AT the minimap ring
local BUTTON_HALF = 15.5
local MIN_INNER_EDGE = 82

local function updateButtonPosition(button)
    if not button or not ns.DB then return end
    local minimap = getMinimapFrame()
    if not minimap then return end
    local angle = math.rad(ns.DB.profile.minimap.angle or 225)
    -- "radius" is how far the inner edge of the button sits from minimap center.
    -- Standard LibDBIcon outer-ring target is ~82px.  Adding BUTTON_HALF places
    -- the button CENTER at 82+15.5 = 97.5px — fully outside the minimap visually.
    local innerEdge = tonumber(ns.DB.profile.minimap.radius) or MIN_INNER_EDGE
    if innerEdge < MIN_INNER_EDGE then
        innerEdge = MIN_INNER_EDGE
        ns.DB.profile.minimap.radius = innerEdge
    end
    local dist = innerEdge + BUTTON_HALF
    local x = math.cos(angle) * dist
    local y = math.sin(angle) * dist
    button:ClearAllPoints()
    button:SetPoint("CENTER", minimap, "CENTER", x, y)
end

function MinimapModule:RefreshButton()
    local button = ns.state.minimapButton
    if not (button and ns.DB) then return end

    local isShown = ns.DB.profile.ui.showMinimapButton and not ns.DB.profile.minimap.hide
    button:SetShown(isShown)
    if not isShown then return end

    applyMinimapIconTexture(button.icon)

    local current = ns.DB.currentSession or {}
    local sleeping = ns.Fishing and ns.Fishing.IsSleeping and ns.Fishing:IsSleeping() or false
    local lureState = ns.Fishing and ns.Fishing.GetLureState and ns.Fishing:GetLureState() or { active = false }
    local tint = sleeping and Theme.colors.muted or (lureState.active and Theme.colors.good or Theme.colors.warn)
    button.icon:SetVertexColor(tint[1], tint[2], tint[3], sleeping and 0.8 or (current.active and 1 or 0.9))
    button.icon:SetDesaturated(sleeping or (not current.active and not lureState.active))
    updateButtonPosition(button)
end

function MinimapModule:ToggleVisibility()
    if not ns.DB then return end
    ns.DB.profile.minimap.hide = not ns.DB.profile.minimap.hide
    self:RefreshButton()
    ns.Utils:Print("Minimap button " .. (ns.DB.profile.minimap.hide and "hidden." or "shown."))
end

function MinimapModule:CreateButton()
    local minimap = getMinimapFrame()
    if not minimap then return end
    if ns.state.minimapButton then
        self:RefreshButton()
        return
    end

    local button = CreateFrame("Button", "AzerothAnglerMinimapButton", minimap)
    button:SetSize(31, 31)
    button:SetFrameStrata("MEDIUM")
    button:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp")
    button.elapsed = 0

    local center = CreateFrame("Frame", nil, button)
    center:SetSize(1, 1)
    center:SetPoint("CENTER", button, "CENTER", 0, 0)

    -- Icon clipped to a circle via MaskTexture (same center as ring)
    local tex = button:CreateTexture(nil, "ARTWORK")
    tex:SetPoint("CENTER", center, "CENTER", ICON_OFFSET_X, ICON_OFFSET_Y)
    tex:SetSize(ICON_SIZE, ICON_SIZE)
    tex:SetTexCoord(ICON_CROP, 1 - ICON_CROP, ICON_CROP, 1 - ICON_CROP)
    applyMinimapIconTexture(tex)
    button.icon = tex

    local mask = button:CreateMaskTexture()
    mask:SetTexture(
        "Interface\\CharacterFrame\\TempPortraitAlphaMask",
        "CLAMPTOBLACKADDITIVE",
        "CLAMPTOBLACKADDITIVE"
    )
    mask:SetAllPoints(tex)
    tex:AddMaskTexture(mask)

    button:SetScript("OnClick", function(_, mouseButton)
        if mouseButton == "RightButton" then
            if IsShiftKeyDown() then
                ns.UI:ToggleCompact()
            elseif ns.Fishing and ns.Fishing.ToggleSleeping then
                ns.Fishing:ToggleSleeping("minimap")
            end
        elseif mouseButton == "MiddleButton" then
            MinimapModule:ToggleVisibility()
        else
            ns.UI:ToggleMain()
        end
    end)
    button:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_LEFT")
        GameTooltip:AddLine("Azeroth Angler", 1, 0.82, 0)
        GameTooltip:AddLine("Left-click: Open main window", 0.85, 0.85, 0.85)
        GameTooltip:AddLine("Right-click: Sleep/Wake helpers", 0.85, 0.85, 0.85)
        GameTooltip:AddLine("Shift-right-click: Toggle compact tracker", 0.85, 0.85, 0.85)
        GameTooltip:AddLine("Middle-click: Hide minimap button", 0.85, 0.85, 0.85)
        GameTooltip:AddLine((ns.DB.profile.minimap.dragUnlocked and "Drag" or "Shift-drag") .. ": Move button", 0.70, 0.82, 0.92)
        if ns.Nearby and ns.Nearby.GetVisibleCount then
            GameTooltip:AddLine("Nearby anglers with addon: " .. tostring(ns.Nearby:GetVisibleCount()), 0.70, 0.90, 1.00)
        end
        if ns.DB.profile.minimap.showStatsTooltip then
            local current = ns.DB.currentSession or {}
            local lureState = ns.Fishing:GetLureState()
            local sleeping = ns.Fishing and ns.Fishing.IsSleeping and ns.Fishing:IsSleeping() or false
            GameTooltip:AddLine(" ")
            GameTooltip:AddLine("Session: " .. (current.active and "Active" or "Idle") .. "  |  Sleep: " .. (sleeping and "On" or "Off"), 1, 1, 1)
            GameTooltip:AddLine("Waters: " .. ns.Utils:AbbrevText(current.zone or ns.Utils:GetZoneName(), 24), 0.80, 0.88, 0.94)
            GameTooltip:AddLine("Casts / Catches: " .. tostring(current.casts or 0) .. " / " .. tostring(current.catches or 0), 0.80, 0.88, 0.94)
            GameTooltip:AddLine("Lure: " .. lureState.label, 0.80, 0.88, 0.94)
        end
        GameTooltip:Show()
    end)
    button:SetScript("OnLeave", function() GameTooltip:Hide() end)
    button:SetScript("OnMouseDown", function(self)
        if ns.DB.profile.minimap.dragUnlocked or IsShiftKeyDown() then
            self.isDragging = true
        end
    end)
    button:SetScript("OnMouseUp", function(self) self.isDragging = false end)
    button:SetScript("OnUpdate", function(self, elapsed)
        if not ns.DB then return end
        self.elapsed = (self.elapsed or 0) + (elapsed or 0)
        if self.isDragging and self.elapsed >= 0.02 then
            self.elapsed = 0
            local minimap = getMinimapFrame()
            if minimap then
                local mx, my = minimap:GetCenter()
                local cx, cy = GetCursorPosition()
                local scale = minimap:GetEffectiveScale()
                cx, cy = cx / scale, cy / scale
                local angle = math.deg(math.atan2(cy - my, cx - mx))
                ns.DB.profile.minimap.angle = angle
                updateButtonPosition(self)
            end
        end
        local sleeping = ns.Fishing and ns.Fishing.IsSleeping and ns.Fishing:IsSleeping() or false
        if not sleeping and ns.DB.profile.minimap.pulseWhileSessionActive and ns.DB.currentSession and ns.DB.currentSession.active then
            self.pulseTime = (self.pulseTime or 0) + (elapsed or 0)
            local scale = 1 + (math.sin((self.pulseTime or 0) * 5) * 0.04)
            self:SetScale(scale)
        else
            self:SetScale(1)
            self.pulseTime = 0
        end
    end)

    ns.state.minimapButton = button
    self:RefreshButton()
end
