using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;

public class GameController : MonoBehaviour{

    public int level;

    [Header("SpawnRates")]
    public Vector2 minSpawnPos;
    public Vector2 maxSpawnPos;
    public float standardEnemySpawnRate = 2f;
    public float circleEnemySpawnRate = 3f;
    public float bigEnemySpawnRate = 4f;
    public float rocketEnemySpawnRate = 10f;
    public float gunSpawnRate = 15f;
    [HideInInspector]
    public float actualStandardEnemySpawnRate, actualCircleEnemySpawnRate, actualBigEnemySpawnRate, actualRocketEnemySpawnRate, actualGunSpawnRate;
    public float spawnRateDivider = .6f;

    [Header("Car")]
    public CinemachineVirtualCamera room1Cam;
    public CinemachineVirtualCamera room2Cam;
    public CinemachineVirtualCamera room3Cam;
    public CinemachineVirtualCamera room4Cam;
    public CameraController cameraController;
    public float speed;
    public GameObject car;
    public GameObject[] checkPoints;
    Transform target;
    public Transform player;
    public HealthBar health;
    [HideInInspector]
    public bool ready, playered;
    bool dead;

    [Header("Level")]
    public GameObject[] doors;

    // Start is called before the first frame update
    void Start(){
        PreFirst();
        GetComponent<BigEnemySpawner>().enabled = false;
        GetComponent<CircleEnemySpawner>().enabled = false;
        GetComponent<EnemySpawner>().enabled = false;
        GetComponent<GunSpawner>().enabled = false;
        GetComponent<RocketEnemySpawner>().enabled = false;
        AudioManager.instance.Stop("MenuTheme");
    }

    // Update is called once per frame
    void Update(){
        if(health.hp <= 0 && dead == false){
            car.SetActive(false);
            ObjectPooler.Instance.SpawnFromPool("CarExplosion", car.transform.position, Quaternion.identity);
            Camera.main.GetComponent<Animator>().SetBool("GameOver", true);
            FindObjectOfType<InGameUI>().GameOver(false);
            AudioManager.instance.Stop("MainTheme");
            Time.timeScale = 0f;
            dead = true;
        }
        if(level != 0 && level != 1){
            actualBigEnemySpawnRate = bigEnemySpawnRate / (spawnRateDivider * level);
            actualStandardEnemySpawnRate = standardEnemySpawnRate / (spawnRateDivider * level);
            actualRocketEnemySpawnRate = rocketEnemySpawnRate / (spawnRateDivider * level);
            actualCircleEnemySpawnRate = circleEnemySpawnRate / (spawnRateDivider * level);
            actualGunSpawnRate = gunSpawnRate * (spawnRateDivider / level);
        }else{
            actualBigEnemySpawnRate = bigEnemySpawnRate;
            actualStandardEnemySpawnRate = standardEnemySpawnRate;
            actualRocketEnemySpawnRate = rocketEnemySpawnRate;
            actualCircleEnemySpawnRate = circleEnemySpawnRate;
            actualGunSpawnRate = gunSpawnRate;
        }

        if (playered){
            if (second){
                minSpawnPos = new Vector2(17, -4);
                maxSpawnPos = new Vector2(33, 4);
                GetComponent<BigEnemySpawner>().enabled = true;
                GetComponent<CircleEnemySpawner>().enabled = true;
                GetComponent<EnemySpawner>().enabled = true;
                GetComponent<GunSpawner>().enabled = true;
                GetComponent<RocketEnemySpawner>().enabled = true;
                room2Cam.gameObject.SetActive(true);
                cameraController.follow = checkPoints[1].transform;
                health.time = 0f;
                Invoke(nameof(Third), 30f);
                foreach (GameObject d in doors){
                    d.SetActive(true);
                }
                second = false;
            }
            if (third){
                minSpawnPos = new Vector2(42, -4);
                maxSpawnPos = new Vector2(58, 4);
                GetComponent<BigEnemySpawner>().enabled = true;
                GetComponent<CircleEnemySpawner>().enabled = true;
                GetComponent<EnemySpawner>().enabled = true;
                GetComponent<GunSpawner>().enabled = true;
                GetComponent<RocketEnemySpawner>().enabled = true;
                room3Cam.gameObject.SetActive(true);
                cameraController.follow = checkPoints[2].transform;
                health.time = 0f;
                Invoke(nameof(Fourth), 30f);
                foreach (GameObject d in doors){
                    d.SetActive(true);
                }
                third = false;
            }
            if (fourth){
                minSpawnPos = new Vector2(67, -4);
                maxSpawnPos = new Vector2(83, 4);
                GetComponent<BigEnemySpawner>().enabled = true;
                GetComponent<CircleEnemySpawner>().enabled = true;
                GetComponent<EnemySpawner>().enabled = true;
                GetComponent<GunSpawner>().enabled = true;
                GetComponent<RocketEnemySpawner>().enabled = true;
                room4Cam.gameObject.SetActive(true);
                cameraController.follow = checkPoints[3].transform;
                health.time = 0f;
                foreach (GameObject d in doors){
                    d.SetActive(true);
                }
                Invoke(nameof(Fifth), 30f);
                fourth = false;
            }
            if (ableToWin){
                Finish();
                Camera.main.GetComponent<Animator>().SetBool("Win", true);
                Invoke(nameof(WinWin), 0.5f);
                ableToWin = false;
            }
        }
    }

    void FixedUpdate(){
        if (health.hp > 0){
            car.transform.position = Vector2.MoveTowards(car.transform.position, new Vector2(target.position.x + .675f, target.position.y), speed * Time.deltaTime);
        }
    }

    void PreFirst(){
        Invoke(nameof(First), 4f);
        target = checkPoints[0].transform;
        room1Cam.gameObject.SetActive(true);
        cameraController.follow = checkPoints[0].transform;
    }

    void First(){
        AudioManager.instance.Play("MainTheme");
        ready = true;
        GetComponent<BigEnemySpawner>().enabled = true;
        GetComponent<CircleEnemySpawner>().enabled = false;
        GetComponent<EnemySpawner>().enabled = true;
        GetComponent<GunSpawner>().enabled = true;
        GetComponent<RocketEnemySpawner>().enabled = false;
        Invoke(nameof(Second), 30f);
    }
    void Second(){
        Finish();
        level = 1;
        foreach(GameObject d in doors){
            d.SetActive(false);
        }
        room1Cam.gameObject.SetActive(false);
        room2Cam.gameObject.SetActive(false);
        room3Cam.gameObject.SetActive(false);
        room4Cam.gameObject.SetActive(false);
        cameraController.follow = player;
        target = checkPoints[1].transform;
        Invoke(nameof(SecondSecond), 25f);
    }
    bool second;
    void SecondSecond(){
        second = true;
    }
    void Third(){
        Finish();
        level = 2;
        foreach (GameObject d in doors){
            d.SetActive(false);
        }
        room1Cam.gameObject.SetActive(false);
        room2Cam.gameObject.SetActive(false);
        room3Cam.gameObject.SetActive(false);
        room4Cam.gameObject.SetActive(false);
        cameraController.follow = player;
        target = checkPoints[2].transform;
        Invoke(nameof(ThirdThird), 25f);
    }
    bool third;
    void ThirdThird(){
        third = true;
    }
    void Fourth(){
        Finish();
        level = 3;
        foreach (GameObject d in doors){
            d.SetActive(false);
        }
        room1Cam.gameObject.SetActive(false);
        room2Cam.gameObject.SetActive(false);
        room3Cam.gameObject.SetActive(false);
        room4Cam.gameObject.SetActive(false);
        cameraController.follow = player;
        target = checkPoints[3].transform;
        Invoke(nameof(FourthFourth), 25f);
    }
    bool fourth;
    void FourthFourth(){
        fourth = true;
    }

    void Fifth(){
        foreach (GameObject d in doors){
            d.SetActive(false);
        }
        room1Cam.gameObject.SetActive(false);
        room2Cam.gameObject.SetActive(false);
        room3Cam.gameObject.SetActive(false);
        room4Cam.gameObject.SetActive(false);
        cameraController.follow = player;
        target = checkPoints[4].transform;
        Invoke(nameof(Win), 18f);
    }
    bool ableToWin;
    void Win(){
        ableToWin = true;
    }

    void WinWin(){
        Time.timeScale = 0f;
        FindObjectOfType<InGameUI>().GameOver(true);
        AudioManager.instance.Stop("MainTheme");
    }

    void Finish(){
        GetComponent<BigEnemySpawner>().enabled = false;
        GetComponent<CircleEnemySpawner>().enabled = false;
        GetComponent<EnemySpawner>().enabled = false;
        GetComponent<GunSpawner>().enabled = false;
        GetComponent<RocketEnemySpawner>().enabled = false;
        foreach (GameObject g in GameObject.FindGameObjectsWithTag("Enemy")){
            ObjectPooler.Instance.SpawnFromPool("EnemyDeath", g.transform.position, Quaternion.identity);
            if(g.transform.parent == null){
                g.SetActive(false);
            }else if(g.transform.parent.CompareTag("Enemy")){
                g.transform.parent.gameObject.SetActive(false);
            }
        }
        foreach (GameObject g in GameObject.FindGameObjectsWithTag("BigEnemy")){
            ObjectPooler.Instance.SpawnFromPool("EnemyDeath", g.transform.position, Quaternion.identity);
            g.SetActive(false);
        }
        foreach (GameObject g in GameObject.FindGameObjectsWithTag("RocketEnemy")){
            ObjectPooler.Instance.SpawnFromPool("RocketEnemyDeath", g.transform.position, Quaternion.identity);
            if (g.transform.parent == null){
                g.SetActive(false);
            }else if (g.transform.parent.CompareTag("RocketEnemy")){
                g.transform.parent.gameObject.SetActive(false);
            }
        }
        foreach (GameObject g in GameObject.FindGameObjectsWithTag("CircleEnemy")){
            ObjectPooler.Instance.SpawnFromPool("CircleEnemyDeath", g.transform.position, Quaternion.identity);
            if (g.transform.parent == null){
                g.SetActive(false);
            }else if (g.transform.parent.CompareTag("CircleEnemy")){
                g.transform.parent.gameObject.SetActive(false);
            }
        }
    }
}
