using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

/// <summary>
/// Creates new agents to be recruited later.
/// </summary>
public class AgentGenerator : BaseBehaviour
{

	[SerializeField]
	PersonalityInfo[] personalityInfoList;

	[SerializeField]
	BackstoryEvent[] backstoryChildhood;
	[SerializeField]
	BackstoryEvent[] backstoryPreviousWork;
	[SerializeField]
	BackstoryEvent[] backstoryBehaviour;

	[SerializeField]
	private Sprite[] malePortraitList;
	[SerializeField]
	private Sprite[] femalePortraitList;
	[SerializeField]
	private float doubleAgentChance = 0.2f;
	[SerializeField]
	private int minPersonalityTraits = 1;
	[SerializeField]
	private int maxPersonalityTraits = 3;
	[SerializeField]
	private TextAsset maleFirstNamesText;
	[SerializeField]
	private TextAsset femaleFirstNamesText;
	[SerializeField]
	private TextAsset lastNamesText;

	private string[] maleFirstNames;
	private string[] femaleFirstNames;
	private string[] lastNames;
	
	public Sprite[] MalePortraitList { get { return malePortraitList; } }
	public Sprite[] FemalePortraitList { get { return femalePortraitList; } }

	private void Awake()
	{
		maleFirstNames = TextAssetUtils.Read(maleFirstNamesText);
		femaleFirstNames = TextAssetUtils.Read(femaleFirstNamesText);
		lastNames = TextAssetUtils.Read(lastNamesText);
	}

	public Agent CreateAgent()
	{
		Gender gender = Random.Range(0.0f, 1.0f) < 0.5f ? Gender.Male : Gender.Female;

		string firstName = "";

		if(gender == Gender.Male)
			firstName = maleFirstNames[Random.Range(0, maleFirstNames.Length)];
		else if(gender == Gender.Female)
			firstName = femaleFirstNames[Random.Range(0, femaleFirstNames.Length)];

		string lastName = lastNames[Random.Range(0, femaleFirstNames.Length)];

		string agentName = string.Format("{0} {1}", firstName, lastName);

		bool isDoubleAgent = Random.Range(0.0f, 1.0f) < doubleAgentChance;

		int portraitIndex = 0;

		if (gender == Gender.Male)
			portraitIndex = Random.Range(0, malePortraitList.Length);
		else if (gender == Gender.Female)
			portraitIndex = Random.Range(0, femalePortraitList.Length);

		List<PersonalityTrait> allTraits = ((PersonalityTrait[])System.Enum.GetValues(typeof(PersonalityTrait))).ToList();
        var traits = new PersonalityTrait[Random.Range(1, maxPersonalityTraits+1)];
		for (int i = 0; i < traits.Length; i++)
		{
			int randomIndex = Random.Range(0, allTraits.Count);
			traits[i] = allTraits[randomIndex];
			allTraits.RemoveAt(randomIndex);
		}

		var backstoryEvents = ChooseBackstoryEvents(traits, isDoubleAgent);

		return new Agent
		{
			Name = agentName,
			Gender = gender,
			IsDoubleAgent = isDoubleAgent,
			PortraitIndex = portraitIndex,
			Traits = traits,
			BackstoryList = backstoryEvents.ToList(),
		};
	}

	private BackstoryEvent[] ChooseBackstoryEvents(PersonalityTrait[] traits, bool isDoubleAgent)
	{
		List<BackstoryEvent> backstoryList = new List<BackstoryEvent>();

		var childhood = ChooseBackstoryEvents(backstoryChildhood, traits, isDoubleAgent);
		if (childhood.Title != null)
			backstoryList.Add(childhood);

		var previousWork = ChooseBackstoryEvents(backstoryPreviousWork, traits, isDoubleAgent);
		if (previousWork.Title != null)
			backstoryList.Add(previousWork);

		var behaviour = ChooseBackstoryEvents(backstoryBehaviour, traits, isDoubleAgent);
		if (behaviour.Title != null)
			backstoryList.Add(behaviour);

		return backstoryList.ToArray();
	}

	private BackstoryEvent ChooseBackstoryEvents(BackstoryEvent[] backstoryPool, PersonalityTrait[] traits, bool isDoubleAgent)
	{
		// add all available backstories to a list (duplicates can be added to the list, increasing their chance to be chosen)
		var availableBackstories = new List<BackstoryEvent>();

		for(int i = 0; i < backstoryPool.Length; i++)
		{
			var backstory = backstoryPool[i];

			// keep adding the backstory to the list everytime a matching trait is found.
			foreach(var backstoryTrait in backstory.Traits)
			{
				if (backstoryTrait == PersonalityTrait.None || traits.Contains(backstoryTrait))
					availableBackstories.Add(backstory);
			}

			if(backstory.couldBeDoubleAgent && isDoubleAgent)
				availableBackstories.Add(backstory);
		}

		if (availableBackstories.Count == 0)
			return new BackstoryEvent();

		return availableBackstories[Random.Range(0, availableBackstories.Count)];
	}

}
