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

public class TetrisBlock : MonoBehaviour
{
    public static bool isLineClearAnimationInProgress = false;
    public float lineClearAnimationDuration = 1f;
    public float fallTimeDecrease = 0.2f;
    public float minFallTime = 0.01f;
    public static int LinesCleared;
    public static int height = 21;
    public TMP_Text Lines_Cleared;
    public int linesPerLevel = 10;
    public Vector3 rotationPoint;
    public float fallTime = 0.8f;
    public static int width = 10;
    public bool gameOver = false;

    [SerializeField] private Animator myAnimationController;
    private static Transform[,] grid = new Transform[width, height];
    private float initialFallTime = 0.8f;
    private GameManager gameManager;
    private int previousLevel = 0;
    private GameObject startMenu;
    private float previousTime;
    private int level = 0;
    private SpawnTetromino spawnTetromino;
    private static int linesClearingCount = 0;

    [SerializeField] private Animator blockAnimator;
    [SerializeField] private string lineClearAnimationTrigger = "LineClear"; 

    [SerializeField] private AnimationClip lineClearClip;

    private TMP_Text linesClearedText;

    void ResetGame()
    {
        if (SceneController.hasRestartedScene)
        {
            startMenu.SetActive(false);
            fallTime = initialFallTime;
            level = 0;
            LinesCleared = 0;
            linesClearingCount = 0;
            UpdateUi();
            SceneController.hasRestartedScene = false;
            Debug.Log($"Scene Has restarted, hasRestartedScene: {SceneController.hasRestartedScene}, fallTime: {fallTime}");
        }
    }

    void Update()
    {
        if (startMenu != null && !startMenu.activeSelf)
        {
            LevelUp();
            InputHandler();
        }
    }

    void InputHandler()
    {
        if(Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A))
        {
            transform.position += new Vector3(-1, 0, 0);
            if(!ValidMove())
                transform.position -= new Vector3(-1, 0, 0);
        }
        else if (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D))
        {
            transform.position += new Vector3(1, 0, 0);
            if (!ValidMove())
                transform.position -= new Vector3(1, 0, 0);
        }
        else if (Input.GetKeyDown(KeyCode.X))
        {
            transform.RotateAround(transform.TransformPoint(rotationPoint), new Vector3(0,0,1), 90);
            if (!ValidMove())
                transform.RotateAround(transform.TransformPoint(rotationPoint), new Vector3(0, 0, 1), -90);
        }

        if (Time.time - previousTime > (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S) ? fallTime / 10 : fallTime))
        {
            transform.position += new Vector3(0, -1, 0);
            if (!ValidMove())
            {
                transform.position -= new Vector3(0, -1, 0);
                AddToGrid();
                CheckForLines();

                this.enabled = false;
                
                if (linesClearingCount == 0 && !gameOver)
                {
                    spawnTetromino.NewTetromino();
                }
            }
            previousTime = Time.time;
        } 
    }

    IEnumerator ClearLines(int i)
    {
        List<Animator> rowAnimators = new List<Animator>();
        
        for (int j = 0; j < width; j++)
        {
            if (grid[j, i] != null)
            {
                Animator animator = grid[j, i].GetComponent<Animator>();
                if (animator != null)
                {
                    rowAnimators.Add(animator);
                }
            }
        }
        
        foreach (Animator animator in rowAnimators)
        {
            animator.SetTrigger(lineClearAnimationTrigger);
        }

        float animationLength = (lineClearClip != null ? lineClearClip.length : 1f) * 5;
        yield return new WaitForSeconds(animationLength);
        
        for (int j = 0; j < width; j++)
        {
            if (grid[j, i] != null)
            {
                Destroy(grid[j, i].gameObject);
                grid[j, i] = null;
            }
        }
        
        RowDown(i);
        
        UpdateUi();
        
        linesClearingCount--;
        
        if (linesClearingCount <= 0)
        {
            isLineClearAnimationInProgress = false;
            if (!gameOver)
            {
                spawnTetromino.NewTetromino();
            }
        }
    }

    void CheckForLines()
    {
        for (int i = height - 1; i >= 0; i--)
        {
            if (HasLine(i))
            {
                LinesCleared++;
                linesClearingCount++;
                StartCoroutine(ClearLines(i));
            }
        }

        if (linesClearingCount > 0)
        {
            isLineClearAnimationInProgress = true;
        }
    }

    bool HasLine(int i)
    {
        for(int j = 0; j< width; j++)
        {
            if (grid[j, i] == null)
                return false;
        }

        return true;
    }

    void DeleteLine(int i)
    {
        for (int j = 0; j < width; j++)
        {
            if (grid[j, i] != null)
            {
                Animator animator = grid[j, i].GetComponent<Animator>();
                if (animator != null)
                {
                    animator.SetTrigger(lineClearAnimationTrigger);
                }
                
                Destroy(grid[j, i].gameObject, lineClearAnimationDuration);
                grid[j, i] = null;
            }
        }
    }

    void RowDown(int i)
    {
        for (int y = i; y < height; y++)
        {
            for (int j = 0; j < width; j++)
            {
                if(grid[j,y] != null)
                {
                    grid[j, y - 1] = grid[j, y];
                    grid[j, y] = null;
                    grid[j, y - 1].transform.position -= new Vector3(0, 1, 0);
                }
            }
        }
    }

    void AddToGrid()
    {
        bool gameOverFlag = false;
        foreach (Transform children in transform)
        {
            int roundedX = Mathf.RoundToInt(children.transform.position.x);
            int roundedY = Mathf.RoundToInt(children.transform.position.y);

            if (roundedX < 0 || roundedX >= width || roundedY < 0 || roundedY >= height)
            {
                gameOverFlag = true;
                break;
            }

            grid[roundedX, roundedY] = children;
            
            if (children.transform.position.y >= 19.5f)
            {
                gameOverFlag = true;
            }
        }

        if (gameOverFlag)
        {
            gameOver = true;
            FindObjectOfType<SpawnTetromino>().GameOver();
        }
    }

    bool ValidMove()
    {
        foreach (Transform children in transform)
        {
            int roundedX = Mathf.RoundToInt(children.transform.position.x);
            int roundedY = Mathf.RoundToInt(children.transform.position.y);

            if(roundedX < 0 || roundedX >= width || roundedY < 0 ||roundedY >= height)
            {
                return false;
            }

            if (grid[roundedX, roundedY] != null)
                return false;
        }

        return true;
    }

    public void UpdateUi()
    {
        if (linesClearedText == null)
        {
            linesClearedText = GameObject.Find("Lines_Cleared").GetComponent<TextMeshProUGUI>();
            if (linesClearedText == null)
            {
                Debug.LogError("Lines_Cleared TextMeshProUGUI component not found!");
                return;
            }
        }

        linesClearedText.text = "Lines Cleared: " + LinesCleared.ToString();
        Debug.Log(linesClearedText.text);
    }

    void LevelUp()
    {
        int newLevel = LinesCleared / linesPerLevel;

        if (newLevel > level)
        {
            int levelDifference = newLevel - level;
            level = newLevel;

            for (int i = 0; i < levelDifference; i++)
            {
                fallTime = Mathf.Max(fallTime - fallTimeDecrease, minFallTime);
            }
        }
    }

    public static void ResetStaticVariables()
    {
        grid = new Transform[width, height];
        LinesCleared = 0;
    }
    
    void Start()
    {
        gameManager = FindObjectOfType<GameManager>();
        
        if (gameManager != null)
        {
            startMenu = gameManager.StartMenu;
        }
        else
        {
            Debug.LogError("GameManager not found in the scene!");
        }

        linesClearedText = GameObject.Find("Lines_Cleared").GetComponent<TextMeshProUGUI>();
        if (linesClearedText == null)
        {
            Debug.LogError("Lines_Cleared TextMeshProUGUI component not found!");
        }

        ResetGame();
        
        spawnTetromino = FindObjectOfType<SpawnTetromino>();
        
        blockAnimator = GetComponent<Animator>();
        if (blockAnimator == null)
        {
            Debug.LogError("Animator component not found on the Tetris block!");
        }

        if (lineClearClip == null)
        {
            Debug.LogError("Line Clear AnimationClip is not assigned!");
        }
    }
}

fix the issue where all of the pieces don't get cleared at the same time and the animation doesn't start at the same time when clearing line