-- ============================================================
-- Asylum Compagnon — Keystone.lua
-- Assistant de clé Mythique+ (esprit Portal Authority) :
--   · Auto-slot : quand le réceptacle de clé s'ouvre, on insère
--     automatiquement ta clé (hors combat, si aucune n'est déjà en place).
--   · Assistant : ajoute des boutons « Ready check » et « Pull » à la
--     fenêtre de clé (ChallengesKeystoneFrame).
-- Les deux sont activables : NS.db.keyAutoSlot / NS.db.keyAssistant.
-- Tout est sous pcall : ces API touchent une fenêtre Blizzard protégée,
-- au pire la fonctionnalité ne fait rien (jamais d'erreur bloquante).
-- ============================================================

local ADDON_NAME, NS = ...

local K = {}
NS.Keystone = K

local function autoSlotEnabled()  return not (NS.db and NS.db.keyAutoSlot  == false) end
local function assistantEnabled() return not (NS.db and NS.db.keyAssistant == false) end

-- ---------- Auto-slot ----------
-- Repère la clé dans les sacs → bag, slot (les clés ont un lien "keystone:")
local function FindKeystone()
    local getSlots = C_Container and C_Container.GetContainerNumSlots
    local getLink  = C_Container and C_Container.GetContainerItemLink
    if not (getSlots and getLink) then return end
    for bag = 0, 5 do
        for slot = 1, (getSlots(bag) or 0) do
            local ok, link = pcall(getLink, bag, slot)
            if ok and link and link:find("Hkeystone:", 1, true) then
                return bag, slot
            end
        end
    end
end

local function HasSlotted()
    if C_ChallengeMode and C_ChallengeMode.HasSlottedKeystone then
        local ok, has = pcall(C_ChallengeMode.HasSlottedKeystone)
        if ok then return has end
    end
    return false
end

function K.TrySlot()
    if not autoSlotEnabled() then return end
    if InCombatLockdown and InCombatLockdown() then return end
    if HasSlotted() then return end
    local bag, slot = FindKeystone()
    if not bag then return end
    if not (C_Container and C_Container.PickupContainerItem) then return end
    -- ne rien faire si le curseur tient déjà quelque chose
    if CursorHasItem and CursorHasItem() then return end
    pcall(C_Container.PickupContainerItem, bag, slot)
    if CursorHasItem and CursorHasItem() then
        if C_ChallengeMode and C_ChallengeMode.SlotKeystone then
            local ok = pcall(C_ChallengeMode.SlotKeystone)
            if not ok and ClearCursor then pcall(ClearCursor) end
        elseif ClearCursor then
            pcall(ClearCursor)
        end
    end
end

-- ---------- Assistant : boutons Ready check + Pull ----------
local PULL_SECONDS = 10

local function DoPull()
    if C_PartyInfo and C_PartyInfo.DoCountdown then
        pcall(C_PartyInfo.DoCountdown, PULL_SECONDS)
    end
end

local rcBtn, pullBtn
local function AddButtons(frame)
    if rcBtn or not frame then return end
    rcBtn = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
    rcBtn:SetSize(120, 22)
    rcBtn:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 0, -6)
    rcBtn:SetText(NS.L("Ready check"))
    rcBtn:SetScript("OnClick", function()
        if DoReadyCheck then pcall(DoReadyCheck) end
    end)

    pullBtn = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
    pullBtn:SetSize(120, 22)
    pullBtn:SetPoint("LEFT", rcBtn, "RIGHT", 8, 0)
    pullBtn:SetText(NS.L("Pull") .. " (" .. PULL_SECONDS .. "s)")
    pullBtn:SetScript("OnClick", DoPull)
end

function K.RefreshButtons()
    local show = assistantEnabled()
    if rcBtn then rcBtn:SetShown(show) end
    if pullBtn then pullBtn:SetShown(show) end
end

-- ---------- Hook de la fenêtre de clé ----------
local function OnFrameShown(frame)
    AddButtons(frame)
    K.RefreshButtons()
    -- petit délai : laisser la fenêtre finir de s'initialiser avant d'insérer
    if C_Timer and C_Timer.After then
        C_Timer.After(0.15, K.TrySlot)
    else
        K.TrySlot()
    end
end

local hooked = false
local function HookKeystoneFrame()
    if hooked then return end
    local frame = _G["ChallengesKeystoneFrame"]
    if not frame then return end
    hooked = true
    frame:HookScript("OnShow", function(self) pcall(OnFrameShown, self) end)
    if frame:IsShown() then pcall(OnFrameShown, frame) end
end

local ev = CreateFrame("Frame")
ev:RegisterEvent("ADDON_LOADED")
ev:SetScript("OnEvent", function(_, _, name)
    if name == "Blizzard_ChallengesUI" then
        pcall(HookKeystoneFrame)
    end
end)

-- si Blizzard_ChallengesUI est déjà chargé au moment où on arrive ici
local isLoaded = C_AddOns and C_AddOns.IsAddOnLoaded and C_AddOns.IsAddOnLoaded("Blizzard_ChallengesUI")
if isLoaded then pcall(HookKeystoneFrame) end
