local DR = select(2, ...)

--- Slim always-on status bar: raid-mode status, who the RL is, your current
--- roll power, and quick-open buttons for the main windows. Toggle with
--- /droll bar (or the Interface options); drag to move when unlocked.
local Toolbar = {
  frame = nil,
}
LibStub("AceEvent-3.0"):Embed(Toolbar)

local BAR_HEIGHT = 26

local function Kit()
  return DR:Require("UI.Kit")
end

local function isLocked()
  return DR.db.profile.ui.toolbarLocked == true
end

local function getLeaderText()
  if not IsInGroup() then
    return "RL: -"
  end
  if UnitIsGroupLeader("player") then
    return "RL: |cffffb84cYou|r"
  end
  if IsInRaid() then
    for i = 1, (GetNumGroupMembers() or 0) do
      local unit = "raid" .. i
      if UnitExists(unit) and UnitIsGroupLeader(unit) then
        return "RL: " .. (UnitName(unit) or "?")
      end
    end
  else
    for i = 1, 4 do
      local unit = "party" .. i
      if UnitExists(unit) and UnitIsGroupLeader(unit) then
        return "RL: " .. (UnitName(unit) or "?")
      end
    end
  end
  return "RL: ?"
end

function Toolbar:CreateBar()
  if self.frame then
    return self.frame
  end

  local kit = Kit()
  local C = kit.COLORS

  local frame = CreateFrame("Frame", "DetentionRollsToolbar", UIParent, "BackdropTemplate")
  frame:SetSize(560, BAR_HEIGHT)
  frame:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8", edgeFile = "Interface\\Buttons\\WHITE8X8", edgeSize = 1 })
  frame:SetBackdropColor(unpack(C.bg))
  frame:SetBackdropBorderColor(unpack(C.border))
  frame:SetMovable(true)
  frame:SetClampedToScreen(true)
  frame:EnableMouse(true)
  frame:RegisterForDrag("LeftButton")
  frame:SetScript("OnDragStart", function(f)
    if not isLocked() then
      f:StartMoving()
    end
  end)
  frame:SetScript("OnDragStop", function(f)
    f:StopMovingOrSizing()
    kit:SavePosition("Toolbar", f)
  end)

  local title = kit:CreateLabel(frame, "DR", "small", C.accent)
  title:SetPoint("LEFT", 8, 0)

  local statusText = kit:CreateLabel(frame, "", "small")
  statusText:SetPoint("LEFT", title, "RIGHT", 8, 0)
  statusText:SetWidth(56)
  statusText:SetJustifyH("LEFT")
  frame.statusText = statusText

  local rlText = kit:CreateLabel(frame, "", "small", C.textDim)
  rlText:SetPoint("LEFT", statusText, "RIGHT", 4, 0)
  rlText:SetWidth(120)
  rlText:SetJustifyH("LEFT")
  rlText:SetWordWrap(false)
  frame.rlText = rlText

  local powerText = kit:CreateLabel(frame, "", "small")
  powerText:SetPoint("LEFT", rlText, "RIGHT", 4, 0)
  powerText:SetWidth(96)
  powerText:SetJustifyH("LEFT")
  frame.powerText = powerText

  -- quick-open buttons, right-aligned; lock toggle at the far right
  local lockBtn = kit:CreateButton(frame, "L", 20, 18, function()
    DR.db.profile.ui.toolbarLocked = not isLocked()
    DR:Print("Toolbar " .. (isLocked() and "locked" or "unlocked (drag to move)"))
    Toolbar:Refresh()
  end, { smallText = true })
  lockBtn:SetPoint("RIGHT", -4, 0)
  lockBtn:HookScript("OnEnter", function(b)
    GameTooltip:SetOwner(b, "ANCHOR_TOP")
    GameTooltip:SetText(isLocked() and "Locked - click to unlock and move" or "Unlocked - drag the bar to move, click to lock", 1, 1, 1, 1, true)
    GameTooltip:Show()
  end)
  lockBtn:HookScript("OnLeave", function()
    GameTooltip:Hide()
  end)
  frame.lockBtn = lockBtn

  local defs = {
    { label = "Trades", width = 52, open = function() DR:Require("Modules.DeferredTradeFrame"):Toggle() end },
    { label = "Roster", width = 52, open = function() DR:Require("Modules.RosterFrame"):Toggle() end },
    { label = "RL", width = 30, open = function() DR:Require("Modules.RaidLeaderFrame"):Toggle() end },
    { label = "Loot", width = 42, open = function() DR:Require("Modules.RaiderFrame"):Toggle() end },
  }
  local anchor = lockBtn
  for _, def in ipairs(defs) do
    local btn = kit:CreateButton(frame, def.label, def.width, 18, def.open, { smallText = true })
    btn:SetPoint("RIGHT", anchor, "LEFT", -4, 0)
    anchor = btn
  end

  kit:RestorePosition("Toolbar", frame, 0, 340)

  frame.updateAccumulator = 0
  frame:SetScript("OnUpdate", function(f, elapsed)
    f.updateAccumulator = f.updateAccumulator + elapsed
    if f.updateAccumulator < 2 then
      return
    end
    f.updateAccumulator = 0
    Toolbar:Refresh()
  end)

  self.frame = frame
  return frame
end

function Toolbar:Refresh()
  local frame = self:CreateBar()

  if not DR.db.profile.ui.toolbarShown then
    frame:Hide()
    return
  end
  frame:Show()

  if DR:Require("Modules.RaidActivation"):IsActive() then
    frame.statusText:SetText("|cff6bcc7aActive|r")
  else
    frame.statusText:SetText("|cff9a9baaInactive|r")
  end

  frame.rlText:SetText(getLeaderText())

  local guid = UnitGUID("player")
  local weight = guid and DR:Require("Services.Ledger"):GetWeight(guid) or 100
  frame.powerText:SetText(string.format("Power: |cffffb84c%s%%|r",
    DR:Require("Domain.RollEngine"):FormatWeight(weight)))

  local kit = Kit()
  if isLocked() then
    frame.lockBtn.label:SetTextColor(unpack(kit.COLORS.accent))
  else
    local c = kit.COLORS.textDim
    frame.lockBtn.label:SetTextColor(c[1], c[2], c[3], c[4] or 1)
  end
end

function Toolbar:Toggle()
  DR.db.profile.ui.toolbarShown = not DR.db.profile.ui.toolbarShown
  self:Refresh()
end

function Toolbar:OnInitialize()
  self:CreateBar()

  self:RegisterMessage("DR_RAID_ACTIVE_CHANGED", function()
    self:Refresh()
  end)
  self:RegisterMessage("DR_SESSION_REWARDED", function()
    self:Refresh()
  end)
  self:RegisterMessage("DR_ROSTER_SYNCED", function()
    self:Refresh()
  end)
  self:RegisterEvent("GROUP_ROSTER_UPDATE", function()
    self:Refresh()
  end)
  self:RegisterEvent("PARTY_LEADER_CHANGED", function()
    self:Refresh()
  end)
end

function Toolbar:OnEnable()
  self:Refresh()
end

DR:RegisterModule("Modules.Toolbar", Toolbar)
