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

public class CharacterSpawner : MonoBehaviour
{
    [SerializeField] private GameObject botPrefab;
    [SerializeField] private List<NavPoint> defendersSpawnPoints;
    [SerializeField] private List<NavPoint> attackersSpawnPoints;
    private static Dictionary<(TypeAI, Team), Func<NPC, BaseBehaviour>> behaviourDictionary;
    private static System.Random random;

    public void Start()
    {
        behaviourDictionary = new Dictionary<(TypeAI, Team), Func<NPC, BaseBehaviour>>()
        {
            { (TypeAI.DumbAlgorithm, Team.Attackers),  new Func<NPC,BaseBehaviour>( npc => new DumbAttacker(npc))},
            { (TypeAI.DumbAlgorithm, Team.Defenders), new Func<NPC,BaseBehaviour>( npc => new DumbDefender(npc)) },
            { (TypeAI.HumanAI, Team.Defenders), new Func<NPC,BaseBehaviour>( npc => new Human(npc))},
            { (TypeAI.HumanAI, Team.Attackers), new Func<NPC,BaseBehaviour>( npc => new Human(npc))},
            //And Other behaviours
        };

        if (SettingsReader.Instance.GetSettings.hasHumanAttacker && SettingsReader.Instance.GetSettings.hasHumanDefender)
            throw new System.Exception("Not allowed to have two players");
        else if (SettingsReader.Instance.GetSettings.hasHumanAttacker == true)
        {
            spawnCharacter(behaviourDictionary[(TypeAI.HumanAI, Team.Attackers)], Team.Attackers);
        }
        else if (SettingsReader.Instance.GetSettings.hasHumanDefender == true)
        {
            spawnCharacter(behaviourDictionary[(TypeAI.HumanAI, Team.Defenders)], Team.Defenders);
        }

        for (int i = 0; i < SettingsReader.Instance.GetSettings.numOfAttackers - (SettingsReader.Instance.GetSettings.hasHumanAttacker ? 1 : 0); i++)
        {
            spawnCharacter(behaviourDictionary[(SettingsReader.Instance.GetSettings.atcTeamAI, Team.Attackers)], Team.Attackers);
        }
        for (int i = 0; i < SettingsReader.Instance.GetSettings.numOfAttackers - (SettingsReader.Instance.GetSettings.hasHumanDefender ? 1 : 0); i++)
        {
            spawnCharacter(behaviourDictionary[(SettingsReader.Instance.GetSettings.defTeamAI, Team.Defenders)], Team.Defenders);
        }
    }

    private void spawnCharacter(Func<NPC, BaseBehaviour> behaviourFunc, Team team)
    {
        var spawnPoint = team == Team.Defenders ?
            defendersSpawnPoints[random.Next(0, defendersSpawnPoints.Count)].position :
            attackersSpawnPoints[random.Next(0, attackersSpawnPoints.Count)].position;
        var entity = Instantiate(botPrefab, spawnPoint, Quaternion.identity);
        var npc = entity.GetComponent<NPC>();
        npc.SetBehaviour(behaviourFunc(npc));
    }
}

