local addonName, privateDB = ...
local L = HDG_L or {}

-- ============================================================================
-- MINIMAP BUTTON & ADDON COMPARTMENT
-- ============================================================================

local HDG_Minimap = {}

-- ============================================================================
-- STORE HELPERS
-- ============================================================================

local function GetStore()
    local HDG = _G.HousingDecorGuide
    return HDG and HDG.Store
end

local function GetState()
    local store = GetStore()
    return store and store:GetState()
end

local function Dispatch(action, payload)
    local store = GetStore()
    if store then
        store:Dispatch(action, payload)
    end
end

local function GetMinimap(key)
    local state = GetState()
    return state and state.minimap and state.minimap[key]
end

local function SetMinimap(key, value)
    Dispatch("SET_MINIMAP", { key = key, value = value })
end
privateDB.HDG_Minimap = HDG_Minimap

local minimapButton = nil

-- Right-click context menu
local function ShowContextMenu(owner)
    MenuUtil.CreateContextMenu(owner, function(_, rootDescription)
        rootDescription:CreateTitle("Housing Decor Guide")
        rootDescription:CreateButton("Lumber Tracker", function()
            HDG_LumberTracker.TogglePinned()
        end)
        rootDescription:CreateButton(L["HEADER_SHOPPING_LIST"] or "Shopping List", function()
            HDG_VendorShoppingList.Toggle()
        end)
    end)
end

-- Minimap shape detection for square minimap addon compatibility
-- Returns true if minimap appears to be square
local function IsMinimapSquare()
    -- Global function set by some addons
    if GetMinimapShape then
        return GetMinimapShape() == "SQUARE"
    end

    -- Method on Minimap frame (ElvUI, VelUI, and forks set this)
    if Minimap.GetShape then
        return Minimap:GetShape() == "SQUARE"
    end

    -- Known square minimap addon frames
    if SexyMapCustomBackdrop or SexyMapSuperTrackerBackground then
        return true
    end
    if BasicMinimapSquare then
        return true
    end

    -- Check mask texture - if changed from default circular mask, assume square
    if Minimap.GetMaskTexture then
        local mask = Minimap:GetMaskTexture()
        if mask and type(mask) == "string" then
            local lower = mask:lower()
            -- Default circular mask contains "minimapmask"; anything else is likely square
            if not lower:find("minimapmask") then
                return true
            end
        end
    end

    return false
end

-- Calculate position for square minimap (uses corner/edge positioning)
local function GetSquarePosition(angle)
    -- For square minimaps, we clamp to the edges
    local rad = math.rad(angle)
    local x = math.cos(rad)
    local y = math.sin(rad)

    -- Normalize to square edges (half-width ~80 for standard minimap)
    local halfSize = 80
    local maxComponent = math.max(math.abs(x), math.abs(y))
    if maxComponent > 0 then
        x = (x / maxComponent) * halfSize
        y = (y / maxComponent) * halfSize
    end

    return x, y
end

-- Calculate position for circular minimap
local function GetCircularPosition(angle)
    local rad = math.rad(angle)
    -- Radius 95 = outside minimap border (minimap ~70 radius + button half-width + buffer)
    local x = math.cos(rad) * 95
    local y = math.sin(rad) * 95
    return x, y
end

function HDG_Minimap.Initialize()
    -- Settings are initialized via Store DEFAULT_STATE
    -- No need to initialize here - Store handles defaults

    -- Create minimap button
    minimapButton = CreateFrame("Button", "HousingDecorGuideMinimapButton", Minimap)
    minimapButton:SetSize(32, 32)
    minimapButton:SetFrameStrata("MEDIUM")
    minimapButton:SetFrameLevel(8)
    minimapButton:RegisterForClicks("LeftButtonUp", "RightButtonUp")
    minimapButton:RegisterForDrag("LeftButton")
    minimapButton:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")

    -- Create icon
    local icon = minimapButton:CreateTexture(nil, "BACKGROUND")
    icon:SetSize(20, 20)
    icon:SetPoint("CENTER", 0, 0)

    -- Load saved icon or use default custom icon
    local iconPath = GetMinimap("icon") or "Interface/AddOns/HousingDecorGuide/textures/HousingDecorIcon"

    -- Try to set the texture - if it fails, fall back to a standard icon
    local success = icon:SetTexture(iconPath)
    if not success or icon:GetTexture() == nil then
        -- Fallback to standard WoW icon if custom icon doesn't load
        iconPath = "Interface\\Icons\\Trade_Engineering"
        icon:SetTexture(iconPath)
    end

    minimapButton.icon = icon

    -- Create border
    local overlay = minimapButton:CreateTexture(nil, "OVERLAY")
    overlay:SetSize(52, 52)
    overlay:SetPoint("TOPLEFT", 0, 0)
    overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
    minimapButton.overlay = overlay

    -- Click handler
    minimapButton:SetScript("OnClick", function(self, button)
        if button == "LeftButton" then
            HDG_UI.Toggle()
        elseif button == "RightButton" then
            ShowContextMenu(self)
        end
    end)

    -- Drag handler
    minimapButton:SetScript("OnDragStart", function(self)
        if not GetMinimap("lock") then
            self:SetScript("OnUpdate", HDG_Minimap.OnUpdate)
        end
    end)

    minimapButton:SetScript("OnDragStop", function(self)
        self:SetScript("OnUpdate", nil)
    end)

    -- Tooltip
    minimapButton:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, HDG_UIHelpers.TOOLTIP_ANCHOR)
        GameTooltip:AddLine("|cFFfcd34dHousing Decor Guide|r", 1, 1, 1)
        GameTooltip:AddLine("|cFFFFFFFFLeft-click:|r Toggle addon", 0.7, 0.7, 0.7)
        GameTooltip:AddLine("|cFFFFFFFFRight-click:|r Menu", 0.7, 0.7, 0.7)
        GameTooltip:AddLine("|cFFFFFFFFDrag:|r Move button", 0.7, 0.7, 0.7)
        GameTooltip:Show()
    end)

    minimapButton:SetScript("OnLeave", function(self)
        GameTooltip:Hide()
    end)

    -- Position the button
    HDG_Minimap.UpdatePosition()

    -- Show/hide based on settings
    HDG_Minimap.UpdateVisibility()

    -- Register with addon compartment (Blizzard's minimap drawer)
    HDG_Minimap.RegisterCompartment()

    -- Register LDB launcher for Bazooka/Titan Panel/etc.
    HDG_Minimap.RegisterLDB()
end

function HDG_Minimap.OnUpdate(self)
    local mx, my = Minimap:GetCenter()
    local px, py = GetCursorPosition()
    local scale = Minimap:GetEffectiveScale()
    px, py = px / scale, py / scale

    local angle = math.atan2(py - my, px - mx)
    SetMinimap("minimapPos", math.deg(angle))
    HDG_Minimap.UpdatePosition()
end

function HDG_Minimap.UpdatePosition()
    if not minimapButton then return end

    minimapButton:ClearAllPoints()

    local angle = GetMinimap("minimapPos") or 220
    local x, y

    if IsMinimapSquare() then
        x, y = GetSquarePosition(angle)
    else
        x, y = GetCircularPosition(angle)
    end

    minimapButton:SetPoint("CENTER", Minimap, "CENTER", x, y)
end

-- Update visibility based on settings
function HDG_Minimap.UpdateVisibility()
    if not minimapButton then return end

    if GetMinimap("hide") or not GetMinimap("showMinimapButton") then
        minimapButton:Hide()
    else
        minimapButton:Show()
    end
end

function HDG_Minimap.Show()
    if minimapButton then
        SetMinimap("hide", false)
        SetMinimap("showMinimapButton", true)
        HDG_Minimap.UpdateVisibility()
    end
end

function HDG_Minimap.Hide()
    if minimapButton then
        SetMinimap("hide", true)
        HDG_Minimap.UpdateVisibility()
    end
end

function HDG_Minimap.Toggle()
    if minimapButton then
        if minimapButton:IsShown() then
            HDG_Minimap.Hide()
        else
            HDG_Minimap.Show()
        end
    end
end

function HDG_Minimap.SetIcon(iconName)
    if not minimapButton then return end

    local iconPath
    -- If the path contains "Interface" or starts with a backslash, treat it as a full path
    -- Otherwise, assume it's a standard icon name
    if iconName:match("^Interface") or iconName:match("^\\") then
        iconPath = iconName
    else
        iconPath = "Interface\\Icons\\" .. iconName
    end

    minimapButton.icon:SetTexture(iconPath)
    SetMinimap("icon", iconPath)
    print("|cFFfcd34d[HDG]|r Minimap icon changed to: " .. iconPath)
end

-- ============================================================================
-- ADDON COMPARTMENT (Minimap Drawer) - Added in Dragonflight
-- ============================================================================

function HDG_Minimap.RegisterCompartment()
    -- AddonCompartmentFrame is the Blizzard minimap addon drawer (added in 10.0)
    if not AddonCompartmentFrame or not AddonCompartmentFrame.RegisterAddon then
        return
    end

    -- Only register if setting is enabled
    if not GetMinimap("showInCompartment") then
        return
    end

    -- Register with the addon compartment
    AddonCompartmentFrame:RegisterAddon({
        text = "Housing Decor Guide",
        icon = "Interface/AddOns/HousingDecorGuide/textures/HousingDecorIcon",
        notCheckable = true,
        func = function(btn, arg1, arg2, checked, mouseButton)
            if mouseButton == "RightButton" then
                ShowContextMenu(btn)
            else
                HDG_UI.Toggle()
            end
        end,
        funcOnEnter = function(menuItem)
            GameTooltip:SetOwner(menuItem, "ANCHOR_RIGHT")
            GameTooltip:AddLine("|cFFfcd34dHousing Decor Guide|r", 1, 1, 1)
            GameTooltip:AddLine("Track and craft housing decor items", 0.7, 0.7, 0.7)
            GameTooltip:AddLine(" ")
            GameTooltip:AddLine("|cFFFFFFFFClick:|r Toggle addon window", 0.7, 0.7, 0.7)
            GameTooltip:AddLine("|cFFFFFFFFRight-click:|r Menu", 0.7, 0.7, 0.7)
            GameTooltip:Show()
        end,
        funcOnLeave = function()
            GameTooltip:Hide()
        end,
    })
end

-- Set minimap button visibility
function HDG_Minimap.SetShowMinimapButton(show)
    SetMinimap("showMinimapButton", show)
    HDG_Minimap.UpdateVisibility()
end

-- Set compartment visibility (requires reload to take effect for registration)
function HDG_Minimap.SetShowInCompartment(show)
    SetMinimap("showInCompartment", show)
    -- Note: Compartment registration happens at load time, so this requires a reload
end

-- Check if compartment is available
function HDG_Minimap.IsCompartmentAvailable()
    return AddonCompartmentFrame and AddonCompartmentFrame.RegisterAddon
end

-- ============================================================================
-- LIBDATABROKER LAUNCHER (for Bazooka, Titan Panel, ChocolateBar, etc.)
-- Zero-dependency: only registers if LibDataBroker-1.1 is already loaded
-- ============================================================================

function HDG_Minimap.RegisterLDB()
    if not LibStub then return end
    local LDB = LibStub:GetLibrary("LibDataBroker-1.1", true)
    if not LDB then return end

    local launcher = LDB:NewDataObject("HousingDecorGuide", {
        type = "launcher",
        icon = "Interface/AddOns/HousingDecorGuide/textures/HousingDecorIcon",
        label = "Housing Decor Guide",
        OnClick = function(frame, button)
            if button == "LeftButton" then
                HDG_UI.Toggle()
            elseif button == "RightButton" then
                ShowContextMenu(frame)
            end
        end,
        OnTooltipShow = function(tooltip)
            tooltip:AddLine("|cFFfcd34dHousing Decor Guide|r")
            tooltip:AddLine("|cFFFFFFFFLeft-click:|r Toggle addon", 0.7, 0.7, 0.7)
            tooltip:AddLine("|cFFFFFFFFRight-click:|r Menu", 0.7, 0.7, 0.7)
        end,
    })
end

-- Don't initialize here - will be called after ADDON_LOADED event
