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

public class GameStart : MonoBehaviour
{
    [SerializeField] private CatController catPrefab;
    [SerializeField] private BombController bombPrefab;
    [SerializeField] private AnimatorOverrideController[] skins;
    [SerializeField] private Transform[] spawns;
    [SerializeField] private Canvas gameOverCanvas;
    [SerializeField] private Canvas startCanvas;
    [SerializeField] private ButtonMashUI buttonMashUI;

    private List<CatController> playerList;
    private List<CatController> alivePlayers;

    public int AlivePlayerCount { get { return alivePlayers.Count;}}

    public static GameStart Instance { get; private set; }


    public PortraitPanel portraitPanel;


	public bool startGame = false;
    private bool slowMotionRunning = false;
    private bool gameEnded = false;

    [SerializeField, Range(0f, 1f)] private float buttonMashChance;

    private void Awake ()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(this.gameObject);
        }
    }

	private void OnEnable()
    {
        GameManager.Instance.OnStartPress += OnJoin;
    }
    private void OnDisable()
    {
        GameManager.Instance.OnStartPress -= OnJoin;
    }

    private void Start()
    {
        StartCoroutine(SoundManager.Instance.PlayIntro());
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.P))
        {
            SoundManager.Instance.StopArena();
            SoundManager.Instance.StopIntro();            
            startGame = true;
            SceneManager.LoadScene(SceneManager.GetActiveScene().name);
        }

        if(Input.GetKeyDown(KeyCode.R) && !slowMotionRunning && !mashMode)
        {
            for (int i = 0; i < playerList.Count; i++)
            {
                Destroy(playerList[i].gameObject);
            }

            playerList = new List<CatController>();
            alivePlayers = new List<CatController>();

            gameOverCanvas.gameObject.SetActive(false);
            gameEnded = false;

            if (OnRestart != null)
            {
                OnRestart(GameManager.Instance.ControllerCount);
            }

            //Debug.Log(GameManager.Instance.ControllerCount);

            for(int i = 0; i < GameManager.Instance.ControllerCount; i++)
            {
                SpawnCharacter(GameManager.Instance.ControllerIDs[i]);
            }

            GameManager.Instance.BombController.Transfer(GetRandomPlayer().transform);
            GameManager.Instance.BombController.Reset();
        }
    }

    public void Restart()
    {
        if (!slowMotionRunning)
        {
            for (int i = 0; i < playerList.Count; i++)
            {
                Destroy(playerList[i].gameObject);
            }

            playerList = new List<CatController>();
            alivePlayers = new List<CatController>();

            gameOverCanvas.gameObject.SetActive(false);
            gameEnded = false;

            if (OnRestart != null)
            {
                OnRestart(GameManager.Instance.ControllerCount);
            }

            //Debug.Log(GameManager.Instance.ControllerCount);

            for(int i = 0; i < GameManager.Instance.ControllerCount; i++)
            {
                SpawnCharacter(GameManager.Instance.ControllerIDs[i]);
            }

            GameManager.Instance.BombController.Transfer(GetRandomPlayer().transform);
            GameManager.Instance.BombController.Reset();
            
        }
    }

    public bool CheckGameOver()
    {
        if(gameEnded) return false;

        if (alivePlayers.Count <= 2)
        {
            SoundManager.Instance.Play(SoundManager.SoundType.Lose);
            slowMotionRunning = true;
            Time.timeScale = 0.3f;
            StartCoroutine(GameOver());
            return true;
        }
        else
        {
            return false;
        }
    }

    public bool mashMode;

    public bool TriggerButtonMash(int id1, int id2)
    {
        Debug.Log(id1);
        Debug.Log(id2);

        float prob = UnityEngine.Random.Range(0f, 1f);
        if (prob <= buttonMashChance)
        {
            buttonMashUI.InitButtonMash(id1, id2);
            //GameStart.Instance.GetPlayerFromID(id1).Input.mashID = id1;
            GameStart.Instance.GetPlayerFromID(id1).Input.mashMode = true;
            mashMode = true;
            //GameStart.Instance.GetPlayerFromID(id2).Input.mashID = id2;
            GameStart.Instance.GetPlayerFromID(id2).Input.mashMode = true;
            return true;
            //Debug.Log("Button Mash!");
        }
        else
        {
            return false;
        }
    }

    public void EndButtonMash(int winnerID, int id1, int id2)
    {
        GameStart.Instance.GetPlayerFromID(id1).Input.mashMode = false;
        GameStart.Instance.GetPlayerFromID(id2).Input.mashMode = false;
        mashMode = false;

        Debug.Log("winnerID");

        Vector2 dir = playerList[id1].transform.position - playerList[id2].transform.position;
        playerList[id1].GetComponent<Rigidbody2D>().simulated = true;
        playerList[id2].GetComponent<Rigidbody2D>().simulated = true;
        playerList[id1].GetComponent<Rigidbody2D>().velocity = Vector2.zero;
        playerList[id2].GetComponent<Rigidbody2D>().velocity = Vector2.zero;
        if (winnerID == id2)
        {
            playerList[id1].GetComponent<Rigidbody2D>().AddForce(dir * 30, ForceMode2D.Impulse);
            playerList[id2].Input.SetPermissions(true);
        }
        else
        {
            dir *= -1;
            playerList[id2].GetComponent<Rigidbody2D>().AddForce(dir * 30, ForceMode2D.Impulse);
            playerList[id1].Input.SetPermissions(true);
        }
    }

    private IEnumerator GameOver()
    {
        yield return new WaitForSeconds(1f);
        slowMotionRunning = false;
        gameEnded = true;
        Time.timeScale = 1;
        //Show text
        gameOverCanvas.gameObject.SetActive(true);
        SoundManager.Instance.Play(SoundManager.SoundType.Win);

    }

	private void OnJoin(int id)
	{
        startCanvas.gameObject.SetActive(false);

		if(startGame) return;

        SoundManager.Instance.StopIntro();
        SoundManager.Instance.PlayArena();

        //GameStart.Instance.GameStart = this;
        startGame = true;

        playerList = new List<CatController>();
        alivePlayers = new List<CatController>();

		//Debug.Log(GameManager.Instance.ControllerCount);

        // if (OnRestart != null)
        // {
        //     OnRestart(GameManager.Instance.ControllerCount);
        // }
        portraitPanel.Init();

        for(int i = 0; i < GameManager.Instance.ControllerCount; i++)
        {
            SpawnCharacter(GameManager.Instance.ControllerIDs[i]);
        }

        gameOverCanvas.gameObject.SetActive(false);

        BombController bc = Instantiate(bombPrefab);
        if (GameManager.Instance.ControllerCount == 4)
        {
            bc.timer = 10;
        }
        if (GameManager.Instance.ControllerCount == 3)
        {
            bc.timer = 15;
        }
        if (GameManager.Instance.ControllerCount == 2)
        {
            bc.timer = 15;
        }
        if (GameManager.Instance.ControllerCount == 1)
        {
            bc.timer = 30;
        }
        GameManager.Instance.RegisterBomb(bc);
        GameManager.Instance.BombController.Transfer(GetRandomPlayer().transform);
        GameManager.Instance.BombController.Reset();
	}

	private void SpawnCharacter(int id)
    {
		CatController cc = Instantiate(catPrefab, spawns[id].position, Quaternion.identity);
        cc.ID = id;
        cc.Appearance.SetSkin(skins[id]);
        cc.Init(id, GameManager.Instance.GetControllerDevice(id));
        cc.Input.SetPermissions(true);
        playerList.Add(cc);
        alivePlayers.Add(cc);
    }

    public CatController GetPlayerFromID(int id)
    {
        return playerList[id];
    }

    public CatController GetRandomPlayer()
    {
        return playerList[UnityEngine.Random.Range(0, playerList.Count)];
    }
    public CatController GetAliveRandomPlayer()
    {
        return alivePlayers[UnityEngine.Random.Range(0, alivePlayers.Count)];
    }

    public Action<int> OnPlayerKill;
    public Action<int> OnRestart;

    public void KillPlayer(Transform t)
    {
        CatController cc = t.GetComponent<CatController>();

        alivePlayers.Remove(cc);
        if (OnPlayerKill != null)
        {
            OnPlayerKill(cc.ID);
        }
    }
}