-- ============================================================
-- GameSlayve Collection Flex
-- Core
-- ============================================================

GameSlayveCollectionFlexDB = GameSlayveCollectionFlexDB or {}
GameSlayveCollectionFlexDB.uiEnabled = GameSlayveCollectionFlexDB.uiEnabled or false

local function CF_Print(msg)
    print("|cffffcc33Collection Flex:|r " .. tostring(msg))
end

-- ============================================================
-- Mount Matching
-- ============================================================

local function CF_FindOwnedMountBySpellID(targetSpellID)
    if not targetSpellID then
        return nil
    end

    local mountIDs = C_MountJournal.GetMountIDs()

    for _, mountID in ipairs(mountIDs) do
        local name, spellID, icon, active, isUsable, sourceType, isFavorite,
              isFactionSpecific, faction, shouldHideOnChar, isCollected =
              C_MountJournal.GetMountInfoByID(mountID)

        if spellID == targetSpellID then
            return {
                mountID = mountID,
                name = name,
                spellID = spellID,
                isUsable = isUsable,
                isCollected = isCollected,
                shouldHideOnChar = shouldHideOnChar,
            }
        end
    end

    return nil
end

local function CF_FindTargetMountSpell()
    if not UnitExists("target") then
        return nil, "No target selected."
    end

    if not UnitIsPlayer("target") then
        return nil, "Target is not a player."
    end

    for i = 1, 40 do
        local aura = C_UnitAuras.GetAuraDataByIndex("target", i, "HELPFUL")

        if aura and aura.spellId then
            local mountID = C_MountJournal.GetMountFromSpell(aura.spellId)

            if mountID then
                return aura.spellId, aura.name
            end
        end
    end

    return nil, "No active mount found on target."
end

local function CF_SummonFallbackMount(reason)
    if reason then
        CF_Print(reason)
    end

    CF_Print("Summoning a fallback mount instead.")

    -- 0 tells Blizzard to summon a random favorite mount when available.
    -- If no favorite is available, Blizzard should pick from usable mounts.
    C_MountJournal.SummonByID(0)
end

local function CF_MatchTargetMount()
    local targetSpellID, targetAuraName = CF_FindTargetMountSpell()

    if not targetSpellID then
        CF_SummonFallbackMount("Mount match failed: " .. tostring(targetAuraName))
        return
    end

    local ownedMount = CF_FindOwnedMountBySpellID(targetSpellID)

    if not ownedMount then
        CF_SummonFallbackMount("Target is mounted with " .. tostring(targetAuraName) .. ", but you do not have that exact mount.")
        return
    end

    if ownedMount.isCollected == false then
        CF_Print("Journal warning: matched " .. tostring(ownedMount.name or targetAuraName) .. ", but isCollected returned false. Trying summon anyway.")
    end

    if ownedMount.isUsable == false then
        CF_SummonFallbackMount("You own " .. tostring(ownedMount.name or targetAuraName) .. ", but it is not usable here.")
        return
    end

    CF_Print("Attempting to match target mount: " .. tostring(ownedMount.name or targetAuraName))
    C_MountJournal.SummonByID(ownedMount.mountID)
end

-- ============================================================
-- Pet Matching
-- ============================================================

local function CF_GetTargetCreatureID()
    local guid = UnitGUID("target")

    if not guid then
        return nil
    end

    local creatureID = tonumber(string.match(guid, "%-(%d+)$"))

    if creatureID and creatureID > 0 then
        return creatureID
    end

    return nil
end

local function CF_SummonFallbackPet(reason)
    if reason then
        CF_Print(reason)
    end

    CF_Print("Summoning a fallback companion pet instead.")

    if C_PetJournal and C_PetJournal.SummonRandomPet then
        C_PetJournal.SummonRandomPet(false)
        return
    end

    CF_Print("Random pet summon API is not available in this client. Fallback pet summon skipped.")
end

local function CF_FindOwnedPetByTarget()
    if not UnitExists("target") then
        return nil, "No target selected."
    end

    local targetName = UnitName("target")
    local targetCreatureID = CF_GetTargetCreatureID()

    if not C_PetJournal or not C_PetJournal.GetNumPets or not C_PetJournal.GetPetInfoByIndex then
        return nil, "Pet journal API is not available."
    end

    local numPets = C_PetJournal.GetNumPets()

    for i = 1, numPets do
        local petID, speciesID, owned, customName, level, favorite, isRevoked,
              name, icon, petType, creatureID =
              C_PetJournal.GetPetInfoByIndex(i)

        if owned and petID then
            if targetCreatureID and creatureID == targetCreatureID then
                return petID, customName or name or targetName
            end

            if targetName and name and string.lower(targetName) == string.lower(name) then
                return petID, customName or name or targetName
            end

            if targetName and customName and string.lower(targetName) == string.lower(customName) then
                return petID, customName or name or targetName
            end
        end
    end

    return nil, "No matching owned companion pet found."
end

local function CF_MatchTargetPet()
    local petID, petNameOrReason = CF_FindOwnedPetByTarget()

if not petID then

    local targetPetName = UnitName("target") or "Unknown Pet"

    CF_SummonFallbackPet(
        "You do not own \"" ..
        tostring(targetPetName) ..
        "\". Summoning a random companion pet instead."
    )

    return
end

    CF_Print("Matching target pet: " .. tostring(petNameOrReason or UnitName("target") or "Unknown Pet"))

    if C_PetJournal and C_PetJournal.SummonPetByGUID then
        C_PetJournal.SummonPetByGUID(petID)
        return
    end

    CF_Print("Pet summon API is not available in this client.")
end

-- ============================================================
-- Toggle
-- ============================================================

local function ToggleCollectionFlex()
    if not GameSlayveCollectionFlexDB.uiEnabled then
        CF_Print("UI is currently disabled. Use /gsflex ui on to enable it.")
        return
    end

    if not CreateCollectionFlexPanel then
        CF_Print("UI file is not loaded.")
        return
    end

    local panel = CreateCollectionFlexPanel()

if panel:IsShown() then
    panel:Hide()
else
    panel:Show()
end
end

-- ============================================================
-- Slash Commands
-- ============================================================

SLASH_GAMESLAYVECOLLECTIONFLEX1 = "/gsflex"
SLASH_GAMESLAYVECOLLECTIONFLEX2 = "/collectionflex"
SLASH_GAMESLAYVECOLLECTIONFLEX3 = "/cf"

SlashCmdList["GAMESLAYVECOLLECTIONFLEX"] = function(msg)
    msg = string.lower(msg or "")

    if msg == "" or msg == "ui" or msg == "panel" then
        ToggleCollectionFlex()
        return
    end

    if msg == "match" or msg == "mount" or msg == "match mount" then
        CF_MatchTargetMount()
        return
    end

    if msg == "pet" or msg == "match pet" then
        CF_MatchTargetPet()
        return
    end

    if msg == "ui on" then
        GameSlayveCollectionFlexDB.uiEnabled = true
        CF_Print("UI enabled.")
        return
    end

    if msg == "ui off" then
        GameSlayveCollectionFlexDB.uiEnabled = false

        if CollectionFlexPanel then
            CollectionFlexPanel:Hide()
        end

        CF_Print("UI disabled.")
        return
    end

    if msg == "help" then
        CF_Print("Commands:")
        print("|cffffcc33/gsflex|r - Toggle panel")
        print("|cffffcc33/gsflex match|r - Match your target's mount")
        print("|cffffcc33/gsflex mount|r - Match your target's mount")
        print("|cffffcc33/gsflex pet|r - Match your target's companion pet")
        print("|cffffcc33/gsflex match pet|r - Match your target's companion pet")
        print("|cffffcc33/gsflex help|r - Show commands")
        print("|cffffcc33/gsflex ui on|r - Enable hidden UI preview")
        print("|cffffcc33/gsflex ui off|r - Disable hidden UI preview")
        return
    end

    CF_Print("Unknown command. Try /gsflex help")
end

-- ============================================================
-- Minimap Button
-- ============================================================

local minimapButton = CreateFrame("Button", "GameSlayveCollectionFlexMinimapButton", Minimap)
minimapButton:SetSize(28, 28)
minimapButton:SetFrameStrata("MEDIUM")
minimapButton:SetPoint("TOPLEFT", Minimap, "TOPLEFT", 0, 0)

minimapButton.texture = minimapButton:CreateTexture(nil, "ARTWORK")
minimapButton.texture:SetAllPoints(minimapButton)
minimapButton.texture:SetTexture("Interface\\Icons\\Ability_Mount_RidingHorse")

minimapButton:RegisterForClicks("AnyUp")
minimapButton:SetScript("OnClick", ToggleCollectionFlex)

minimapButton:SetScript("OnEnter", function(self)
    GameTooltip:SetOwner(self, "ANCHOR_LEFT")
    GameTooltip:AddLine("Collection Flex")
    GameTooltip:AddLine("Left-click: Toggle panel", 1, 1, 1)
    GameTooltip:AddLine("/gsflex", 1, 1, 1)
    GameTooltip:Show()
end)

minimapButton:SetScript("OnLeave", function()
    GameTooltip:Hide()
end)

-- print("|cffffcc33Collection Flex:|r clean UI foundation loaded")