using NUnit.Framework;
using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;

    private int level = 0;

    [Header("Game Settings")]
    [SerializeField] private int killer_Count;
    [SerializeField] private float killer_Timer;
    [SerializeField] private int max_Npc_Kill;
    private int npc_Killed;

    [SerializeField] private List<GameObject> npc_List = new();
    [SerializeField] private List<GameObject> killer_List = new();

    [SerializeField]
    MaskProperties[] masks;

    [SerializeField]
    int characterCount;

    [HideInInspector] public List<CharacterInfo> Characters = new();

    private void Awake()
    {
        if (Instance != null)
        {
            Destroy(gameObject);
            return;
        }

        Instance = this;
        DontDestroyOnLoad(gameObject);
    }

    private void OnEnable()
    {
        SceneManager.sceneLoaded += OnSceneLoaded;
    }

    private void OnDisable()
    {
        SceneManager.sceneLoaded -= OnSceneLoaded;
    }

    private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        re_Start();
    }

    private void re_Start()
    {
        switch (level)
        {
            case 0:
                killer_Count = 1;
                break;
            case 1:
                killer_Count = 1;
                break;
            case 2:
                killer_Count = 2;
                break;
            default:
                killer_Count = 3;
                max_Npc_Kill = 5;
                break;
        }


        var availableCharacters = FindObjectsByType<CharacterInfo>(FindObjectsSortMode.None).ToList();
        var availableMasks = masks.ToList();
        killer_List.Clear();
        npc_List.Clear();
        npc_List = availableCharacters.Select(g => g.gameObject).ToList();
        KillerList(npc_List, killer_List, killer_Count);

        foreach (var character in availableCharacters)
        {
            character.gameObject.SetActive(false);
        }

        for (int i = 0; i < characterCount; i++)
        {
            if (availableCharacters.Count == 0)
                break;

            var randomCharacter = availableCharacters[Random.Range(0, availableCharacters.Count)];
            var randomMask = availableMasks[Random.Range(0, availableMasks.Count)];

            availableMasks.Remove(randomMask);
            availableCharacters.Remove(randomCharacter);
            Characters.Add(randomCharacter);
            randomCharacter.gameObject.SetActive(true);
            randomCharacter.AttachMask(randomMask);
        }
        if (CluesGenerator.Instance != null)
            CluesGenerator.Instance.StartScenario(level);
    }

    private void KillerList(List<GameObject> from, List<GameObject> to, int count)
    {
        if (from == null || to == null) return;
        if (from.Count == 0 || count <= 0) return;

        count = Mathf.Min(count, from.Count);

        for (int i = 0; i < count; i++)
        {
            int randomIndex = Random.Range(0, from.Count);
            GameObject go = from[randomIndex];

            from.RemoveAt(randomIndex);
            to.Add(go);
        }

        SetupKiller();
    }

    private void SetupKiller()
    {
        foreach (GameObject go in killer_List)
        {
            if (go == null) continue;

            // Enable NavMeshAgent first (so controller can set destination immediately)
            var na = go.GetComponent<NavMeshAgent>();
            if (na != null)
                na.enabled = true;

            var kc = go.GetComponent<KillerController>();
            if (kc == null) continue;

            kc.enabled = true;

            kc.startDelay = killer_Timer;

            // Assign random target
            if (npc_List.Count > 0)
            {
                GameObject randomNpc = npc_List[Random.Range(0, npc_List.Count)];
                kc.SetTarget(randomNpc.transform);
            }
        }
    }

    public int KillerCount => killer_List.Count;

    public CharacterInfo GetKiller(int index)
    {
        if (index < 0 || index >= killer_List.Count)
            return null;
        GameObject killerGO = killer_List[index];
        if (killerGO == null)
            return null;
        return killerGO.GetComponent<CharacterInfo>();
    }

    public void RemoveFromList(GameObject go)
    {
        if (npc_List.Remove(go))
        {
            //Innocent killed 
            npc_Killed++;
            if (npc_Killed >= max_Npc_Kill)
            {
                UIManager.Instance.Loose_InnocentKill();
            }
        }
        else
        {
            CharacterInfo ci = go.GetComponent<CharacterInfo>();
            ci.isDead = true;
            if (killer_List.Select(g => g.GetComponent<CharacterInfo>()).Count(k => !k.isDead) == 0)
            {
                UIManager.Instance.Win();
            }
        }
    }

    public void ReloadScene()
    {
        level = 0;
        SceneManager.LoadScene("Tuto");
    }

    public void NextScene()
    {
        level++;
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }

}
