-- navigation.lua (Final Version — Auto Map Rotation + Debug Toggle)
local ADDON_NAME, WDIGI = ...
WDIGI.Navigation = WDIGI.Navigation or {}

------------------------------------------------------------
-- NAV HUD FRAME
------------------------------------------------------------
local navHUD = CreateFrame("Frame", "WDIGINavHUD", UIParent, "BackdropTemplate")
WDIGI.Navigation.HUD = navHUD

navHUD:SetSize(340, 100)
navHUD:SetPoint("TOP", UIParent, "TOP", 0, -100)
navHUD:Hide()

if navHUD.SetBackdrop then
    navHUD:SetBackdrop({
        bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 16,
        insets = { left = 4, right = 4, top = 4, bottom = 4 }
    })
    navHUD:SetBackdropColor(0, 0, 0, 0.9)
end

------------------------------------------------------------
-- ICONS
------------------------------------------------------------
navHUD.itemIcon = navHUD:CreateTexture(nil, "OVERLAY")
navHUD.itemIcon:SetSize(32, 32)
navHUD.itemIcon:SetPoint("TOPLEFT", 8, -10)

navHUD.vendorIcon = navHUD:CreateTexture(nil, "OVERLAY")
navHUD.vendorIcon:SetSize(20, 20)
navHUD.vendorIcon:SetPoint("LEFT", navHUD.itemIcon, "RIGHT", 6, -2)

------------------------------------------------------------
-- TEXT ELEMENTS
------------------------------------------------------------
navHUD.title = navHUD:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
navHUD.title:SetPoint("TOPLEFT", navHUD.vendorIcon, "TOPRIGHT", 6, 2)

navHUD.vendor = navHUD:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
navHUD.vendor:SetPoint("TOPLEFT", navHUD.title, "BOTTOMLEFT", 0, -2)
navHUD.vendor:SetWidth(220)
navHUD.vendor:SetJustifyH("LEFT")

navHUD.itemName = navHUD:CreateFontString(nil, "OVERLAY", "GameFontNormal")
navHUD.itemName:SetPoint("TOPLEFT", navHUD.vendor, "BOTTOMLEFT", 0, -2)
navHUD.itemName:SetWidth(220)
navHUD.itemName:SetJustifyH("LEFT")

navHUD.cost = navHUD:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
navHUD.cost:SetPoint("TOPLEFT", navHUD.itemName, "BOTTOMLEFT", 0, -2)

navHUD.dist = navHUD:CreateFontString(nil, "OVERLAY", "GameFontHighlightHuge")

------------------------------------------------------------
-- ARROW
------------------------------------------------------------
navHUD.arrow = navHUD:CreateTexture(nil, "OVERLAY")
navHUD.arrow:SetSize(52, 52)
navHUD.arrow:SetPoint("RIGHT", navHUD, "RIGHT", -8, 0)
navHUD.arrow:SetTexture("Interface\\Minimap\\MiniMap-QuestArrow")
navHUD.arrow:SetVertexColor(0.2, 1, 0.2)

navHUD.dist:SetPoint("RIGHT", navHUD.arrow, "LEFT", -2, 0)

------------------------------------------------------------
-- CLOSE BUTTON
------------------------------------------------------------
navHUD.close = CreateFrame("Button", nil, navHUD, "UIPanelCloseButton")
navHUD.close:SetPoint("TOPRIGHT", 2, 2)
navHUD.close:SetScale(0.7)
navHUD.close:SetScript("OnClick", function()
    navHUD:Hide()
    C_Map.ClearUserWaypoint()
end)

navHUD:EnableMouse(true)
navHUD:SetMovable(true)
navHUD:RegisterForDrag("LeftButton")
navHUD:SetScript("OnDragStart", navHUD.StartMoving)
navHUD:SetScript("OnDragStop", navHUD.StopMovingOrSizing)

------------------------------------------------------------
-- UPDATE HUD
------------------------------------------------------------
function WDIGI.Navigation.UpdateHUD(x, y, vendorName, itemName, cost, sourceType, targetZoneID, itemIcon, vendorIcon)
--     if not WDIGI.Settings.Get("WDIGI_EnableNavHUD_Experimental") then
--         navHUD:Hide()
--         return
--     end

    navHUD.tx = tonumber(x)
    navHUD.ty = tonumber(y)
    navHUD.targetZoneID = tonumber(targetZoneID)
    navHUD.lastDist = nil
    navHUD.sourceType = sourceType or "NAVIGATING TO:"

    local cleanVendor = tostring(vendorName or "Unknown Vendor")
        :gsub("|c%x%x%x%x%x%x%x%x", "")
        :gsub("|r", "")

    navHUD.vendor:SetText(cleanVendor)
    navHUD.itemName:SetText(itemName or "")
    navHUD.cost:SetText(cost or "")

    if itemIcon then
        navHUD.itemIcon:SetTexture(itemIcon)
        navHUD.itemIcon:Show()
    else
        navHUD.itemIcon:Hide()
    end

    if vendorIcon then
        navHUD.vendorIcon:SetTexture(vendorIcon)
        navHUD.vendorIcon:Show()
    else
        navHUD.vendorIcon:Hide()
    end

    navHUD:Show()
end

------------------------------------------------------------
-- SET PIN (REAL MAP LOGIC)
------------------------------------------------------------
function WDIGI.Navigation.SetPin(mapID, x, y, vendorName, itemName, cost, sourceType, itemIcon, vendorIcon)
    local mID = tonumber(mapID)
    local nX  = tonumber(x)
    local nY  = tonumber(y)

    if not mID or not nX or not nY or mID == 0 then return end

    local dx, dy = nX / 100, nY / 100
    if dx < 0 or dx > 1 or dy < 0 or dy > 1 then return end

    local point = UiMapPoint.CreateFromCoordinates(mID, dx, dy)
    C_Map.SetUserWaypoint(point)

    if C_SuperTrack and C_SuperTrack.SetSuperTrackedUserWaypoint then
        C_SuperTrack.SetSuperTrackedUserWaypoint(true)
    end

    WDIGI.Navigation.UpdateHUD(
        nX, nY,
        vendorName,
        itemName,
        cost,
        sourceType,
        mID,
        itemIcon,
        vendorIcon
    )
end

------------------------------------------------------------
-- ONUPDATE ENGINE (TomTom-style per-zone rotation)
------------------------------------------------------------
navHUD:SetScript("OnUpdate", function(self, elapsed)
--     if not WDIGI.Settings.Get("WDIGI_EnableNavHUD_Experimental") then
--         self:Hide()
--         return
--     end

    -- HUD should always work; arrow is experimental
    local arrowEnabled = WDIGI.Settings.Get("WDIGI_EnableNavHUD_Experimental")

    self.timer = (self.timer or 0) + elapsed
    if self.timer < 0.1 then return end
    self.timer = 0

    local targetID = self.targetZoneID
    if not targetID or targetID == 0 then return end

    --------------------------------------------------------
    -- PLAYER POSITION
    --------------------------------------------------------
    local currentMap = C_Map.GetBestMapForUnit("player")
    if not currentMap then return end

    local pos = C_Map.GetPlayerMapPosition(currentMap, "player")
    if not pos then return end

    local px, py = pos.x, pos.y

    --------------------------------------------------------
    -- ZONE CHECK
    --------------------------------------------------------
    if currentMap ~= targetID then
        local mapInfo = C_Map.GetMapInfo(targetID)
        self.dist:SetText(mapInfo and mapInfo.name or "Wrong Zone")
        self.dist:SetTextColor(0.6, 0.6, 0.6)
        self.arrow:Hide()
        return
    end

    --------------------------------------------------------
    -- TARGET COORDS
    --------------------------------------------------------
    local tx, ty = self.tx / 100, self.ty / 100

    --------------------------------------------------------
    -- MAP-SPACE VECTOR
    --------------------------------------------------------
    local mdx, mdy = tx - px, ty - py

    --------------------------------------------------------
    -- DISTANCE
    --------------------------------------------------------
    local rawDist = math.sqrt(mdx * mdx + mdy * mdy)
    local mult = WDIGI.MapUtils.GetZoneMultiplier(currentMap) or 1000
    local yards = math.floor(rawDist * mult)

    --------------------------------------------------------
    -- MAP ROTATION → WORLD-SPACE VECTOR
    --------------------------------------------------------
    local info = C_Map.GetMapInfo(currentMap)
    local cosr, sinr

    if info and info.horizontalCos and info.horizontalSin then
        cosr = info.horizontalCos
        sinr = info.horizontalSin
    else
        cosr = 1
        sinr = 0
    end

    local wx = mdx * cosr - mdy * sinr
    local wy = mdx * sinr + mdy * cosr

    --------------------------------------------------------
    -- ANGLE TO TARGET (WORLD SPACE)
    --------------------------------------------------------
    local angle = math.atan2(wy, wx)
    local facing = GetPlayerFacing() or 0
    local rel = angle - facing

    --------------------------------------------------------
    -- DEBUG OUTPUT
    --------------------------------------------------------
    if WDIGI.Settings.DebugNav() then
        navHUD.title:SetText(string.format("REL: %.1f°", math.deg(rel)))
    else
        navHUD.title:SetText(self.sourceType or "NAVIGATING TO:")
    end

    --------------------------------------------------------
    -- FINAL ROTATION (texture points UP → subtract 90°)
    -- (only if experimental enabled)
    --------------------------------------------------------
    if arrowEnabled then
        local rotation = rel - (math.pi / 2)
        self.arrow:SetRotation(rotation)
        self.arrow:Show()
    else
        self.arrow:Hide()
    end

    --------------------------------------------------------
    -- PULSE EFFECT
    --------------------------------------------------------
    local pulse = 1 + (math.sin(GetTime() * 6) * 0.05)
    self.dist:SetScale(pulse)

    --------------------------------------------------------
    -- ARRIVAL CHECK
    --------------------------------------------------------
    if yards <= 3 then
        self:Hide()
        C_Map.ClearUserWaypoint()
        UIErrorsFrame:AddMessage("Arrived at Destination!", 0, 1, 0)
        return
    end

    --------------------------------------------------------
    -- DISTANCE TEXT + COLOR
    --------------------------------------------------------
    self.dist:SetText(yards .. "yd")

    if self.lastDist and yards > (self.lastDist + 0.5) then
        self.dist:SetTextColor(1, 0.2, 0.2)
        self.arrow:SetVertexColor(1, 0.2, 0.2)
    elseif yards <= 10 then
        self.dist:SetTextColor(1, 0.8, 0)
        self.arrow:SetVertexColor(1, 0.8, 0)
    else
        self.dist:SetTextColor(0.2, 1, 0.2)
        self.arrow:SetVertexColor(0.2, 1, 0.2)
    end

    self.lastDist = yards
end)
