--[[--------------------------------------------------------------------
  PaladinHolyPower – ui/components/subpanel.lua
  Styled subpanels and tab bars used inside settings pages.

  API:
    • PHP.CreateTabs(parent, tabNames[, opts]) -> tabs, tabBar
    • PHP.CreateSubTabs(parent, tabNames, buildFns[, opts])
        -> { tabs = <array>, panels = <array>, frame = <subTabBar> }
    • PHP.AttachFrameBelow(frame, anchorTo[, yOffset])
----------------------------------------------------------------------]]

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

-- Do NOT cache PHP.Theme here. It may not be initialized yet.
local WHITE_TEX = (PHP.Theme and PHP.Theme.WhiteTex and PHP.Theme.WhiteTex()) or "Interface\\Buttons\\WHITE8x8"

-- match sidebar palette from panel.lua (BGs only; active text comes from Theme)
local COLOR_TAB_N = { 0.22, 0.20, 0.14, 1.00 }  -- idle bg
local COLOR_TAB_A = { 0.13, 0.12, 0.10, 1.00 }  -- active bg
local TEXT_N      = { 1.00, 1.00, 1.00, 0.95 }  -- idle text (plain)

-- sizes
local TAB_WIDTH, TAB_HEIGHT, TAB_SPACING = 132, 28, 5
local function lerp(a,b,t) return a + (b-a)*t end

-- Use PHP.Theme at call time (not at file load time).
local function ApplyActiveGradient(fs, plain)
  local Theme = PHP and PHP.Theme
  if Theme and Theme.ApplyGradientText then
    Theme.ApplyGradientText(fs, plain, nil, nil, { outline = true })
  else
    -- fallback if theme really isn't available
    fs:SetText(plain or "")
  end
end

-- one animated tab button (no gradient math here)
local function CreateAnimatedTab(parent, w, h, label)
  local btn = CreateFrame("Button", nil, parent, "BackdropTemplate")
  btn:SetSize(w, h)
  btn:SetBackdrop({ bgFile = WHITE_TEX })
  btn:SetBackdropColor(COLOR_TAB_N[1], COLOR_TAB_N[2], COLOR_TAB_N[3], COLOR_TAB_N[4])
  btn.__active = false

  -- label (same naming as panel.lua)
  local fs = btn:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  fs:SetPoint("CENTER", 0, 0)
  fs:SetJustifyH("CENTER")
  fs:SetText(label or "")
  fs:SetTextColor(1, 1, 1, 1) -- neutral so per-char colors show
  btn.Text = fs
  btn._labelPlain = label or ""

  -- ink + gloss
  local ink = btn:CreateTexture(nil, "BACKGROUND")
  ink:SetTexture(WHITE_TEX); ink:SetAllPoints(btn); ink:SetVertexColor(1,1,1,1); ink:SetAlpha(0)
  local gloss = btn:CreateTexture(nil, "OVERLAY", nil, 1)
  gloss:SetTexture(WHITE_TEX); gloss:SetAllPoints(btn); gloss:SetAlpha(0)
  if gloss.SetGradient and CreateColor then
    gloss:SetGradient("VERTICAL", CreateColor(1,1,1,0.10), CreateColor(1,1,1,0.00))
  else
    gloss:SetVertexColor(1,1,1,0.05)
  end
  btn._ink, btn._gloss = ink, gloss

  -- minimal anim state (BG + ink only)
  btn._state = { targetBG = { COLOR_TAB_N[1], COLOR_TAB_N[2], COLOR_TAB_N[3], COLOR_TAB_N[4] }, inkAlpha = 0, speed = 18 }

  local function RunAnim(self, elapsed)
    local s = self._state
    if not s then self:SetScript("OnUpdate", nil); self._animating=false; return end
    local k = math.min(1, (elapsed or 0) * (s.speed or 18))
    local r,g,b,a = self:GetBackdropColor()
    r = lerp(r, s.targetBG[1], k); g = lerp(g, s.targetBG[2], k)
    b = lerp(b, s.targetBG[3], k); a = lerp(a, s.targetBG[4], k)
    self:SetBackdropColor(r,g,b,a)
    self._ink:SetAlpha(lerp(self._ink:GetAlpha(), s.inkAlpha or 0, k))
    if math.abs(r-s.targetBG[1])<.001 and math.abs(g-s.targetBG[2])<.001
       and math.abs(b-s.targetBG[3])<.001 and math.abs(a-s.targetBG[4])<.001
       and math.abs(self._ink:GetAlpha()-(s.inkAlpha or 0))<.001 then
      self:SetScript("OnUpdate", nil); self._animating=false
    end
  end
  local function Kick(self) self._animating = true; self:SetScript("OnUpdate", RunAnim) end
  btn.__Kick = Kick

  -- hover ink
  btn:SetScript("OnEnter", function(self) self._state.inkAlpha = self.__active and 0.08 or 0.06; self._gloss:SetAlpha(1);               Kick(self) end)
  btn:SetScript("OnLeave", function(self) self._state.inkAlpha = self.__active and 0.08 or 0;    self._gloss:SetAlpha(self.__active and 1 or 0); Kick(self) end)
  btn:SetScript("OnMouseDown", function(self) self._state.inkAlpha = self.__active and 0.10 or 0.12; Kick(self) end)
  btn:SetScript("OnMouseUp",   function(self) self._state.inkAlpha = self.__active and 0.08 or 0;    Kick(self) end)

  -- select/deselect (gradient comes ONLY from theme.lua)
  function btn:SetSelected(active)
    self.__active = not not active
    local s = self._state
    if active then
      s.targetBG = { COLOR_TAB_A[1], COLOR_TAB_A[2], COLOR_TAB_A[3], COLOR_TAB_A[4] }
      s.inkAlpha = 0.08
      self._gloss:SetAlpha(1)
      ApplyActiveGradient(self.Text, self._labelPlain) -- << call theme at usage time
    else
      s.targetBG = { COLOR_TAB_N[1], COLOR_TAB_N[2], COLOR_TAB_N[3], COLOR_TAB_N[4] }
      s.inkAlpha = 0
      self._gloss:SetAlpha(0)
      self.Text:SetText(self._labelPlain)
      self.Text:SetTextColor(TEXT_N[1], TEXT_N[2], TEXT_N[3], TEXT_N[4])
    end
    if self.__Kick then self:__Kick() end
  end

  -- ensure gradient also applies if the button shows while already active
  btn:SetScript("OnShow", function(self)
    if self.__active then ApplyActiveGradient(self.Text, self._labelPlain) end
  end)

  return btn
end

-- centered tab row
function PHP.CreateTabs(parent, tabNames, opts)
  opts = opts or {}
  local n, tabs = #tabNames, {}
  local totalW = n * TAB_WIDTH + (n-1) * TAB_SPACING
  local bar = CreateFrame("Frame", nil, parent, "BackdropTemplate")
  bar:SetPoint("TOP", parent, "TOP", 0, -(opts.padTop or 0))
  bar:SetSize(totalW, TAB_HEIGHT)

  local x = -totalW/2
  for i, name in ipairs(tabNames) do
    local b = CreateAnimatedTab(bar, TAB_WIDTH, TAB_HEIGHT, name)
    b:SetPoint("LEFT", bar, "LEFT", x, 0)
    tabs[i] = b
    x = x + TAB_WIDTH + TAB_SPACING
  end

  local function setActive(idx) for i,b in ipairs(tabs) do b:SetSelected(i==idx) end end
  for i, b in ipairs(tabs) do local idx=i; b:SetScript("OnClick", function() setActive(idx) end) end
  setActive(1)
  return tabs, bar
end

-- subtabs with panels
function PHP.CreateSubTabs(parent, tabNames, buildFns, opts)
  opts = opts or {}
  local n, tabs, panels, built = #tabNames, {}, {}, {}

  local subTabBar = CreateFrame("Frame", nil, parent, "BackdropTemplate")
  local totalW = n * TAB_WIDTH + (n-1) * TAB_SPACING
  subTabBar:SetPoint("TOPLEFT", parent, "TOPLEFT", (opts.padLeft or 0), -(opts.padTop or 0))
  subTabBar:SetSize(totalW, TAB_HEIGHT)

  local panelInsetTop = TAB_HEIGHT + 8
  local panelX = (opts.padLeft or 0)

  local x = 0
  for i, name in ipairs(tabNames) do
    local b = CreateAnimatedTab(subTabBar, TAB_WIDTH, TAB_HEIGHT, name)
    b:SetPoint("LEFT", subTabBar, "LEFT", x, 0)
    tabs[i] = b
    x = x + TAB_WIDTH + TAB_SPACING

    local panel = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    panel:SetBackdrop({ bgFile = WHITE_TEX })
    panel:SetBackdropColor(0,0,0,0) -- parent background shows through
    panel:SetPoint("TOPLEFT", parent, "TOPLEFT", panelX, -panelInsetTop)
    panel:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", 0, 0)
    panel:Hide()
    panels[i] = panel

    if buildFns and buildFns[i] then buildFns[i](panel, PHP); built[i] = true end
  end

  local active = 1
  local function setActive(idx)
    if panels[active] then panels[active]:Hide() end
    active = idx
    if not built[idx] and buildFns and buildFns[idx] then buildFns[idx](panels[idx], PHP); built[idx] = true end
    for i, b in ipairs(tabs) do b:SetSelected(i == idx) end
    if panels[idx] then panels[idx]:Show() end
  end

  for i, b in ipairs(tabs) do local idx=i; b:SetScript("OnClick", function() setActive(idx) end) end
  setActive(1)

  return { tabs = tabs, panels = panels, frame = subTabBar }
end

function PHP.AttachFrameBelow(frame, anchorTo, yOffset)
  frame:ClearAllPoints()
  frame:SetPoint("TOP", anchorTo, "BOTTOM", 0, yOffset or -6)
end