using UnityEngine;
using System.Collections.Generic;
using System;
using mgaia.Utils;

public static class RequestLetterManager
{
    private class RequestLetterData
    {
        public RequestLetter Letter;
        public bool Available;

        public RequestLetterData(RequestLetter letter, bool available)
        {
            Letter = letter;
            Available = available;
        }
    }

    private static Dictionary<Attributes, Dictionary<AttributeInfluenceLevel, List<RequestLetterData>>> mRequestLetters = new Dictionary<Attributes, Dictionary<AttributeInfluenceLevel, List<RequestLetterData>>>();
    
    static RequestLetterManager()
    {
        List<RequestLetter> tempRequestLetters = new List<RequestLetter>();
        SubclassGetter.GetSubclasses<RequestLetter>(true).ForEach(requestLetter =>
        {
            tempRequestLetters.Add(requestLetter.GetConstructor(new Type[] { }).Invoke(new object[] { }) as RequestLetter);
        });
        foreach(Attributes att in Enum.GetValues(typeof(Attributes)))
        {
            mRequestLetters[att] = new Dictionary<AttributeInfluenceLevel, List<RequestLetterData>>();
            foreach (AttributeInfluenceLevel attInfLevel in Enum.GetValues(typeof(AttributeInfluenceLevel)))
            {                
                mRequestLetters[att][attInfLevel] = new List<RequestLetterData>();
                tempRequestLetters.Where(letter => letter.RelatedAttribute == att && letter.InfluenceLevelRequired == attInfLevel)
                    .ForEach(letter => mRequestLetters[att][attInfLevel].Add(new RequestLetterData(letter, true)));
                Assert.AssertTrue(mRequestLetters[att][attInfLevel].Count != 0, "No letters found for the following combination: " + attInfLevel + " " + att);
            }
        }
        //mRequestLetters.ForEach(kvp => kvp.Value.ForEach(kvp2 => kvp2.Value.ForEach(letter => Debug.Log(kvp.Key + " " + kvp2.Key + " " + letter.Letter))));
    }

    public static RequestLetter GetAndCheckRequestLetter(Attributes attribute, AttributeInfluenceLevel influenceLevel)
    {
        RequestLetterData chosenLetterData = mRequestLetters[attribute][influenceLevel].First(letterData => letterData.Available);
        chosenLetterData.Available = false;
        RequestLetter chosenLetter = chosenLetterData.Letter;
        if (mRequestLetters[attribute][influenceLevel].TrueForAll(letterData => !letterData.Available))
        {
            ReElectRequestLetter(attribute, influenceLevel);
        }
        return chosenLetter;
    }

    private static void ReElectRequestLetter(Attributes attribute, AttributeInfluenceLevel influenceLevel)
    {
        mRequestLetters[attribute][influenceLevel].ForEach(letterData => letterData.Available = true);
    }
}