--[[
  SpellSmasher v4.0.0 - clean rewrite

  (c) Tracy Howard / SpellSmasher. Own product.
  OOC compile  >  Priority / Reverse Priority triangle  >  SecureActionButton one cast per mash  >  always advance.

  Iron rules:
  - Cast only what's on the sequence list
  - Easy helpers only if On
  - No secret code-injected spells
  - [nochanneling] on combat casts
  - Pack: !SpellSmasher!1! base64 JSON (site parity)

  /spellsmasher  /ssm
]]

local NS = SpellSmasherNS

print("|cff3dd68c[SpellSmasher]|r loading v" .. NS.VERSION .. " ...")

local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("ADDON_LOADED")
eventFrame:RegisterEvent("PLAYER_LOGIN")
eventFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
eventFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
eventFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
eventFrame:RegisterEvent("PLAYER_LEVEL_UP")
eventFrame:RegisterEvent("PLAYER_LEVEL_CHANGED")

eventFrame:SetScript("OnEvent", function(_, event, arg1)
  if event == "ADDON_LOADED" and arg1 == "SpellSmasher" then
  NS.MergeDB()
  elseif event == "PLAYER_LOGIN" or event == "PLAYER_ENTERING_WORLD" then
  if not NS.db then
  NS.MergeDB()
  end
  NS.Secure.CreateButton()
  NS.Secure.ApplyLayout()
  -- Account-wide pack list: prefer an Active pack for this character's class
  if NS.EnsureActivePackForPlayer and NS.EnsureActivePackForPlayer() then
  NS.Print("|cff3dd68cActive pack|r set to a list for your class.")
  end
  if not InCombatLockdown() then
  NS.Secure.Recompile()
  else
  NS.pendingRecompile = true
  end
  if NS.db and NS.db.firstRun then
  NS.db.firstRun = false
  NS.Print("v" .. NS.VERSION .. "  -  /spellsmasher  -  open UI for the in-game guide")
  NS.Print("Mash casts ONLY your sequence list. Easy AA/RT/DEF default Off. List = your class by default.")
  end
  if NS.UI and NS.UI.UpdateTalentApplyEnabled then
  NS.UI.UpdateTalentApplyEnabled()
  end
  -- Do NOT auto-overwrite Method pack talent strings with live CUk on login.
  -- Method packs keep Method loadouts (spell list + tree pair). Use From me / Export for live.
  elseif event == "PLAYER_LEVEL_UP" or event == "PLAYER_LEVEL_CHANGED" then
  if NS.UI and NS.UI.UpdateTalentApplyEnabled then
  NS.UI.UpdateTalentApplyEnabled()
  end
  elseif event == "PLAYER_REGEN_ENABLED" then
  if NS.pendingLayout then
  NS.Secure.ApplyLayout()
  end
  if NS.pendingRecompile then
  NS.Secure.Recompile()
  else
  -- Leave combat: reset Once engagement + mash step to openers
  if NS.Secure.ResetOnceEngagement then
  NS.Secure.ResetOnceEngagement("leave-combat")
  elseif NS.Secure.seqButton and not InCombatLockdown() then
  NS.Secure.seqButton:SetAttribute("step", 1)
  NS.Secure.seqButton:SetAttribute("aoe_step", 1)
  end
  end
  if NS.pendingOnceReset and NS.Secure.ResetOnceEngagement then
  NS.Secure.ResetOnceEngagement("pending")
  end
  elseif event == "PLAYER_TARGET_CHANGED" then
  -- OOC only (cannot SetAttribute from insecure code in combat).
  -- Mid-fight retarget: Once stays skipped until leave combat.
  if not InCombatLockdown() and NS.Secure.ResetOnceEngagement then
  NS.Secure.ResetOnceEngagement("target-changed-ooc")
  end
  end
end)

local function SlashHandler(msg)
  msg = NS.Trim(msg or ""):lower()
  if msg == "" or msg == "open" or msg == "ui" then
  NS.UI.Toggle()
  return
  end
  if msg == "recompile" or msg == "compile" then
  NS.Secure.verboseCompile = true
  NS.Secure.Recompile()
  return
  end
  if msg == "quiet" then
  NS.Secure.verboseCompile = false
  NS.Print("Compile chat spam off (default). Use |cff3dd68c/ssm recompile|r when you want one summary.")
  return
  end
  if msg == "secure" or msg == "dump" then
  NS.Secure.DumpSample(15)
  return
  end
  if msg == "reset" then
  if NS.Secure.seqButton and not InCombatLockdown() then
  NS.Secure.seqButton:SetAttribute("step", 1)
  NS.Secure.seqButton:SetAttribute("aoe_step", 1)
  NS.Print("Step reset to 1.")
  end
  return
  end
  if msg == "hide" then
  if NS.db then
  NS.db.hidden = true
  NS.Secure.ApplyLayout()
  NS.Print("Floating button hidden (bar mash still works).")
  end
  return
  end
  if msg == "show" then
  if NS.db then
  NS.db.hidden = false
  NS.db.hideFloatingWhenBar = false
  NS.Secure.ApplyLayout()
  NS.Print("Floating button shown.")
  end
  return
  end
  if msg == "lock" then
  if NS.db then
  NS.db.locked = not NS.db.locked
  NS.Secure.ApplyLayout()
  NS.Print(NS.db.locked and "Button locked" or "Button unlocked")
  end
  return
  end
  if msg == "version" or msg == "ver" then
  NS.Print("v" .. NS.VERSION .. "  -  priority-triangle  -  reverse-pri  -  sequence-only")
  return
  end
  if msg == "help" or msg == "guide" or msg == "coach" or msg == "tutorial" then
  if NS.UI and NS.UI.ShowCoach then
  NS.UI.Open()
  NS.UI.ShowCoach(1)
  else
  NS.Print("/ssm - open UI")
  NS.Print("/ssm help - in-game guide")
  NS.Print("/ssm recompile - rebuild secure step list")
  NS.Print("/ssm secure - dump first macrotexts (must be list spells only)")
  NS.Print("/ssm reset - step 1")
  NS.Print("/ssm show|hide|lock")
  end
  return
  end
  NS.UI.Toggle()
end

SLASH_SPELLSMASHER1 = "/spellsmasher"
SLASH_SPELLSMASHER2 = "/ssm"
SlashCmdList["SPELLSMASHER"] = SlashHandler

-- Export a few globals for debugging
SpellSmasher = NS
