using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using UnityEngine;

namespace Set.Data
{
    public class TraitsMapping : MonoBehaviour
    {
        // long for champion, int for traits
        public static int TotalChampionCout = 63;
        public static int TotalTraitCount = 25;
        public static Dictionary<long, int> ChampsTraits = new Dictionary<long, int>
        {
            // Cost 1 Champions
            {
                (long)ChampionsEnum.AATROX,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MIGHTYMECH, TraitsEnum.HEAVYWEIGHT, TraitsEnum.JUGGERNAUT }
                )
            },
            {
                (long)ChampionsEnum.EZREAL,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.BATTLEACADEMIA, TraitsEnum.PRODIGY }
                )
            },
            {
                (long)ChampionsEnum.GAREN,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.BATTLEACADEMIA, TraitsEnum.BASTION }
                )
            },
            {
                (long)ChampionsEnum.GNAR,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.LUCHADOR, TraitsEnum.SNIPER }
                )
            },
            {
                (long)ChampionsEnum.KALISTA,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SOULFIGHTER, TraitsEnum.EXECUTIONER }
                )
            },
            {
                (long)ChampionsEnum.KAYLE,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.WRAITH, TraitsEnum.DUELIST }
                )
            },
            {
                (long)ChampionsEnum.KENNEN,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SUPREMECELLS, TraitsEnum.PROTECTOR, TraitsEnum.SORCERER }
                )
            },
            {
                (long)ChampionsEnum.LUCIAN,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MIGHTYMECH, TraitsEnum.SORCERER }
                )
            },
            {
                (long)ChampionsEnum.MALPHITE,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.THECREW, TraitsEnum.PROTECTOR }
                )
            },
            {
                (long)ChampionsEnum.NAAFIRI,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SOULFIGHTER, TraitsEnum.JUGGERNAUT }
                )
            },
            {
                (long)ChampionsEnum.RELL,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.STARGUARDIAN, TraitsEnum.BASTION }
                )
            },
            {
                (long)ChampionsEnum.SIVIR,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.THECREW, TraitsEnum.SNIPER }
                )
            },
            {
                (long)ChampionsEnum.SYNDRA,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.CRYSTALGAMBIT, TraitsEnum.STARGUARDIAN, TraitsEnum.PRODIGY }
                )
            },
            {
                (long)ChampionsEnum.ZAC,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.WRAITH, TraitsEnum.HEAVYWEIGHT }
                )
            },

            // Cost 2 Champions
            {
                (long)ChampionsEnum.DRMUNDO,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.LUCHADOR, TraitsEnum.JUGGERNAUT }
                )
            },
            {
                (long)ChampionsEnum.GANGPLANK,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MIGHTYMECH, TraitsEnum.DUELIST }
                )
            },
            {
                (long)ChampionsEnum.JANNA,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.CRYSTALGAMBIT, TraitsEnum.PROTECTOR, TraitsEnum.STRATEGIST }
                )
            },
            {
                (long)ChampionsEnum.JHIN,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.WRAITH, TraitsEnum.SNIPER }
                )
            },
            {
                (long)ChampionsEnum.KAISA,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SUPREMECELLS, TraitsEnum.DUELIST }
                )
            },
            {
                (long)ChampionsEnum.KATARINA,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.BATTLEACADEMIA, TraitsEnum.EXECUTIONER }
                )
            },
            {
                (long)ChampionsEnum.KOBUKO,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MENTOR, TraitsEnum.HEAVYWEIGHT }
                )
            },
            {
                (long)ChampionsEnum.LUX,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SOULFIGHTER, TraitsEnum.SORCERER }
                )
            },
            {
                (long)ChampionsEnum.RAKAN,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.BATTLEACADEMIA, TraitsEnum.PROTECTOR }
                )
            },
            {
                (long)ChampionsEnum.SHEN,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.THECREW, TraitsEnum.BASTION, TraitsEnum.EDGELORD }
                )
            },
            {
                (long)ChampionsEnum.VI,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.CRYSTALGAMBIT, TraitsEnum.JUGGERNAUT }
                )
            },
            {
                (long)ChampionsEnum.XAYAH,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.STARGUARDIAN, TraitsEnum.EDGELORD }
                )
            },
            {
                (long)ChampionsEnum.XINZHAO,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SOULFIGHTER, TraitsEnum.BASTION }
                )
            },

            // Cost 3 Champions
            {
                (long)ChampionsEnum.AHRI,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.STARGUARDIAN, TraitsEnum.SORCERER }
                )
            },
            {
                (long)ChampionsEnum.CAITLYN,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.BATTLEACADEMIA, TraitsEnum.SNIPER }
                )
            },
            {
                (long)ChampionsEnum.DARIUS,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SUPREMECELLS, TraitsEnum.HEAVYWEIGHT }
                )
            },
            {
                (long)ChampionsEnum.JAYCE,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.BATTLEACADEMIA, TraitsEnum.HEAVYWEIGHT }
                )
            },
            {
                (long)ChampionsEnum.KOGMAW,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MONSTERTRAINER }
                )
            },
            {
                (long)ChampionsEnum.LULU,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MONSTERTRAINER }
                )
            },
            {
                (long)ChampionsEnum.MALZAHAR,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.WRAITH, TraitsEnum.PRODIGY }
                )
            },
            {
                (long)ChampionsEnum.NEEKO,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.STARGUARDIAN, TraitsEnum.PROTECTOR }
                )
            },
            {
                (long)ChampionsEnum.RAMMUS,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MONSTERTRAINER }
                )
            },
            {
                (long)ChampionsEnum.SENNA,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MIGHTYMECH, TraitsEnum.EXECUTIONER }
                )
            },
            {
                (long)ChampionsEnum.SMOLDER,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MONSTERTRAINER }
                )
            },
            {
                (long)ChampionsEnum.SWAIN,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.CRYSTALGAMBIT, TraitsEnum.BASTION, TraitsEnum.SORCERER }
                )
            },
            {
                (long)ChampionsEnum.UDYR,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MENTOR, TraitsEnum.JUGGERNAUT, TraitsEnum.DUELIST }
                )
            },
            {
                (long)ChampionsEnum.VIEGO,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SOULFIGHTER, TraitsEnum.DUELIST }
                )
            },
            {
                (long)ChampionsEnum.YASUO,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MENTOR, TraitsEnum.EDGELORD }
                )
            },
            {
                (long)ChampionsEnum.ZIGGS,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.THECREW, TraitsEnum.STRATEGIST }
                )
            },

            // Cost 4 Champions
            {
                (long)ChampionsEnum.AKALI,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SUPREMECELLS, TraitsEnum.EXECUTIONER }
                )
            },
            {
                (long)ChampionsEnum.ASHE,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.CRYSTALGAMBIT, TraitsEnum.DUELIST }
                )
            },
            {
                (long)ChampionsEnum.JARVANIV,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MIGHTYMECH, TraitsEnum.STRATEGIST }
                )
            },
            {
                (long)ChampionsEnum.JINX,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.STARGUARDIAN, TraitsEnum.SNIPER }
                )
            },
            {
                (long)ChampionsEnum.KARMA,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MIGHTYMECH, TraitsEnum.SORCERER }
                )
            },
            {
                (long)ChampionsEnum.KSANTE,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.WRAITH, TraitsEnum.PROTECTOR }
                )
            },
            {
                (long)ChampionsEnum.LEONA,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.BATTLEACADEMIA, TraitsEnum.BASTION }
                )
            },
            {
                (long)ChampionsEnum.POPPY,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.STARGUARDIAN, TraitsEnum.HEAVYWEIGHT }
                )
            },
            {
                (long)ChampionsEnum.RYZE,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.MENTOR, TraitsEnum.EXECUTIONER, TraitsEnum.STRATEGIST }
                )
            },
            {
                (long)ChampionsEnum.SAMIRA,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SOULFIGHTER, TraitsEnum.EDGELORD }
                )
            },
            {
                (long)ChampionsEnum.SETT,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SOULFIGHTER, TraitsEnum.JUGGERNAUT }
                )
            },
            {
                (long)ChampionsEnum.VOLIBEAR,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.LUCHADOR, TraitsEnum.EDGELORD }
                )
            },
            {
                (long)ChampionsEnum.YUUMI,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.BATTLEACADEMIA, TraitsEnum.PRODIGY }
                )
            },

            // Cost 5 Champions
            {
                (long)ChampionsEnum.BRAUM,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.THECHAMP, TraitsEnum.LUCHADOR, TraitsEnum.BASTION }
                )
            },
            {
                (long)ChampionsEnum.EKKO,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.PRODIGY, TraitsEnum.SORCERER, TraitsEnum.STRATEGIST }
                )
            },
            {
                (long)ChampionsEnum.GWEN,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.SOULFIGHTER, TraitsEnum.SORCERER }
                )
            },
            {
                (long)ChampionsEnum.LEESIN,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.STANCEMASTER, TraitsEnum.DUELIST, TraitsEnum.JUGGERNAUT, TraitsEnum.EXECUTIONER }
                )
            },
            {
                (long)ChampionsEnum.SERAPHINE,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.STARGUARDIAN, TraitsEnum.PRODIGY }
                )
            },
            {
                (long)ChampionsEnum.TWISTEDFATE,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.ROGUECAPTAIN, TraitsEnum.THECREW }
                )
            },
            {
                (long)ChampionsEnum.VARUS,
                TraitUtils.ToInt(
                    new HashSet<TraitsEnum> { TraitsEnum.WRAITH, TraitsEnum.SNIPER }
                )
            },
        };

        public static Dictionary<int, long> TraitsChamp = new Dictionary<int, long>
        {
            {
                (int)TraitsEnum.BATTLEACADEMIA,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.EZREAL,
                        ChampionsEnum.GAREN,
                        ChampionsEnum.KATARINA,
                        ChampionsEnum.RAKAN,
                        ChampionsEnum.CAITLYN,
                        ChampionsEnum.JAYCE,
                        ChampionsEnum.LEONA,
                        ChampionsEnum.YUUMI,
                    }
                )
            },
            {
                (int)TraitsEnum.CRYSTALGAMBIT,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.SYNDRA,
                        ChampionsEnum.JANNA,
                        ChampionsEnum.VI,
                        ChampionsEnum.ASHE,
                        ChampionsEnum.SWAIN,
                    }
                )
            },
            {
                (int)TraitsEnum.LUCHADOR,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.GNAR,
                        ChampionsEnum.DRMUNDO,
                        ChampionsEnum.BRAUM,
                        ChampionsEnum.VOLIBEAR,
                    }
                )
            },
            {
                (int)TraitsEnum.MIGHTYMECH,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.AATROX,
                        ChampionsEnum.LUCIAN,
                        ChampionsEnum.GANGPLANK,
                        ChampionsEnum.SENNA,
                        ChampionsEnum.JARVANIV,
                        ChampionsEnum.KARMA,
                    }
                )
            },
            {
                (int)TraitsEnum.MONSTERTRAINER,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.KOGMAW,
                        ChampionsEnum.LULU,
                        ChampionsEnum.RAMMUS,
                        ChampionsEnum.SMOLDER,
                    }
                )
            },
            {
                (int)TraitsEnum.SOULFIGHTER,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.KALISTA,
                        ChampionsEnum.NAAFIRI,
                        ChampionsEnum.LUX,
                        ChampionsEnum.XINZHAO,
                        ChampionsEnum.VIEGO,
                        ChampionsEnum.SAMIRA,
                        ChampionsEnum.SETT,
                        ChampionsEnum.GWEN,
                    }
                )
            },
            {
                (int)TraitsEnum.STARGUARDIAN,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.RELL,
                        ChampionsEnum.SYNDRA,
                        ChampionsEnum.XAYAH,
                        ChampionsEnum.AHRI,
                        ChampionsEnum.NEEKO,
                        ChampionsEnum.JINX,
                        ChampionsEnum.POPPY,
                        ChampionsEnum.SERAPHINE,
                    }
                )
            },
            {
                (int)TraitsEnum.SUPREMECELLS,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.KENNEN,
                        ChampionsEnum.KAISA,
                        ChampionsEnum.DARIUS,
                        ChampionsEnum.AKALI,
                    }
                )
            },
            {
                (int)TraitsEnum.THECREW,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.MALPHITE,
                        ChampionsEnum.SIVIR,
                        ChampionsEnum.SHEN,
                        ChampionsEnum.ZIGGS,
                        ChampionsEnum.TWISTEDFATE,
                    }
                )
            },
            {
                (int)TraitsEnum.WRAITH,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.KAYLE,
                        ChampionsEnum.ZAC,
                        ChampionsEnum.JHIN,
                        ChampionsEnum.MALZAHAR,
                        ChampionsEnum.KSANTE,
                        ChampionsEnum.VARUS,
                    }
                )
            },
            {
                (int)TraitsEnum.MENTOR,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.KOBUKO,
                        ChampionsEnum.UDYR,
                        ChampionsEnum.YASUO,
                        ChampionsEnum.RYZE,
                    }
                )
            },
            {
                (int)TraitsEnum.PRODIGY,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.EZREAL,
                        ChampionsEnum.SYNDRA,
                        ChampionsEnum.MALZAHAR,
                        ChampionsEnum.YUUMI,
                        ChampionsEnum.EKKO,
                        ChampionsEnum.SERAPHINE,
                    }
                )
            },
            {
                (int)TraitsEnum.THECHAMP,
                ChampionUtils.ToLong(new HashSet<ChampionsEnum>() { ChampionsEnum.BRAUM })
            },
            {
                (int)TraitsEnum.STANCEMASTER,
                ChampionUtils.ToLong(new HashSet<ChampionsEnum>() { ChampionsEnum.LEESIN })
            },
            {
                (int)TraitsEnum.ROGUECAPTAIN,
                ChampionUtils.ToLong(new HashSet<ChampionsEnum>() { ChampionsEnum.TWISTEDFATE })
            },
            {
                (int)TraitsEnum.BASTION,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.GAREN,
                        ChampionsEnum.RELL,
                        ChampionsEnum.SHEN,
                        ChampionsEnum.XINZHAO,
                        ChampionsEnum.SWAIN,
                        ChampionsEnum.LEONA,
                        ChampionsEnum.BRAUM,
                    }
                )
            },
            {
                (int)TraitsEnum.DUELIST,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.KAYLE,
                        ChampionsEnum.GANGPLANK,
                        ChampionsEnum.KAISA,
                        ChampionsEnum.ASHE,
                        ChampionsEnum.UDYR,
                        ChampionsEnum.VIEGO,
                        ChampionsEnum.LEESIN,
                    }
                )
            },
            {
                (int)TraitsEnum.EDGELORD,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.SHEN,
                        ChampionsEnum.XAYAH,
                        ChampionsEnum.YASUO,
                        ChampionsEnum.SAMIRA,
                        ChampionsEnum.VOLIBEAR,
                    }
                )
            },
            {
                (int)TraitsEnum.EXECUTIONER,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.KALISTA,
                        ChampionsEnum.KATARINA,
                        ChampionsEnum.AKALI,
                        ChampionsEnum.RYZE,
                        ChampionsEnum.SENNA,
                        ChampionsEnum.LEESIN,
                    }
                )
            },
            {
                (int)TraitsEnum.HEAVYWEIGHT,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.AATROX,
                        ChampionsEnum.ZAC,
                        ChampionsEnum.KOBUKO,
                        ChampionsEnum.DARIUS,
                        ChampionsEnum.JAYCE,
                        ChampionsEnum.POPPY,
                    }
                )
            },
            {
                (int)TraitsEnum.JUGGERNAUT,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.AATROX,
                        ChampionsEnum.NAAFIRI,
                        ChampionsEnum.DRMUNDO,
                        ChampionsEnum.VI,
                        ChampionsEnum.UDYR,
                        ChampionsEnum.SETT,
                        ChampionsEnum.LEESIN,
                    }
                )
            },
            {
                (int)TraitsEnum.PROTECTOR,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.KENNEN,
                        ChampionsEnum.MALPHITE,
                        ChampionsEnum.JANNA,
                        ChampionsEnum.RAKAN,
                        ChampionsEnum.NEEKO,
                        ChampionsEnum.KSANTE,
                    }
                )
            },
            {
                (int)TraitsEnum.SNIPER,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.GNAR,
                        ChampionsEnum.SIVIR,
                        ChampionsEnum.JHIN,
                        ChampionsEnum.CAITLYN,
                        ChampionsEnum.JINX,
                        ChampionsEnum.VARUS,
                    }
                )
            },
            {
                (int)TraitsEnum.SORCERER,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.KENNEN,
                        ChampionsEnum.LUCIAN,
                        ChampionsEnum.LUX,
                        ChampionsEnum.AHRI,
                        ChampionsEnum.SWAIN,
                        ChampionsEnum.KARMA,
                        ChampionsEnum.EKKO,
                        ChampionsEnum.GWEN,
                    }
                )
            },
            {
                (int)TraitsEnum.STRATEGIST,
                ChampionUtils.ToLong(
                    new HashSet<ChampionsEnum>()
                    {
                        ChampionsEnum.JANNA,
                        ChampionsEnum.ZIGGS,
                        ChampionsEnum.JARVANIV,
                        ChampionsEnum.RYZE,
                        ChampionsEnum.EKKO,
                    }
                )
            },
        };

        public Dictionary<long, int> ChampionCost = new Dictionary<long, int>()
        {
            // Cost 1 Champions
            { (long)ChampionsEnum.AATROX, 1 },
            { (long)ChampionsEnum.EZREAL, 1 },
            { (long)ChampionsEnum.GAREN, 1 },
            { (long)ChampionsEnum.GNAR, 1 },
            { (long)ChampionsEnum.KALISTA, 1 },
            { (long)ChampionsEnum.KAYLE, 1 },
            { (long)ChampionsEnum.KENNEN, 1 },
            { (long)ChampionsEnum.LUCIAN, 1 },
            { (long)ChampionsEnum.MALPHITE, 1 },
            { (long)ChampionsEnum.NAAFIRI, 1 },
            { (long)ChampionsEnum.RELL, 1 },
            { (long)ChampionsEnum.SIVIR, 1 },
            { (long)ChampionsEnum.SYNDRA, 1 },
            { (long)ChampionsEnum.ZAC, 1 },

            // Cost 2 Champions
            { (long)ChampionsEnum.DRMUNDO, 2 },
            { (long)ChampionsEnum.GANGPLANK, 2 },
            { (long)ChampionsEnum.JANNA, 2 },
            { (long)ChampionsEnum.JHIN, 2 },
            { (long)ChampionsEnum.KAISA, 2 },
            { (long)ChampionsEnum.KATARINA, 2 },
            { (long)ChampionsEnum.KOBUKO, 2 },
            { (long)ChampionsEnum.LUX, 2 },
            { (long)ChampionsEnum.RAKAN, 2 },
            { (long)ChampionsEnum.SHEN, 2 },
            { (long)ChampionsEnum.VI, 2 },
            { (long)ChampionsEnum.XAYAH, 2 },
            { (long)ChampionsEnum.XINZHAO, 2 },

            // Cost 3 Champions
            { (long)ChampionsEnum.AHRI, 3 },
            { (long)ChampionsEnum.CAITLYN, 3 },
            { (long)ChampionsEnum.DARIUS, 3 },
            { (long)ChampionsEnum.JAYCE, 3 },
            { (long)ChampionsEnum.KOGMAW, 3 },
            { (long)ChampionsEnum.LULU, 3 },
            { (long)ChampionsEnum.MALZAHAR, 3 },
            { (long)ChampionsEnum.NEEKO, 3 },
            { (long)ChampionsEnum.RAMMUS, 3 },
            { (long)ChampionsEnum.SENNA, 3 },
            { (long)ChampionsEnum.SMOLDER, 3 },
            { (long)ChampionsEnum.SWAIN, 3 },
            { (long)ChampionsEnum.UDYR, 3 },
            { (long)ChampionsEnum.VIEGO, 3 },
            { (long)ChampionsEnum.YASUO, 3 },
            { (long)ChampionsEnum.ZIGGS, 3 },

            // Cost 4 Champions
            { (long)ChampionsEnum.AKALI, 4 },
            { (long)ChampionsEnum.ASHE, 4 },
            { (long)ChampionsEnum.JARVANIV, 4 },
            { (long)ChampionsEnum.JINX, 4 },
            { (long)ChampionsEnum.KARMA, 4 },
            { (long)ChampionsEnum.KSANTE, 4 },
            { (long)ChampionsEnum.LEONA, 4 },
            { (long)ChampionsEnum.POPPY, 4 },
            { (long)ChampionsEnum.RYZE, 4 },
            { (long)ChampionsEnum.SAMIRA, 4 },
            { (long)ChampionsEnum.SETT, 4 },
            { (long)ChampionsEnum.VOLIBEAR, 4 },
            { (long)ChampionsEnum.YUUMI, 4 },

            // Cost 5 Champions
            { (long)ChampionsEnum.BRAUM, 5 },
            { (long)ChampionsEnum.EKKO, 5 },
            { (long)ChampionsEnum.GWEN, 5 },
            { (long)ChampionsEnum.LEESIN, 5 },
            { (long)ChampionsEnum.SERAPHINE, 5 },
            { (long)ChampionsEnum.TWISTEDFATE, 5 },
            { (long)ChampionsEnum.VARUS, 5 },
        };

        public static Dictionary<int, List<int>> TraitsSteps = new Dictionary<int, List<int>>
        {
            {
                (int)TraitsEnum.BATTLEACADEMIA,
                new List<int> { 3, 5, 7 }
            },
            {
                (int)TraitsEnum.CRYSTALGAMBIT,
                new List<int> { 2, 4, 6 }
            },
            {
                (int)TraitsEnum.LUCHADOR,
                new List<int> { 2, 4 }
            },
            {
                (int)TraitsEnum.MIGHTYMECH,
                new List<int> { 3, 5, 7 }
            },
            {
                (int)TraitsEnum.MONSTERTRAINER,
                new List<int> { 1 }
            },
            {
                (int)TraitsEnum.SOULFIGHTER,
                new List<int> { 2, 4, 6, 8 }
            },
            {
                (int)TraitsEnum.STARGUARDIAN,
                new List<int> { 2, 3, 4, 5, 6, 7, 8, 9, 10 }
            },
            {
                (int)TraitsEnum.SUPREMECELLS,
                new List<int> { 2, 3, 4 }
            },
            {
                (int)TraitsEnum.THECREW,
                new List<int> { 2, 3, 4, 5 }
            },
            {
                (int)TraitsEnum.WRAITH,
                new List<int> { 2, 4, 6 }
            },
            {
                (int)TraitsEnum.MENTOR,
                new List<int> { 1, 4 }
            },
            {
                (int)TraitsEnum.PRODIGY,
                new List<int> { 2, 3, 4, 5 }
            },
            {
                (int)TraitsEnum.THECHAMP,
                new List<int> { 1 }
            },
            {
                (int)TraitsEnum.STANCEMASTER,
                new List<int> { 1 }
            },
            {
                (int)TraitsEnum.ROGUECAPTAIN,
                new List<int> { 1 }
            },
            {
                (int)TraitsEnum.BASTION,
                new List<int> { 2, 4, 6 }
            },
            {
                (int)TraitsEnum.DUELIST,
                new List<int> { 2, 4, 6 }
            },
            {
                (int)TraitsEnum.EDGELORD,
                new List<int> { 2, 4, 6 }
            },
            {
                (int)TraitsEnum.EXECUTIONER,
                new List<int> { 2, 3, 4, 5 }
            },
            {
                (int)TraitsEnum.HEAVYWEIGHT,
                new List<int> { 2, 4, 6 }
            },
            {
                (int)TraitsEnum.JUGGERNAUT,
                new List<int> { 2, 4, 6 }
            },
            {
                (int)TraitsEnum.PROTECTOR,
                new List<int> { 2, 4, 6 }
            },
            {
                (int)TraitsEnum.SNIPER,
                new List<int> { 2, 3, 4, 5 }
            },
            {
                (int)TraitsEnum.SORCERER,
                new List<int> { 2, 4, 6 }
            },
            {
                (int)TraitsEnum.STRATEGIST,
                new List<int> { 2, 3, 4, 5 }
            },
        };

        public static int GetMinimalActivation(int trait)
        {
            return TraitsSteps[trait][0];
        }

        public bool TraitEnabled(int trait, int traitChampCount)
        {
            return traitChampCount >= GetMinimalActivation(trait);
        }

        /// <summary>
        /// first int is the trait, second int is the number of champions with this trait
        /// </summary>
        /// <param name="compo"></param>
        /// <returns></returns>
        public static Dictionary<int, int> TraitCountInCompo(long compo)
        {
            Dictionary<int, int> synergies = new Dictionary<int, int>();
            for (int i = 0; i < TotalChampionCout; i++)
            {
                if ((compo & (1L << i)) != 0)
                {
                    var champ = (long)(1L << i);
                    var traits = ChampsTraits[champ];
                    // combine the traits within synergies using bitwise operation
                    for (int trait = 0; trait < TotalTraitCount; trait++)
                    {
                        if ((traits & (1 << trait)) != 0)
                        {
                            if (synergies.ContainsKey(1 << trait))
                            {
                                synergies[1 << trait]++;
                            }
                            else
                            {
                                synergies.Add(1 << trait, 1);
                            }
                        }
                    }
                }
            }

            return synergies;
        }

        /// <summary>
        /// first int is trait, second int is the number of champions with this trait
        /// output is int of the flag of active traits
        /// </summary>
        /// <param name="synergies"></param>
        /// <returns></returns>
        public static int FilterActiveTraits(Dictionary<int, int> synergies)
        {
            int output = 0;
            foreach (var kvp in synergies)
            {
                if (kvp.Value >= GetMinimalActivation(kvp.Key))
                {
                    output |= kvp.Key;
                }
            }
            return output;
        }

        /// <summary>
        /// trait is the trait, count is the number of champions with this trait
        /// </summary>
        /// <param name="synergies"></param>
        /// <param name="additionalEmblems"></param>
        /// <returns></returns>
        public static Dictionary<int, int> MergeEmblems(
            Dictionary<int, int> synergies,
            Dictionary<int, int> additionalEmblems
        )
        {
            Dictionary<int, int> mergedEmblems = new Dictionary<int, int>();

            mergedEmblems = synergies
                .Concat(additionalEmblems)
                .GroupBy(x => x.Key)
                .ToDictionary(x => x.Key, x => x.Sum(y => y.Value));
            return mergedEmblems;
        }

        public void DisplayTraits(Dictionary<TraitsEnum, int> traits)
        {
            foreach (var kvp in traits)
            {
                Debug.Log($"{kvp.Key} : {kvp.Value}");
            }
        }

        public string DisplayComposition(HashSet<ChampionsEnum> compo)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var champ in compo)
            {
                sb.Append(champ.ToString() + " / ");
            }
            return sb.ToString();
        }

        public static int MaxIntForCombinationOfn(int n)
        {
            return (1 << n) - 1;
        }

        internal static string CompositionToString(HashSet<ChampionsEnum> composition)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var champ in composition)
            {
                sb.Append(champ.ToString() + " / ");
            }
            sb.Append(" --------- ");
            // HashSet<TraitsEnum> activeSynergies = FilterActiveTraits(ChampionUtils.ToLong(composition)));
            // foreach (var trait in activeSynergies)
            // {
            //     sb.Append(trait.ToString() + " / ");
            // }
            return sb.ToString();
        }

        /// <summary>
        /// I have a list of champion that are fixed, in a long called mandatoryChamps.
        /// I have a list of champions that are possible, in a long called possibleChamps.
        /// I want to generate all possible combinations of champions that contain all mandatory champions.
        /// I can use MaxIntForCombinationOfn to get the maximum number of possible combinations and iterate over all possible combination,
        /// each bit of the combination will represent the nth champion in the list of possible champions, which is not a list but a long.
        /// The composition will be composed of all the mandatory champs and some of the possible champs, to add up to the composition size exactly.
        /// </summary>
        /// <param name="composition"></param>
        /// <param name="activeSynergies"></param>
        /// <returns></returns>
        ///
        public static List<long> GenerateCombinations(
            long mandatoryChamps,
            long possibleChamps,
            int compositionSize
        )
        {
            possibleChamps = possibleChamps & ~mandatoryChamps;

            Assert.IsTrue((mandatoryChamps & possibleChamps) == 0);

            List<long> compositions = new List<long>();
            int champToSelectCount =
                compositionSize - ChampionUtils.NumberOfChampions(mandatoryChamps);
            int possibleChampCount = ChampionUtils.NumberOfChampions(possibleChamps);
            Assert.IsTrue(champToSelectCount >= 0); // else we have too many mandatory champs
            HashSet<long> combinations = BitWise.GetAllPermutation(
                champToSelectCount,
                possibleChampCount
            );
            foreach (var combinationOfPossibleChamps in combinations)
            {
                var composition = SelectSublistOfChampion(
                    possibleChamps,
                    combinationOfPossibleChamps
                );
                composition |= mandatoryChamps;
                compositions.Add(composition);
            }
            return compositions;
        }

        public static IEnumerator DisplayCompositions(List<long> compositions)
        {
            Debug.Log("Number of compositions : " + compositions.Count);
            yield return null;
            foreach (var compo in compositions)
            {
                Debug.Log(CompositionToString(ChampionUtils.FromLong(compo)));
                yield return null;
            }
        }

        public static long SelectSublistOfChampion(
            long accessibleChampions,
            long subselectedChampions
        )
        {
            var champs = ChampionUtils.FromLong(accessibleChampions).ToList<ChampionsEnum>();
            // this list of champ is ordered. I want to filter this with the subselectedChampions bit flag
            // where all bit to 1 are the champions I want to keep, and all bit to 0 are the champions I want to remove
            HashSet<ChampionsEnum> selectedChamps = new HashSet<ChampionsEnum>();

            for (int i = 0; i < champs.Count; i++)
            {
                if ((subselectedChampions & (1L << i)) != 0)
                {
                    selectedChamps.Add(champs[i]);
                }
            }
            return ChampionUtils.ToLong(selectedChamps);
        }
    }
}
