using UnityEngine;
using UnityEngine.SceneManagement;
using Random = UnityEngine.Random;

public class Tetromino : MonoBehaviour
{
    public float timeBetweenSteps;
    public bool active = true;
    
    private TetrominoUserControl tetrominoUserControl;
    private TetrominoSpawnManager tetrominoSpawnManager;
    
    private float stepTimer = 0.0f;
    private bool wouldCollide = false;
    
    private Color[] tetrominoColors = new Color[7]
    {
        new Color(0.05f,0.04f,0.36f,1),
        new Color(0.54f,0.31f,0.04f,1),
        new Color(0.54f,0.20f,0.04f,1),
        new Color(0,0.30f,0.04f,1),
        new Color(0.02f,0.27f,0.34f,1),
        new Color(0.28f,0.02f,0.36f,1),
        new Color(0.53f,0,0.04f,1)
    };
    
    private Color[] overlayColors = new Color[7]
    {
        new Color(0.31f,0.5f,0.66f,1),
        new Color(0.82f,0.66f,0.19f,1),
        new Color(0.82f,0.42f,0.19f,1),
        new Color(0.55f,0.76f,0.18f,1),
        new Color(0.24f,0.49f,0.57f,1),
        new Color(0.44f,0.14f,0.54f,1),
        new Color(0.79f,0.20f,0.23f,1)
    };

    // Start is called before the first frame update
    void Start()
    {
        tetrominoSpawnManager = FindObjectOfType<TetrominoSpawnManager>();
        tetrominoUserControl = FindObjectOfType<TetrominoUserControl>();
        tetrominoUserControl.setActiveTetromino(gameObject);

        //set tetromino color to a random pairing
        int newColor = Random.Range(1, 7);
        
        foreach (Transform child in transform)
        {
            //First the tetromino base color
            child.GetComponent<SpriteRenderer>().color = tetrominoColors[newColor];
            //then the overlay
            child.GetChild(0).GetComponent<SpriteRenderer>().color = overlayColors[newColor];
        }
    }

    // Update is called once per frame
    void Update()
    {
        stepTimer += Time.deltaTime;

        if (stepTimer >= timeBetweenSteps && active)
        {
            stepTimer = stepTimer - timeBetweenSteps;
            nextStep();
        }
        
    }

    void nextStep()
    {
        //I want to run this for each piece of the tetromino.
        foreach (Transform child in transform)
        {
            if (checkFallCollision(child))
            {
                    wouldCollide = true;
                    break;
            }
        }
        
        if (wouldCollide == false)
        {
            Fall();
        }
        else
        {
            GetComponent<AudioSource>().Play();
            active = false;
            tetrominoUserControl.unsetActiveTetromino();
            tetrominoSpawnManager.spawnTetromino();
        }
    }

    private bool checkFallCollision(Transform pieceToCheck) //returns true if the next step collides with something
    {
        //Cast a ray to the next position of the tetromino. 
        //NOTE: disabled "Queries Start in Colliders" in Project Settings>Physics 2D (thank you again, Tavi).
        RaycastHit2D collision = Physics2D.Raycast(pieceToCheck.position, Vector2.down, 1.0f);
        
        //Only go further if the ray collided with something, and if that something is not another
        //piece of the same tetromino.
        if (collision.collider != null && collision.collider.transform.parent != pieceToCheck.parent)
        {
            Debug.Log("Collided with object: " + collision.collider.name);
            //We hit something, but we only want to collide with the ground or other tetrominoes.
            if (collision.collider.CompareTag("Ground") || collision.collider.CompareTag("Tetromino") || collision.collider.CompareTag("Platform"))
            {
                ScoreCounter.scoreAmount += 100;
                return true;
            }
            //We do also want to check if we're crushing the player.
            if (collision.collider.CompareTag("Player"))
            {
                SceneManager.LoadScene("loseScreen");
            }
        }

        return false;
    }

    void Fall()
    {
        transform.position += Vector3.down * 1.0f;
    }

}
