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

public class SceneController : MonoBehaviour
{
    public GameObject Dialog;
    public Transform playerPrefab;
    public List<string> sceneList;
    public List<Transform> loadedPlayer;
    public CameraFollower mainCamera;
	[SerializeField]
    private int loadedIndex = 0;
    private LevelData currentLevelData;
    public bool isSceneSwitching;

    [Header("Dialog Cutscene")]
    private int dialogIndex;

    [SerializeField]
    private List<string> dialogLines;
    [SerializeField]
    private Text textComponent;

	private static SceneController sceneController;


    void Awake()
    {
		sceneController = this;
        loadedPlayer = new List<Transform>();
        LoadNextLevel();
        InitializePlayer();
    }

    private void InitializePlayer()
    {
        Transform p1 = Instantiate(playerPrefab);
        Transform p2 = Instantiate(playerPrefab);

        p1.GetComponent<JoyStickInputController>().controller = Controller.One;
        p2.GetComponent<JoyStickInputController>().controller = Controller.Two;

        loadedPlayer.Add(p1);
        loadedPlayer.Add(p2);
    }

    public void StartLevelTransition()
    {

        for (int i = 0; i < loadedPlayer.Count; i++)
        {
            isSceneSwitching = true;
            mainCamera.moveDown = true;
        }
        LoadNextLevel();
    }

	public static void Nextlevel()
	{
		if(sceneController!=null)
			sceneController.StartLevelTransition();
	}


    void Update()
    {
        if ((Input.GetButton("A_BTN_Controller_First") || Input.GetKey(KeyCode.Space)) && !isSceneSwitching && loadedIndex != sceneList.Count)
            StartLevelTransition();
    }

    public void LoadNextLevel()
    {
        if (loadedIndex == sceneList.Count-1)
		{
			SceneManager.LoadScene("Level Outro", LoadSceneMode.Single);
		}
/* 
        for (int i = 0; i < loadedPlayer.Count; i++)
        {
            SceneManager.MoveGameObjectToScene(loadedPlayer[i].gameObject, SceneManager.GetSceneByBuildIndex(0));
        }
*/
        StartCoroutine(LoadLevel());

    }

    private void LoadLevelData()
    {
        GameObject[] rootObjects = SceneManager.GetActiveScene().GetRootGameObjects();

        for (int i = 0; i < rootObjects.Length; i++)
        {
            if (rootObjects[i].CompareTag("Config"))
            {
                currentLevelData = rootObjects[i].GetComponent<LevelData>();
            }
        }
    }



    IEnumerator LoadLevel()
    {
        if (mainCamera.lastRendererInView != null)
        {
            yield return new WaitUntil(() => !mainCamera.lastRendererInView.isVisible);
            Dialog.SetActive(true);
        }



        if (loadedIndex > 0)
        {
            yield return new WaitForSeconds(1f);
            yield return SceneManager.UnloadSceneAsync(sceneList[loadedIndex - 1]);
        }

        yield return SceneManager.LoadSceneAsync(sceneList[loadedIndex], LoadSceneMode.Additive);

        SceneManager.SetActiveScene(SceneManager.GetSceneByName(sceneList[loadedIndex]));

        loadedIndex++;
        LoadLevelData();
        SetupLevel();
    }
    
    private IEnumerator LerpObjectToTarget(Transform objectToMove, Vector3 start, Vector3 end, float time)
    {
        float timer = 0;
        while (timer < time)
        {
            objectToMove.position = Vector3.Lerp(start, end, timer / time);//Mathf.SmoothStep(start, end, timer / time);
            objectToMove.rotation = Quaternion.Lerp(objectToMove.rotation, Quaternion.identity, timer / time);//Mathf.SmoothStep(start, end, timer / time);

            timer += Time.deltaTime;
            yield return null;
        }
    }

    public IEnumerator LerpObjectToTarget(Transform transform, Vector3 position, Quaternion rotation, float time)
    {
        var currentPos = transform.position;
        var currentRotation = transform.rotation;
        var t = 0f;
        while (t < 1)
        {
            t += Time.deltaTime / time;
            transform.position = Vector3.Lerp(currentPos, position, t);
            transform.rotation = Quaternion.Lerp(currentRotation, rotation, t);
            yield return null;
        }
        
        transform.GetComponent<Roll>().Initialize();
    }

    private void SetupLevel()
    {
        if (loadedIndex > 1)
        {
	        foreach (Transform t in loadedPlayer)
	        {
		        JoyStickInputController p = t.GetComponent<JoyStickInputController>();
		        var spawn = currentLevelData.GetSpawn(p);
		        StartCoroutine(LerpObjectToTarget(t, spawn.position, spawn.rotation, 1.7f));
		        currentLevelData.AssignBoardManager(p);
		        Dialog.SetActive(false);
		        isSceneSwitching = false;
		        currentLevelData.AssignCameraTarget(mainCamera);
	        }
        }
        else
        {
	        foreach (Transform t in loadedPlayer)
	        {
		        JoyStickInputController p = t.GetComponent<JoyStickInputController>();
		        var spawn = currentLevelData.GetSpawn(p);
		        t.position = spawn.position;
		        t.rotation = spawn.rotation;
		        currentLevelData.AssignBoardManager(p);
		        currentLevelData.AssignCameraTarget(mainCamera);
	        }
        }
    }

    IEnumerator Wait(int seconds)
    {
        yield return new WaitForSeconds(seconds);
    }
}
