-- Sleek RP - Warlock Pets (Core.lua) — Talking UI only + Chat output
local ADDON_NAME, SRPWL = ...
SRPWL = SRPWL or {}
_G.SRPWL = SRPWL

-- ====== DB (saved vars) ======
SleekRP_WLP_DB = SleekRP_WLP_DB or {}
local DB = SleekRP_WLP_DB

-- Defaults : plus de bulle, on ne garde que la Talking UI
DB.cooldown           = DB.cooldown           or 12
DB.enable_audio       = (DB.enable_audio ~= false)
DB.debug              = (DB.debug == true)

-- Talking UI (ON par défaut)
if DB.use_talking_style == nil then DB.use_talking_style = true end
DB.talking_duration   = DB.talking_duration   or 5.0
DB.talking_scale      = DB.talking_scale      or 1.0
DB.talking_lock       = (DB.talking_lock == true)

-- ====== Registre de pets ======
local REGISTRY = {}              -- key -> petTable
local PET_KEY_ACTIVE = nil       -- clé du pet actif (dérivée de "pet")

function SRPWL.RegisterPet(pet)
  if not pet or not pet.key or not pet.dialogues then return end
  REGISTRY[pet.key] = pet
end

function SRPWL.GetPet(key)
  return key and REGISTRY[key] or (PET_KEY_ACTIVE and REGISTRY[PET_KEY_ACTIVE]) or nil
end

-- Optionnel: utilisé par Events.lua pour vérifier si une clé existe dans au moins un registre
function SRPWL.HasEventKey(evKey)
  if not evKey or evKey == "" then return false end
  for _, pet in pairs(REGISTRY) do
    local d = pet and pet.dialogues
    if d and d[evKey] then return true end
  end
  return false
end

-- ====== Détection du pet du joueur ======
local FAMILY_TO_KEY = {
  ["Imp"]              = "Imp",
  ["Diablotin"]        = "Imp",           -- FR
  ["Voidwalker"]       = "Voidwalker",
  ["Marcheur du Vide"] = "Voidwalker",    -- FR
  ["Felhunter"]        = "Felhunter",
  ["Chasseur corrompu"]= "Felhunter",     -- FR
  ["Succubus"]         = "Succubus",
  ["Succube"]          = "Succubus",      -- FR
  ["Incubus"]          = "Sayaad",
  ["Sayaad"]           = "Sayaad",
  ["Felguard"]         = "Felguard",
  ["Garde funeste"]    = "Felguard",      -- FR
}

local function DetectActivePetKey()
  if UnitExists("pet") and UnitIsUnit("pet", "playerpet") then
    local family = UnitCreatureFamily("pet")
    if family and FAMILY_TO_KEY[family] then
      return FAMILY_TO_KEY[family]
    end
  end
  return nil
end

-- ====== Cooldown ======
local lastTime = 0
local function CanSpeak()
  local now = GetTime()
  local cd = DB.cooldown or 12
  if (now - lastTime) >= cd then
    lastTime = now
    return true
  end
  return false
end

-- ====== Localized Action Labels ======
local ACTION_LABELS_EN = {
  MountSummoned="Mount summoned", PotionUsed="Potion used", HealthstoneUsed="Healthstone used",
  SoulstoneApplied="Soulstone applied", HearthstoneUsed="Hearthstone used", SummonStoneUsed="Summoning stone",
  PortalUsed="Portal used", BuffReceived="Buff received", GroupInvite="Group invite",
  GroupJoined="Group joined", GroupLeft="Group left", TeammateAlmostDead="Ally critical",
  TeammateDead="Ally dead", RaidWipe="Raid wipe", LootRollWon="Loot won", LootRollLost="Loot lost",
  QuestCompleted="Quest completed", CraftingStarted="Crafting started", CraftingCompleted="Crafting finished",
  SpellCastMajor="Major spell cast", GatheringHerb="Herbalism", GatheringMine="Mining",
  FishingStarted="Fishing started", FishingCatch="Fish caught", GatheringSkin="Skinning",
  GatheringLootChest="Chest looted", GatheringQuestItem="Quest item looted", OpeningCorpseLoot="Corpse looted",
  RepairingGear="Repair", UsingVendor="Vendor", EatingDrinking="Eat/Drink", CookingStarted="Cooking",
  InnResting="Inn resting", BankUsed="Bank", MailboxUsed="Mailbox", AuctionHouseUsed="Auction House",
  TransmogUsed="Transmog", FlightPathTaken="Flight path", DungeonQueueJoin="Dungeon queue",
  ReadyCheck="Ready check", MapOpened="Map opened", PetSummoned="Pet summoned", PetResummoned="Pet resummoned",
  PetSacrificed="Pet sacrificed", BossKill="Boss defeated", EpicLoot="Epic loot", LevelUp="Level up",
  ZoneDiscovered="Zone discovered", Event_GoldReceived="Gold received",
  -- Emotes
  Emote_Hi="Hi", Emote_Love="Love", Emote_Dance="Dance", Emote_Sleep="Sleep", Emote_Pet="Pet",
  Emote_Sit="Sit", Emote_Yes="Yes", Emote_No="No", Emote_Cheer="Cheer", Emote_Clap="Clap", Emote_Thank="Thank",
  Emote_WaveKiss="Blow a kiss", Emote_Rude="Rude", Emote_Bow="Bow", Emote_Kneel="Kneel",
  Emote_Point="Point", Emote_Wave="Wave", Emote_Salute="Salute", Emote_Laugh="Laugh", Emote_Cry="Cry",
  Emote_Hug="Hug", Emote_Pat="Pat", Emote_Shrug="Shrug", Emote_Roar="Roar", Emote_Wink="Wink", Emote_Whistle="Whistle",
}
local ACTION_LABELS_FR = {
  MountSummoned="Invocation de monture", PotionUsed="Potion utilisée", HealthstoneUsed="Pierre de soin utilisée",
  SoulstoneApplied="Pierre d’âme appliquée", HearthstoneUsed="Pierre de foyer utilisée", SummonStoneUsed="Pierre d’invocation",
  PortalUsed="Portail utilisé", BuffReceived="Amélioration reçue", GroupInvite="Invitation de groupe",
  GroupJoined="Groupe rejoint", GroupLeft="Groupe quitté", TeammateAlmostDead="Allié en danger",
  TeammateDead="Allié mort", RaidWipe="Wipe du raid", LootRollWon="Jet de butin gagné",
  LootRollLost="Jet de butin perdu", QuestCompleted="Quête terminée", CraftingStarted="Fabrication commencée",
  CraftingCompleted="Fabrication terminée", SpellCastMajor="Sort majeur lancé", GatheringHerb="Herboristerie",
  GatheringMine="Minage", FishingStarted="Pêche commencée", FishingCatch="Poisson pêché", GatheringSkin="Dépeçage",
  GatheringLootChest="Coffre fouillé", GatheringQuestItem="Objet de quête récupéré", OpeningCorpseLoot="Butin sur cadavre",
  RepairingGear="Réparation", UsingVendor="Marchand", EatingDrinking="Manger/Boire", CookingStarted="Cuisine",
  InnResting="Repos à l’auberge", BankUsed="Banque", MailboxUsed="Boîte aux lettres", AuctionHouseUsed="Hôtel des ventes",
  TransmogUsed="Transmogrification", FlightPathTaken="Maître de vol", DungeonQueueJoin="File donjon",
  ReadyCheck="Vérif. des prêts", MapOpened="Carte ouverte", PetSummoned="Familier invoqué", PetResummoned="Familier réinvoqué",
  PetSacrificed="Familier sacrifié", BossKill="Boss vaincu", EpicLoot="Butin épique", LevelUp="Niveau gagné",
  ZoneDiscovered="Zone découverte", Event_GoldReceived="Or reçu",
  -- Emotes
  Emote_Hi="Salut", Emote_Love="Amour", Emote_Dance="Danse", Emote_Sleep="Sommeil", Emote_Pet="Caresse",
  Emote_Sit="Assis", Emote_Yes="Oui", Emote_No="Non", Emote_Cheer="Acclame", Emote_Clap="Applaudit", Emote_Thank="Remercie",
  Emote_WaveKiss="Envoie un baiser", Emote_Rude="Geste grossier", Emote_Bow="S’incline", Emote_Kneel="S’agenouille",
  Emote_Point="Montre du doigt", Emote_Wave="Fait signe", Emote_Salute="Salue", Emote_Laugh="Rit", Emote_Cry="Pleure",
  Emote_Hug="Câlin", Emote_Pat="Tape dans le dos", Emote_Shrug="Hausse les épaules", Emote_Roar="Rugit",
  Emote_Wink="Clin d’œil", Emote_Whistle="Siffle",
}

local function TitleCaseWords(s)
  return (s:gsub("(%a)([%w_']*)", function(a,b) return string.upper(a)..b end))
end

local function PrettyFromPrefix(eventKey, prefix, fallback)
  local tail = eventKey:sub(#prefix + 1)
  tail = tail:gsub("^_", ""):gsub("_", " ")
  tail = TitleCaseWords(tail)
  return (#tail > 0) and tail or fallback
end

local function LocalizedActionLabel(eventKey)
  local loc = GetLocale and GetLocale() or "enUS"
  local T = (loc == "frFR") and ACTION_LABELS_FR or ACTION_LABELS_EN
  local label = T[eventKey]
  if not label then
    if eventKey:find("^Zone_") then
      label = PrettyFromPrefix(eventKey,"Zone_", (loc=="frFR") and "Zone" or "Zone")
    elseif eventKey:find("^Raid_") then
      label = PrettyFromPrefix(eventKey,"Raid_", (loc=="frFR") and "Raid" or "Raid")
    else
      label = TitleCaseWords(eventKey:gsub("_"," "))
    end
  end
  return "< "..label.." >"
end

-- ====== Anti-répétition (pas 2 fois la même ligne d'affilée par event) ======
local _lastLineByKey = {}
local function pickLineNoRepeat(lines, evKey)
  if not lines or #lines == 0 then return nil end
  local choice
  if #lines == 1 then
    choice = lines[1]
  else
    local tries = 4
    repeat
      choice = lines[math.random(#lines)]
      tries = tries - 1
    until choice ~= _lastLineByKey[evKey] or tries <= 0
  end
  _lastLineByKey[evKey] = choice
  return choice
end

-- ====== Sortie Chat ======
local GOLD = "|cffffd100"          -- jaune/or
local PALE_VIOLET = "|cffdec9ff"    -- violet pâle doux
local RESET = "|r"

local function BuildPetIconTag(icon)
  if not icon then return "" end
  if type(icon) == "number" then
    return ("|T%d:16:16:0:0|t "):format(icon)
  elseif type(icon) == "string" and icon ~= "" then
    return ("|T%s:16:16:0:0|t "):format(icon)
  end
  return ""
end

function SRPWL.ChatOut(actionLabel, petName, text, icon)
  local iconTag = BuildPetIconTag(icon)
  local msg = string.format("%s%s%s %s- %s%s%s : %s%s",
    iconTag,
    GOLD, actionLabel, RESET,
    PALE_VIOLET, (petName or "Pet"), RESET,
    PALE_VIOLET, (text or ""), RESET
  )
  if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then
    DEFAULT_CHAT_FRAME:AddMessage(msg)
  else
    print(msg)
  end
end

-- ====== API publique : TrySpeak(eventKey) ======
function SRPWL.TrySpeak(eventKey)
  if not eventKey then return end
  PET_KEY_ACTIVE = DetectActivePetKey()
  local pet = SRPWL.GetPet(PET_KEY_ACTIVE)
  if not pet then return end
  if not CanSpeak() then return end

  local lines = pet.dialogues[eventKey]
  local text = pickLineNoRepeat(lines, eventKey)
  if not text then return end

  local label = LocalizedActionLabel(eventKey)
  local petName = (UnitExists("pet") and UnitName("pet")) or pet.pretty or pet.key
  local icon = (SRPWL.DemonIcons and SRPWL.DemonIcons[pet.key])

  -- Talking UI (UNIQUEMENT)
  if SRPWL.ShowTalking then
    SRPWL.ShowTalking(pet.key, petName, label, text, icon)
  end

  -- Chat
  SRPWL.ChatOut(label, petName, text, icon)

  -- Audio
  if DB.enable_audio and SRPWL.AudioPlayFor then
    SRPWL.AudioPlayFor(eventKey, pet.key, text)
  end
end

-- ===== Events WoW =====
local _loginAt = 0
local f = CreateFrame("Frame")
f:RegisterEvent("PLAYER_LOGIN")
f:RegisterEvent("UNIT_PET")

-- 🐾 Suivi du GUID du familier pour distinguer “PetSummoned” vs “PetResummoned”
f._lastPetGUID = nil

f:SetScript("OnEvent", function(_, ev, ...)
  if ev == "PLAYER_LOGIN" then
    PET_KEY_ACTIVE = DetectActivePetKey()
    -- Talking UI ON à chaque login (au cas où une ancienne valeur OFF traîne)
    SleekRP_WLP_DB.use_talking_style = true
    _loginAt = GetTime()
    f._lastPetGUID = UnitGUID("pet") -- init (nil si pas de pet)

  elseif ev == "UNIT_PET" then
    local unit = ...
    if unit == "player" then
      -- Petit délai pour laisser le nouveau pet s'instancier correctement
      local afterLogin = (GetTime() - (_loginAt or 0)) > 5
      C_Timer.After(0.25, function()
        PET_KEY_ACTIVE = DetectActivePetKey()
        local g = UnitGUID("pet")
        if afterLogin then
          if g and not f._lastPetGUID then
            SRPWL.TrySpeak("PetSummoned")
          elseif g and f._lastPetGUID and g ~= f._lastPetGUID then
            SRPWL.TrySpeak("PetResummoned")
          end
        end
        f._lastPetGUID = g
      end)
    end
  end
end)

-- ===== Slash tests =====
SLASH_SLEEKRP1 = "/srp"
SlashCmdList["SLEEKRP"] = function(msg)
  local cmd, a, b = msg:match("^(%S+)%s*(%S*)%s*(%S*)")
  cmd = cmd and cmd:lower() or ""

  if cmd == "test" then
    local eventKey = (a ~= "" and a) or "PetSummoned"
    local petKey = (b ~= "" and b) or PET_KEY_ACTIVE
    local pet = SRPWL.GetPet(petKey)
    if not pet then
      print("|cffa9a9ff[SRP]|r Test: unknown pet key.")
      return
    end
    local lines = pet.dialogues[eventKey]
    local function pickLineLocal(t) if t and #t>0 then return t[math.random(#t)] end end
    local text = pickLineLocal(lines) or "(no line)"
    local label = LocalizedActionLabel(eventKey)
    local petName = (UnitExists("pet") and UnitName("pet")) or (pet.pretty or pet.key)
    local icon = (SRPWL.DemonIcons and SRPWL.DemonIcons[pet.key])

    if SRPWL.ShowTalking then
      SRPWL.ShowTalking(pet.key, petName, label, text, icon)
    end
    SRPWL.ChatOut(label, petName, text, icon)

    if DB.enable_audio and SRPWL.AudioPlayFor and lines and #lines > 0 then
      SRPWL.AudioPlayFor(eventKey, pet.key, text)
    end
    print("|cffa9a9ff[SRP]|r Test:", (petKey or "?"), "["..eventKey.."] ->", text)
    return
  end

  print("|cffa9a9ff[SRP]|r Usage:")
  print("  /srp test [EventKey] [PetKey]")
end
