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

public class HumanControl : MonoBehaviour 
{
    public ControlIndicator ControlIndicator;
    public string DEBUG;

    private static List<Transform> Humans = new List<Transform>();
    public static Transform ActiveHuman;
    public static ControlIndicator Indicator;

    public static void AddHuman(Transform h)
    {
        Debug.Log("HC Adding Human: " + h);

        Humans.Add(h);
        if (ActiveHuman == null)
        {
            ActiveHuman = h;
            if (Indicator != null)
                Indicator.SetTarget(ActiveHuman);
        }
    }

    public static void RemoveHuman(Transform h)
    {
        Debug.Log("HC Removing Human: " + h);
        Humans.Remove(h);
        if (ActiveHuman == null || ActiveHuman == h)
            CycleActiveHuman(false);
    }

    public static void EndLevelWith(List<Transform> savedHumans)
    {
        Debug.Log("HumanControl ending level with " + savedHumans.Count + " saved humans out of " + Humans.Count + " total.");
        foreach (Transform human in Humans.ToArray())
        {
            if (!savedHumans.Contains(human))
            {
                RemoveHuman(human);
                Score.HumansAbandoned++;
                if (human != null)
                    Destroy(human.gameObject);
                else
                    Debug.LogWarning("HumanControl tried to remove a null from list");
            }
        }
    }

    public static IEnumerable<Transform> HumansWithLoS(Vector2 position)
    {
        return Humans.Where(h => AIUtil.HasLoS(position, h.position));
    }

    private static void CycleActiveHuman(bool reverse)
    {
        if (Humans.Count == 0)
            return;

        if (ActiveHuman == null)
        {
            ActiveHuman = Humans[0];
        }
        else
        {
            int idx = Humans.IndexOf(ActiveHuman);
            int newIdx = (reverse ? (Humans.Count + idx - 1) : (idx + 1)) % Humans.Count;
            ActiveHuman = Humans[newIdx];
        }

        if (Indicator != null)
            Indicator.SetTarget(ActiveHuman);
    }

    private bool invokedGameOver = false;
    void Update () 
	{
        DEBUG = Humans.Count + " " + ((ActiveHuman == null) ? "null" : ActiveHuman.name);

        if (Exit.ExitClosed)
            return;

        if (Input.GetKeyDown(KeyCode.Escape))
            Application.Quit();

        if (Input.GetKeyDown(KeyCode.Tab) || Input.GetKeyDown(KeyCode.Return))
        {
            CycleActiveHuman(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift));            
            ScrambleKit.FX.SoundFX.PlaySound("ControlSwitch");
        }

        if(!invokedGameOver && Humans.Count == 0)
        {
            Invoke("LoadGameOver", 1.5f);
        }
    }

    void LoadGameOver()
    {
        SceneManager.LoadScene("GameOverScene");
    }

    void Awake()
    {
        Indicator = ControlIndicator;
    }
}
