--[[--------------------------------------------------------------------
  PaladinHolyPower - ui/hp_log/window.lua
----------------------------------------------------------------------]]

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

-- Defensive init in case logic file hasn't loaded yet
PHP.HPLog = PHP.HPLog or { fights = {}, cur = 1, active = nil, max = 5 }

-- Theme (source of truth)
local Theme = PHP.Theme

-- ------- Shared look to match Settings Panel -------
local HEADER_HEIGHT  = 44
local DIVIDER_THICK  = (Theme and Theme.DividerThickness and Theme.DividerThickness()) or 1

-- Shared media (prefer Theme)
local WHITE_TEX      = (Theme and Theme.WhiteTex and Theme.WhiteTex()) or "Interface\\Buttons\\WHITE8x8"
local FALLBACK_TEX   = "Interface\\AddOns\\PaladinHolyPower\\media\\icons\\background\\panel_1.png"
local PANEL_TEX      = (Theme and Theme.Texture and Theme.Texture()) or FALLBACK_TEX

-- Icon to match panel.lua
local ICON_PATH      = "Interface\\AddOns\\PaladinHolyPower\\media\\paladin_holy_power.png"

-- Fallback tints if Theme is unavailable
local TINT_ROOT_FB    = { 0.98, 0.98, 0.99, 0.75 }
local TINT_HEADER_FB  = { 0.95, 0.90, 0.55, 0.75 }
local TINT_CONTENT_FB = { 0.95, 0.90, 0.55, 0.70 }

local function getTint(name, fb)
  if Theme and Theme.GetTint then
    local t = Theme.GetTint(name)
    if t then return t end
  end
  return fb
end

local PixelUtil = _G.PixelUtil

-- Fallback BG applier (Theme.Apply*BG is preferred)
local function ApplyBG(frame, bgTex, rgba)
  if not frame then return end
  frame:SetBackdrop({ bgFile = bgTex })
  frame:SetBackdropColor(rgba[1], rgba[2], rgba[3], rgba[4])
end

-- Divider helpers (ALLOW CHOOSING LAYER; default to BACKGROUND so it can sit behind content)
local function NewDivider(parent, layer)
  if Theme and Theme.NewDivider then
    return Theme.NewDivider(parent, layer or "BACKGROUND")
  end
  local t = parent:CreateTexture(nil, layer or "BACKGROUND")
  t:SetTexture(WHITE_TEX)
  local c = PHP.ACCENT_COLOR or { 1, 1, 1, 1 }
  t:SetColorTexture(c[1], c[2], c[3], c[4])
  if t.SetSnapToPixelGrid then t:SetSnapToPixelGrid(true); t:SetTexelSnappingBias(0) end
  return t
end

local function RecolorDivider(tex)
  if Theme and Theme.RecolorDivider then
    Theme.RecolorDivider(tex); return
  end
  local c = PHP.ACCENT_COLOR or { 1, 1, 1, 1 }
  tex:SetColorTexture(c[1], c[2], c[3], c[4])
end

local function DrawH(line, frame, yFromTop)
  if Theme and Theme.DrawH then
    Theme.DrawH(line, frame, yFromTop); return
  end
  line:ClearAllPoints()
  if PixelUtil and PixelUtil.SetPoint then
    PixelUtil.SetPoint(line, "TOPLEFT",  frame, "TOPLEFT",  0, -yFromTop)
    PixelUtil.SetPoint(line, "TOPRIGHT", frame, "TOPRIGHT", 0, -yFromTop)
    PixelUtil.SetHeight(line, DIVIDER_THICK)
  else
    line:SetPoint("TOPLEFT",  frame, "TOPLEFT",  0, -yFromTop)
    line:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -yFromTop)
    line:SetHeight(DIVIDER_THICK)
  end
end

-- ------- Time helpers -------
local date = _G.date
local function Is24Hour()
  local get = (C_CVar and C_CVar.GetCVar) or _G.GetCVar
  local v = (type(get) == "function") and get("timeMgrUseMilitaryTime") or "0"
  return tostring(v) == "1"
end
local function FormatClockStart(sec)
  if not sec then return "—.—" end
  if Is24Hour() then
    return date("%H.%M", sec)
  else
    return date("%I.%M %p", sec)
  end
end

-- ------- Labels for fights -------
local function fightLabelFrom(cf, index)
  if not cf then
    return "—.— • No fights"
  end
  local clock = FormatClockStart(cf.startedLocal)
  local name  = (cf.bossName and cf.bossName ~= "") and cf.bossName or "Trash"
  if index then
    return string.format("%s • %s |cff666666(#%d)|r", clock, name, index)
  else
    return string.format("%s • %s", clock, name)
  end
end

-- ------- Build window (once) -------
local function ensureWindow()
  if PHP.HPLogWindow then return PHP.HPLogWindow end

  local W, H = 391, 400
  local f = CreateFrame("Frame", "PHP_HPLogWindow", UIParent, "BackdropTemplate")
  f:SetSize(W, H)
  f:SetFrameStrata("DIALOG")
  f:Hide()

  -- Prefer the same texture the settings panel uses; else Theme; else fallback
  local SHARED_BG = PANEL_TEX
  if PHP.SettingsPanel and PHP.SettingsPanel.GetBackdrop then
    local bd = PHP.SettingsPanel:GetBackdrop()
    if bd and bd.bgFile then SHARED_BG = bd.bgFile end
  end

  -- Root background: themed to match panel.lua (NO border)
  if Theme and Theme.ApplyRootBG then
    Theme.ApplyRootBG(f)
  else
    f:SetBackdrop({ bgFile = SHARED_BG }) -- no edgeFile => no border
    f:SetBackdropColor(unpack(TINT_ROOT_FB))
  end

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

  -- Header
  local header = CreateFrame("Frame", nil, f, "BackdropTemplate")
  header:SetPoint("TOPLEFT", 0, 0)
  header:SetPoint("TOPRIGHT", 0, 0)
  header:SetHeight(HEADER_HEIGHT)
  if Theme and Theme.ApplyHeaderBG then
    Theme.ApplyHeaderBG(header)
  else
    ApplyBG(header, SHARED_BG, TINT_HEADER_FB)
  end

  -- Header icon (match panel.lua)
  local icon = header:CreateTexture(nil, "ARTWORK")
  icon:SetSize(32, 32)
  icon:SetPoint("TOPLEFT", 10, -((HEADER_HEIGHT - 32) / 2))
  icon:SetTexture(ICON_PATH)

  -- Title (match panel.lua sizing & style)
  local title = header:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
  title:SetPoint("LEFT", icon, "RIGHT", 10, 0)
  do
    local fnt, sz, fl = title:GetFont()
    title:SetFont(fnt, (tonumber(sz) or 14) + 8, (fl and fl ~= "") and fl or "OUTLINE")
  end
  if Theme and Theme.ApplyGradientText then
    Theme.ApplyGradientText(title, "Log", nil, nil, { outline = true, sizeDelta = 0 })
  else
    title:SetText("Log")
  end

  -- Close (on root)
  local close = CreateFrame("Frame", nil, f)
  close:SetSize(14, 14)
  close:SetPoint("TOPRIGHT", -6, -6)
  close:EnableMouse(true)
  local l1 = close:CreateTexture(nil, "ARTWORK")
  l1:SetTexture(WHITE_TEX)
  l1:SetSize(2, 14); l1:SetPoint("CENTER"); l1:SetRotation(math.rad(45))
  local l2 = close:CreateTexture(nil, "ARTWORK")
  l2:SetTexture(WHITE_TEX)
  l2:SetSize(2, 14); l2:SetPoint("CENTER"); l2:SetRotation(math.rad(-45))
  l1:SetVertexColor(1,1,1); l2:SetVertexColor(1,1,1)
  close:SetScript("OnEnter", function() l1:SetVertexColor(.85,.85,.85); l2:SetVertexColor(.85,.85,.85) end)
  close:SetScript("OnLeave", function() l1:SetVertexColor(1,1,1);       l2:SetVertexColor(1,1,1)       end)
  close:SetScript("OnMouseUp", function() f:Hide() end)

  -- ======= SINGLE DIVIDER like panel.lua (under header) — BEHIND CONTENT =======
  -- Holder sits at same strata but one level lower; texture uses BACKGROUND layer.
  local behind = CreateFrame("Frame", nil, f)
  behind:SetAllPoints(f)
  behind:EnableMouse(false)
  behind:SetFrameStrata(f:GetFrameStrata())
  behind:SetFrameLevel(math.max(0, (f:GetFrameLevel() or 1) - 1))

  behind._line = behind._line or NewDivider(behind, "BACKGROUND")
  local function RedrawLine()
    RecolorDivider(behind._line)
    DrawH(behind._line, behind, HEADER_HEIGHT)
  end
  RedrawLine()
  f:HookScript("OnSizeChanged", RedrawLine)

  -- Body
  local body = CreateFrame("Frame", nil, f, "BackdropTemplate")
  body:SetPoint("TOPLEFT", 0, -HEADER_HEIGHT)
  body:SetPoint("BOTTOMRIGHT", 0, 0)
  if Theme and Theme.ApplyContentBG then
    Theme.ApplyContentBG(body)
  else
    ApplyBG(body, SHARED_BG, getTint("content", TINT_CONTENT_FB))
  end
  body:SetClipsChildren(true)

  -- Soft top gradient like panel.lua content
  local grad = body:CreateTexture(nil, "BACKGROUND")
  grad:SetPoint("TOPLEFT"); grad:SetPoint("TOPRIGHT"); grad:SetHeight(96)
  if grad.SetGradient and CreateColor then
    grad:SetGradient("VERTICAL", CreateColor(1,1,1,0.06), CreateColor(1,1,1,0.00))
  end

  -- ===== Header controls inside BODY =====
  local function fightsMax()
    local maxKeep = (PHP.HPLog and PHP.HPLog.max) or 5
    if maxKeep < 1 then maxKeep = 1 elseif maxKeep > 5 then maxKeep = 5 end
    return maxKeep
  end

  local function currentFightLabel()
    local fights = (PHP.HPLog and PHP.HPLog.fights) or {}
    local idx = PHP.HPLog.cur or 1
    return fightLabelFrom(fights[idx], idx)
  end

  local function buildFightItems()
    local items  = {}
    local fights = (PHP.HPLog and PHP.HPLog.fights) or {}
    local cap = math.min(#fights, fightsMax())
    for i = 1, cap do
      items[i] = fightLabelFrom(fights[i], i)
    end
    if #items == 0 then
      items[1] = fightLabelFrom(nil)
    end
    return items
  end

  local function selectFightByLabel(label)
    local fights = (PHP.HPLog and PHP.HPLog.fights) or {}
    local cap = math.min(#fights, fightsMax())
    for i = 1, cap do
      if fightLabelFrom(fights[i], i) == label then
        PHP.HPLog.cur = i
        break
      end
    end
    if PHP.HPLog_Refresh then PHP.HPLog_Refresh() end
  end

  local ddWidth = 260
  local dd

  local function createDropdown()
    if dd and dd:IsShown() then dd:Hide() end
    if dd then dd:ClearAllPoints(); dd:SetParent(nil) end

    if PHP.CreateDropdown then
      dd = PHP.CreateDropdown(
        "PHP_HPLogFightDD",
        "",
        buildFightItems(),
        body,                 -- parent now body
        12, -10,              -- x, y inside body
        currentFightLabel(),
        function(label) selectFightByLabel(label) end,
        ddWidth
      )
    else
      local _dd = CreateFrame("Frame", "PHP_HPLog_Dropdown", body, "UIDropDownMenuTemplate")
      _dd:SetPoint("TOPLEFT", body, "TOPLEFT", -10, -2)
      UIDropDownMenu_SetWidth(_dd, ddWidth)
      UIDropDownMenu_SetText(_dd, currentFightLabel())
      UIDropDownMenu_Initialize(_dd, function(self, level)
        if (level or 1) ~= 1 then return end
        local fights = (PHP.HPLog and PHP.HPLog.fights) or {}
        local cap = math.min(#fights, fightsMax())
        for i = 1, cap do
          local info = UIDropDownMenu_CreateInfo()
          info.text    = fightLabelFrom(fights[i], i)
          info.value   = i
          info.checked = (PHP.HPLog.cur or 1) == i
          info.func    = function(btn)
            PHP.HPLog.cur = btn.value
            if PHP.HPLog_Refresh then PHP.HPLog_Refresh() end
          end
          UIDropDownMenu_AddButton(info, 1)
        end
      end)
      dd = _dd
    end
  end
  createDropdown()

  local durFS = body:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
  durFS:SetPoint("TOPRIGHT", body, "TOPRIGHT", -12, -16)
  durFS:SetText("0:00")
  f._durationFS = durFS

  local function labelsChanged(a, b)
    if type(a) ~= "table" or type(b) ~= "table" then return true end
    if #a ~= #b then return true end
    for i = 1, #a do
      if a[i] ~= b[i] then return true end
    end
    return false
  end

  local function setHeader()
    -- duration text
    local label, dur = "Trash", "0:00"
    if PHP.HPLog_GetHeader then
      local l, d = PHP.HPLog_GetHeader()
      if l then label = l end
      if d then dur = d end
    end
    durFS:SetText(dur)

    -- dropdown text & items
    local nowItems = buildFightItems()
    if PHP.CreateDropdown and dd and dd.value then
      dd.value:SetText(currentFightLabel())
    else
      if _G.UIDropDownMenu_SetText then _G.UIDropDownMenu_SetText(dd, currentFightLabel()) end
    end

    if labelsChanged(f._lastItems or {}, nowItems) then
      createDropdown()
      f._lastItems = nowItems
    end
  end
  f._lastItems = buildFightItems()

  -- ===== Log area =====
  local tintContent = getTint("content", TINT_CONTENT_FB)
  local listBG = CreateFrame("Frame", nil, body, "BackdropTemplate")
  listBG:SetPoint("TOPLEFT",  body, "TOPLEFT", 12, -48)
  listBG:SetPoint("BOTTOMRIGHT", body, "BOTTOMRIGHT", -12, 44)
  listBG:SetBackdrop({ bgFile = SHARED_BG })                   -- same texture
  listBG:SetBackdropColor(tintContent[1], tintContent[2], tintContent[3], 0.75) -- 75% opacity

  local smf = CreateFrame("ScrollingMessageFrame", "PHP_HPLog_SMF", listBG)
  f.SMF = smf
  smf:SetPoint("TOPLEFT", 6, -6)
  smf:SetPoint("BOTTOMRIGHT", -6, 6)
  smf:SetFontObject(GameFontHighlightSmall)
  smf:SetFading(false)
  smf:SetJustifyH("LEFT")
  smf:SetMaxLines(4000)
  smf:SetHyperlinksEnabled(true)
  smf:EnableMouseWheel(true)
  smf:SetScript("OnMouseWheel", function(self, delta)
    if delta > 0 then self:ScrollUp() else self:ScrollDown() end
  end)

  local function ShowHPTip(payload, shown)
    GameTooltip:SetOwner(smf, "ANCHOR_CURSOR_RIGHT")
    GameTooltip:AddLine("Holy Power", 1, 1, 1)
    if payload == "wasted" then
      local val = tostring(shown or "")
      GameTooltip:AddLine("Wasted " .. val .. " Holy Power", .9, .9, .9)
    elseif tonumber(payload) then
      GameTooltip:AddLine("Spent " .. payload .. " Holy Power", .9, .9, .9)
    else
      GameTooltip:AddLine("Class resource used by Paladins.", .9, .9, .9, true)
      GameTooltip:AddLine("• Spenders consume Holy Power", .7, .7, .7, true)
      GameTooltip:AddLine("• Generators add Holy Power", .7, .7, .7, true)
    end
    GameTooltip:Show()
  end

  smf:SetScript("OnHyperlinkEnter", function(self, link, text)
    local ltype, payload = tostring(link):match("^(%a+):(.+)$")
    if ltype == "phpower" then
      local shown = tostring(text or payload or "")
      shown = shown:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "")
      ShowHPTip(payload, shown)
    else
      GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
      GameTooltip:SetHyperlink(link)
      GameTooltip:Show()
    end
  end)
  smf:SetScript("OnHyperlinkLeave", function() GameTooltip:Hide() end)

  -- ===== Footer area inside BODY =====
  local footerBG = CreateFrame("Frame", nil, body, "BackdropTemplate")
  footerBG:SetPoint("BOTTOMLEFT", body, "BOTTOMLEFT", 12, 12)
  footerBG:SetPoint("BOTTOMRIGHT", body, "BOTTOMRIGHT", -12, 12)
  footerBG:SetHeight(28)
  footerBG:SetBackdrop({ bgFile = SHARED_BG })                -- same texture
  footerBG:SetBackdropColor(tintContent[1], tintContent[2], tintContent[3], 0.75) -- 75% opacity

  local totals = footerBG:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
  totals:SetPoint("CENTER", footerBG, "CENTER", 0, 0)
  totals:SetText("Generated 0 | Spent 0 | Wasted 0")
  f._totalsFS = totals

  -- Refresh hook
  function PHP.HPLog_Refresh()
    setHeader()
    smf:Clear()
    local idx = PHP.HPLog.cur or 1
    local fight = PHP.HPLog.fights and PHP.HPLog.fights[idx]
    if fight and fight.lines then
      for i = 1, #fight.lines do
        smf:AddMessage(fight.lines[i])
      end
      local gen, spent, wasted = (fight.gen or 0), (fight.spend or 0), (fight.wasted or 0)
      totals:SetText(string.format("Generated %d | Spent %d | Wasted %d", gen, spent, wasted))
      smf:ScrollToBottom()
    else
      totals:SetText("Generated 0 | Spent 0 | Wasted 0")
    end
  end

  -- Keep header fresh while shown
  f:SetScript("OnUpdate", function(self)
    if self:IsShown() then setHeader() end
  end)

  -- Positioning: when shown, snap to the LEFT of the settings panel if possible
  f:HookScript("OnShow", function(self)
    self:ClearAllPoints()
    if PHP.SettingsPanel and PHP.SettingsPanel:IsShown() then
      self:SetPoint("TOPRIGHT", PHP.SettingsPanel, "TOPLEFT", -8, 0)
    else
      self:SetPoint("CENTER")
    end
  end)

  PHP.HPLogWindow = f
  return f
end

-- ------- Public API -------
function PHP.HPLog_OpenWindow()
  local w = ensureWindow()
  w:Show()
  if PHP.HPLog_Refresh then PHP.HPLog_Refresh() end
end

function PHP.HPLog_ToggleWindow()
  local w = ensureWindow()
  if w:IsShown() then
    w:Hide()
  else
    w:Show()
    if PHP.HPLog_Refresh then PHP.HPLog_Refresh() end
  end
end

PHP.ToggleHPLog = PHP.HPLog_ToggleWindow