--[[--------------------------------------------------------------------
  PaladinHolyPower - tracker/holy_power_log/display.lua
  Holy Power Log Tracker (RENDERER ONLY)

  Responsibilities:
    • Draw & update the tracker icon + number (Masque-safe).
    • React to settings (size, alpha, font, zoom, color, value).
    • NO visibility decisions here. Show/Hide is owned by
      tracker/holy_power_log/events.lua which calls:
        - PHP.EnableHPLTrackerFrame()
        - PHP.DisableHPLTrackerFrame()
        - PHP.UpdateHPLTracker()

  Subscriptions:
    • PHP.HPLog_Subscribe(gen, spend, wasted) → updates value.
----------------------------------------------------------------------]]

local PHP = _G.PaladinHolyPower
if not PHP then return end

-- Masque support
local MASQUE_KEY   = "PHP_HPL"
local MASQUE_TITLE = "Holy Power Log"

local function MS() return PHP.MasqueSupport end
local function Masque_EnableSafe(btn, icon)
  local m = MS(); if not m then return end
  if type(m.EnableGroup) == "function" then m:EnableGroup(MASQUE_KEY, MASQUE_TITLE) end
  if type(m.AddButton)  == "function" and btn and icon then m:AddButton(MASQUE_KEY, btn, icon) end
  if     type(m.ReskinNow)    == "function" then m:ReskinNow(MASQUE_KEY)
  elseif type(m.RefreshGroup) == "function" then m:RefreshGroup(MASQUE_KEY)
  elseif type(m.UpdateGroup)  == "function" then m:UpdateGroup(MASQUE_KEY)
  end
end
local function Masque_DisableSafe(btn)
  local m = MS(); if not m then return end
  if type(m.RemoveButton) == "function" and btn then m:RemoveButton(MASQUE_KEY, btn) end
  if type(m.DisableGroup) == "function" then m:DisableGroup(MASQUE_KEY) end
end
local function Masque_ReskinSafe()
  local m = MS(); if m and type(m.ReskinNow) == "function" then m:ReskinNow(MASQUE_KEY) end
end

-- Utilities
local function ClampZoom(z)
  z = tonumber(z) or 0
  if z >= .5 then return .49 elseif z < 0 then return 0 else return z end
end

-- Live slider feedback (optional, only if panel exists & is open)
function PHP.Tracker_UpdateSlidersRealTime(x, y)
  if not (PHP.settings and PHP.settings.HPL and PHP.SettingsPanel and PHP.SettingsPanel.IsShown and PHP.SettingsPanel:IsShown()) then
    return
  end
  local panel = PHP.SettingsPanel
  local xSlider = _G.HplPosXSlider
  local ySlider = _G.HplPosYSlider
  if (not xSlider or not ySlider) and panel and panel.GetNumChildren then
    for i = 1, panel:GetNumChildren() do
      local child = select(i, panel:GetChildren())
      if child and child.GetName then
        local n = child:GetName()
        if n == "HplPosXSlider" then xSlider = child end
        if n == "HplPosYSlider" then ySlider = child end
      end
    end
  end
  if xSlider and xSlider.SetValue then xSlider:SetValue(x or 0) end
  if ySlider and ySlider.SetValue then ySlider:SetValue(y or 0) end
end
local UpdateSlidersRealTime = PHP.Tracker_UpdateSlidersRealTime

-- Fonts
local fonts = PHP.fonts or {}
local function GetFontPath(fontName)
  local LSM = LibStub and LibStub("LibSharedMedia-3.0", true)
  if LSM then
    local path = LSM:Fetch("font", fontName, true)
    if path then return path end
  end
  for _, f in ipairs(fonts) do
    if f.name == fontName then return f.path end
  end
  return "Fonts\\FRIZQT__.TTF"
end

-- Root frame (initially hidden; events.lua will show/hide)
local f = CreateFrame("Frame", "PaladinHolyPowerIcon", UIParent, "BackdropTemplate")
f:SetSize(64, 64)
f:SetPoint("CENTER", UIParent, "CENTER", 0, 200)
f:SetMovable(true)
f:RegisterForDrag("LeftButton")
f:SetClampedToScreen(true)
f:SetFrameStrata("MEDIUM")
f:EnableMouse(true)
f:Hide()

-- Edit handle (mover)
if PHP.EditHandle and PHP.EditHandle.AttachMovablePanel then
  PHP.EditHandle.AttachMovablePanel(
    f,
    function() return PHP.settings and PHP.settings.HPL end,
    {
      default = { x = 0, y = 200 },
      panelTitle = "Holy Power Log",
      onChange = function(x, y)
        UpdateSlidersRealTime(x, y)
        PHP.UpdateHPLTracker()
      end,
    }
  )
end

-- Root clicks (only open handle in EditMode; right-click to open settings if unlocked)
f:SetScript("OnMouseUp", function(self)
  if PHP.EditModeActive and self.ShowEditHandle then self:ShowEditHandle() end
end)
f:SetScript("OnMouseDown", function(self, button)
  if PHP.EditModeActive then return end
  local S = PHP.settings and PHP.settings.HPL
  if S and not S.locked and button == "RightButton" then
    if SlashCmdList and SlashCmdList.PHP then SlashCmdList.PHP() end
  end
end)

-- Masque button + icon
local btn = CreateFrame("Button", "PHP_HPL_Button", f)
btn:SetAllPoints(f)
btn:EnableMouse(false)
btn:Hide()

local icon = btn:CreateTexture(nil, "ARTWORK")
icon:SetAllPoints(btn)
icon:SetAlpha(1)
icon:SetVertexColor(1, 1, 1, 1)
icon:Hide()
btn.Icon = icon

-- Text holder + fontstring
local textHolder = CreateFrame("Frame", nil, f)
textHolder:SetPoint("CENTER", f, "CENTER", 0, 0)
textHolder:SetSize(f:GetSize())

local text = textHolder:CreateFontString("PaladinHolyPowerIconText", "OVERLAY")
text:SetPoint("CENTER")
text:SetJustifyH("CENTER")
text:SetJustifyV("MIDDLE")
text:SetFont("Fonts\\FRIZQT__.TTF", 20, "OUTLINE")
text:SetText("0")
text:Hide()

local function SetConfiguredColor()
  local S = PHP.settings and PHP.settings.HPL
  if S and type(S.valueColor) == "table" and #S.valueColor == 3 then
    text:SetTextColor(S.valueColor[1], S.valueColor[2], S.valueColor[3])
  else
    text:SetTextColor(0.91, 0.38, 0.37)
  end
end

-- Pulse (smooth single bounce)
local function BuildPulse()
  if textHolder._pulse then return end
  local ag = textHolder:CreateAnimationGroup()
  ag:SetLooping("NONE")

  local up = ag:CreateAnimation("Scale")
  up:SetOrder(1); up:SetDuration(0.08); up:SetSmoothing("OUT")
  up:SetScale(1.3, 1.3)

  local dn = ag:CreateAnimation("Scale")
  dn:SetOrder(2); dn:SetDuration(0.12); dn:SetSmoothing("IN")
  dn:SetScale(1/1.3, 1/1.3)

  ag:SetScript("OnPlay", function() text:SetTextColor(0.95, 0.35, 0.32) end)
  ag:SetScript("OnFinished", function() textHolder:SetScale(1); SetConfiguredColor() end)

  textHolder._pulse = ag
  text.pulseAnim = ag
end
BuildPulse()

-- Expose
PHP.trackerFrame      = f
PHP.trackerIcon       = icon
PHP.trackerValueText  = text
PHP.TriggerHPLTrackerBounce = PHP.TriggerHPLTrackerBounce or function() end

-- Totals cache
local TOT_GEN, TOT_SPENT, TOT_WASTED = 0, 0, 0
local function CurrentMode()
  local m = (PHP.settings and PHP.settings.HPL and PHP.settings.HPL.mode)
         or (PHP.settings and PHP.settings.HPT and PHP.settings.HPT.mode)
         or "wasted"
  m = string.lower(m)
  if m ~= "generated" and m ~= "spent" and m ~= "wasted" then m = "wasted" end
  return m
end
local function GetDisplayValue()
  local mode = CurrentMode()
  if mode == "generated" then return TOT_GEN
  elseif mode == "spent" then return TOT_SPENT
  else return TOT_WASTED end
end

-- Core updater (NO visibility changes here)
do
  local lastW, lastH, lastZoom
  local lastShown
  local lastFontPath, lastFontSize

  local function ApplyZoom(z)
    local pad = ClampZoom(z)
    icon:SetTexCoord(pad, 1 - pad, pad, 1 - pad)
    if btn.Icon and btn.Icon ~= icon then
      btn.Icon:SetTexCoord(pad, 1 - pad, pad, 1 - pad)
    end
  end

  function PHP.UpdateHPLTracker()
    local S = PHP.settings and PHP.settings.HPL
    if not S or S.enabled == false then
      -- Respect disabled state; renderer doesn't force hide if already shown,
      -- let events.lua call DisableHPLTrackerFrame().
      return
    end

    -- Ensure Masque group exists
    Masque_EnableSafe(btn, icon)

    -- Position & size
    local x = S.x or 0
    local y = S.y or 200
    f:ClearAllPoints()
    f:SetPoint("CENTER", UIParent, "CENTER", x, y)

    local iconSize = S.HPL_iconSize or S.iconSize or 64
    f:SetSize(iconSize, iconSize)
    textHolder:SetSize(iconSize, iconSize)

    -- Texture + zoom
    local media = PHP.MEDIA or "Interface\\AddOns\\PaladinHolyPower\\media\\"
    icon:SetTexture(media .. "holy_power.png")
    local zoom = ClampZoom(S.HPL_zoom or S.zoom)

    local w, h = f:GetSize()
    if (w ~= lastW) or (h ~= lastH) or (zoom ~= lastZoom) then
      lastW, lastH, lastZoom = w, h, zoom
      Masque_ReskinSafe()
    end
    ApplyZoom(zoom)

    -- Alpha
    local a = tonumber(S.HPL_alpha or S.alpha) or 1
    if a > 1 then a = a / 100 end
    f:SetAlpha(a); icon:SetAlpha(a)

    -- Font
    local wantPath = GetFontPath(S.HPLFont or S.hplFont or S.font)
    local wantSize = S.HPL_textSize or S.textSize or 20
    if wantPath ~= lastFontPath or wantSize ~= lastFontSize then
      text:SetFont(wantPath, wantSize, "OUTLINE")
      lastFontPath, lastFontSize = wantPath, wantSize
    end
    if not (text.pulseAnim and text.pulseAnim:IsPlaying()) then
      SetConfiguredColor()
    end

    -- Value + pulse
    local newText = tostring(GetDisplayValue() or 0)
    if newText ~= lastShown then
      lastShown = newText
      text:SetText(newText)
      local ag = textHolder._pulse
      if ag and ag:IsPlaying() then ag:Stop(); textHolder:SetScale(1) end
      if ag then ag:Play() end
      if PHP.TriggerHPLTrackerBounce then PHP.TriggerHPLTrackerBounce() end
    end

    -- IMPORTANT: No Show/Hide calls here.
    -- Visibility is owned by events.lua.
  end
end

-- Reskin on size change
f:SetScript("OnSizeChanged", function()
  Masque_ReskinSafe()
end)

-- Public toggles (ONLY place that shows/hides)
local trackerFrameEnabled = false
function PHP.EnableHPLTrackerFrame()
  if trackerFrameEnabled then return end
  local S = PHP.settings and PHP.settings.HPL
  if S and S.enabled == false then return end
  trackerFrameEnabled = true
  Masque_EnableSafe(btn, icon)
  f:Show(); btn:Show(); icon:Show(); text:Show()
  PHP.UpdateHPLTracker()
end

function PHP.DisableHPLTrackerFrame()
  if not trackerFrameEnabled then return end
  trackerFrameEnabled = false
  f:Hide(); btn:Hide(); icon:Hide(); text:Hide()
  text:SetText("0")
  Masque_DisableSafe(btn)
end

-- Subscribe to log totals
local function _OnTotals(gen, spend, wasted)
  TOT_GEN, TOT_SPENT, TOT_WASTED = (gen or 0), (spend or 0), (wasted or 0)
  if PHP.UpdateHPLTracker then PHP.UpdateHPLTracker() end
end
if PHP.HPLog_Subscribe then PHP.HPLog_Subscribe(_OnTotals) end
if PHP.HPLog_GetTotals then local g,s,w = PHP.HPLog_GetTotals(); _OnTotals(g,s,w) end