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

public class GameController : MonoBehaviour
{
    [Header("References")]
    public SpriteRenderer GoalOn;
    public SpriteRenderer GoalRay;
    public SpriteRenderer GoalOff;
    public SpriteRenderer GoalOffGlow;
    public RayShooter rayShooter;
    public Text levelText;
    public GameObject levelSelectMenu;
    public GameObject levelSelectButton;
    public GameObject introMenu;
    public SpriteRenderer[] gemRends = new SpriteRenderer[3];
    public Sprite gemOn;
    public Sprite gemOff;

    [HideInInspector]
    public Config.RayColor currentGoalColor;

    private static GameController _instance;
    public static GameController Instance
    {
        get
        {
            if (_instance == null)
                _instance = FindObjectOfType<GameController>();
            return _instance;
        }
    }

    void Start()
    {
        introMenu.SetActive(true);
    }

    public void OnPressPlay()
    {
        //Hide intro
        ShowLevelSelect();
        introMenu.SetActive(false);
    }

    public void ShowLevelSelect()
    {
        //If level select button disabled, ignore this coroutine
        if (levelSelectButton.activeInHierarchy || introMenu.activeInHierarchy)
        {
            //Disable level select button
            levelSelectButton.SetActive(false);
            SetGoalMode(false, Config.RayColor.Green);

            //Show level select
            levelSelectMenu.SetActive(true);

            if (currentLevel > 0)
            {
                SceneManager.UnloadSceneAsync(currentLevel);
                levelText.gameObject.SetActive(false);
            }
        }
    }

    int currentLevel = -1;
    public void OnLevelSelected(int levelNumber)
    {
        currentLevel = levelNumber;
        currentGoalColorIndex = 0;

        //Enable level select button
        levelSelectButton.SetActive(true);

        //Disable level select menu
        levelSelectMenu.SetActive(false);

        //Load level
        SceneManager.LoadScene(levelNumber, LoadSceneMode.Additive);        
    }


    public void SetGoalMode(bool isOn, Config.RayColor rayCol = Config.RayColor.Red)
    {
        if (isOn)
        {
            Color startColor = new Color(1, 1, 1, 0);
            Color endColor = Color.white;

            StartCoroutine(Utils.CrossFade(startColor, endColor, 0.3f, (dcol) =>
            {
                GoalOn.color = dcol;
                GoalRay.color = dcol;
            }));
        }
        else
        {
            GoalOn.color = new Color(1, 1, 1, 0);
            GoalRay.color = new Color(1, 1, 1, 0);
            Color col = Config.RayColors[(int)rayCol] * 0.6f;
            GoalOffGlow.color = col;

            currentGoalColor = rayCol;
        }
    }

    int currentGoalColorIndex = 0;
    public void Win()
    {
        UpdateGemColors();

        LevelSettings level = FindObjectOfType<LevelSettings>();
        if (currentGoalColorIndex < level.GoalColors.Length - 1)
        {
            currentGoalColorIndex++;

            SetGoalMode(false, level.GoalColors[currentGoalColorIndex]);
            return;
        }

        SetGoalMode(true);

        print("You won!");
        //Show some UI for 3 seconds
        levelText.gameObject.SetActive(true);
        levelText.StartCoroutine(ShowText("Perfect!", 3, () =>
        {
            //Unload current level
            SceneManager.UnloadSceneAsync(currentLevel);
            currentLevel = -1;

            //Show level select menu
            ShowLevelSelect();
        }));
    }

    public void UpdateGemColors()
    {
        LevelSettings level = FindObjectOfType<LevelSettings>();
        int remaining = level.GoalColors.Length - currentGoalColorIndex;
        print("Remining: " + remaining);
        for (int i = 0; i < gemRends.Length; i++)
        {
            gemRends[i].sprite = i < remaining ? gemOff : gemOn;
        }
        List<Config.RayColor> unusedColors = new List<Config.RayColor>()
        {
            Config.RayColor.Red, Config.RayColor.Green, Config.RayColor.Blue
        };
        foreach (var item in level.GoalColors)
        {
            if (unusedColors.Contains(item))
                unusedColors.Remove(item);
        }

        for (int i = 0; i < gemRends.Length; i++)
        {
            if (unusedColors.Count == 0)
                break;
            if (gemRends[i].sprite == gemOn)
            {
                Config.RayColor rcol = unusedColors[0];
                unusedColors.RemoveAt(0);
                gemRends[i].color = Config.RayColors[(int)rcol];
            }
        }

        if (currentGoalColorIndex < level.GoalColors.Length - 1)
        {
            currentGoalColorIndex++;

            SetGoalMode(false, level.GoalColors[currentGoalColorIndex]);
            return;
        }
    }

    public IEnumerator ShowText(string text, float duration, System.Action onEnd = null)
    {
        levelText.text = text;
        levelText.CrossFadeAlpha(1, 0.5f, false);
        yield return new WaitForSeconds(duration);
        levelText.CrossFadeAlpha(0, 0.7f, false);
        yield return new WaitForSeconds(0.7f);
        levelText.text = "";

        if (onEnd != null)
            onEnd();
    }
}
