using UnityEngine; 
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance { get; private set; }
    
    [Header("Game Settings")]
    public int lives = 3;
    public int score = 0;

    [Header("Prefabs")]
    public Ball ballPrefab;
    public DestructibleBrick brickPrefab;
    public Paddle paddlePrefab;
    public MultiBallBrick multiBallBrickPrefab;
    public GameObject splitBallPrefab; // Префаб дочернего мяча

    [Header("Field Configuration")]
    public int rows = 5;
    public int columns = 8;
    public float brickSpacing = 0.2f;
    public Vector2 brickOffset = new Vector2(0, 4);
    
    [Header("Special Bricks")]
    [Range(0, 10)]
    public int multiBallBricksCount = 3; // Количество специальных блоков на поле

    [Header("Scale Settings")]
    [Range(0.1f, 3.0f)]
    public float brickScale = 1.0f;
    [Range(0.1f, 3.0f)]
    public float ballScale = 1.0f;
    [Range(0.1f, 3.0f)] 
    public float paddleScale = 1.0f;

    [Header("Wall Settings")]
    public float wallThickness = 0.5f;
    public float wallHeight = 10f;
    public Color wallColor = Color.gray;

    // Properties for UI access
    public int DestroyedBricks => destroyedBricks;
    public int TotalBricks => totalBricks;
    public int UsedLives => usedLives;
    public int InitialLives => initialLives;

    private Ball currentBall;
    private Paddle paddle;
    private GameObject leftWall;
    private GameObject rightWall;
    private GameObject topWall;
    private int totalBricks;
    private int destroyedBricks;
    private int initialLives;
    private int usedLives;
    private int activeBallsCount = 0;

    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    void Start()
    {
        InitializeGame();
    }

    void InitializeGame()
    {
        score = 0;
        destroyedBricks = 0;
        usedLives = 0;
        initialLives = lives;
        totalBricks = rows * columns;
        
        CreateWalls();
        
        // Создаем платформу с заданным масштабом
        paddle = Instantiate(paddlePrefab, new Vector3(0, -4, 0), Quaternion.identity);
        paddle.transform.localScale = new Vector3(paddleScale, paddleScale, 1f);
        
        SpawnNewBall();
        CreateBricks();
    }

    void CreateBricks()
    {
        Vector2 brickSize = brickPrefab.GetComponent<SpriteRenderer>().bounds.size;
        // Применяем масштаб к размеру блока
        brickSize *= brickScale;

        // Создаем список всех возможных позиций
        Vector2[,] positions = new Vector2[rows, columns];
        for (int row = 0; row < rows; row++)
        {
            for (int col = 0; col < columns; col++)
            {
                positions[row, col] = new Vector2(
                    (-columns/2f + col) * (brickSize.x + brickSpacing) + brickSize.x/2f,
                    brickOffset.y - row * (brickSize.y + brickSpacing)
                );
            }
        }

        // Размещаем специальные блоки случайным образом
        int specialBricksPlaced = 0;
        while (specialBricksPlaced < multiBallBricksCount)
        {
            int randomRow = Random.Range(0, rows);
            int randomCol = Random.Range(0, columns);

            if (positions[randomRow, randomCol] == Vector2.zero)
                continue;

            // Создаем специальный блок
            Brick specialBrick = Instantiate(multiBallBrickPrefab, positions[randomRow, randomCol], Quaternion.identity);
            specialBrick.transform.localScale = new Vector3(brickScale, brickScale, 1f);

            // Помечаем позицию как использованную
            positions[randomRow, randomCol] = Vector2.zero;
            specialBricksPlaced++;
        }

        // Заполняем оставшиеся позиции обычными блоками
        for (int row = 0; row < rows; row++)
        {
            // Количество жизней зависит от строки (сверху вниз)
            // Максимум 15 жизней для самого верхнего ряда
            int rowHitPoints = Mathf.Min(15, rows - row);
            
            // Очки за блок зависят от количества жизней
            int rowPoints = rowHitPoints * 100;
            
            for (int col = 0; col < columns; col++)
            {
                // Пропускаем использованные позиции
                if (positions[row, col] == Vector2.zero)
                    continue;

                DestructibleBrick brick = Instantiate(brickPrefab, positions[row, col], Quaternion.identity);
                brick.transform.localScale = new Vector3(brickScale, brickScale, 1f);
                brick.hitPoints = rowHitPoints;
                brick.points = rowPoints;
            }
        }
    }

    public SplitBall CreateSplitBall(Vector3 position, Vector2 velocity, float scale)
    {
        GameObject splitBallObj = Instantiate(splitBallPrefab.gameObject, position, Quaternion.identity);
        SplitBall splitBall = splitBallObj.GetComponent<SplitBall>();
        
        if (splitBall != null)
        {
            splitBall.Initialize(velocity, scale);
            activeBallsCount++; // Увеличиваем счетчик при создании нового мяча
            Debug.Log($"Split ball created. Active balls: {activeBallsCount}");
        }
        
        return splitBall;
    }

    public void SpawnNewBall()
    {
        // Создаем новый мяч только если нет других активных мячей
        if (activeBallsCount <= 0)
        {
            // Создаем мяч над платформой с учетом масштабов
            float paddleHeight = paddle.GetComponent<SpriteRenderer>().bounds.size.y;
            float ballHeight = ballPrefab.GetComponent<SpriteRenderer>().bounds.size.y * ballScale;
            Vector3 spawnPosition = paddle.transform.position + Vector3.up * (paddleHeight/2 + ballHeight/2 + 0.1f);
            
            GameObject ballObj = Instantiate(ballPrefab.gameObject, spawnPosition, Quaternion.identity);
            currentBall = ballObj.GetComponent<Ball>();
            if (currentBall != null)
            {
                currentBall.transform.localScale = Vector3.one * ballScale;
                activeBallsCount++; // Увеличиваем счетчик при создании основного мяча
                Debug.Log($"Main ball created. Active balls: {activeBallsCount}");
            }
        }
        else
        {
            Debug.Log($"Not spawning main ball - there are still {activeBallsCount} active balls");
        }
    }

    // Перегрузка для обратной совместимости
    public void LoseBall()
    {
        LoseBall(null);
    }

    public void LoseBall(Ball ball)
    {
        if (ball != null)
        {
            if (ball == currentBall)
            {
                currentBall = null;
            }
            Destroy(ball.gameObject);
            activeBallsCount--;
            Debug.Log($"Ball lost. Remaining active balls: {activeBallsCount}");
        }
        else
        {
            // Если мяч не указан, считаем что это основной мяч
            if (currentBall != null)
            {
                Destroy(currentBall.gameObject);
                currentBall = null;
                activeBallsCount--;
                Debug.Log($"Main ball lost. Remaining active balls: {activeBallsCount}");
            }
        }

        // Проверяем, остались ли еще мячи
        if (activeBallsCount <= 0)
        {
            lives--;
            usedLives++;
            UpdateUI();
            Debug.Log($"No balls remaining. Lives left: {lives}");
            
            if (lives <= 0)
            {
                GameOver();
            }
            else
            {
                SpawnNewBall();
            }
        }
    }

    public void BrickDestroyed()
    {
        destroyedBricks++;
        CheckWinCondition();
    }

    public void AddScore(int points)
    {
        score += points;
    }

    public void CheckWinCondition()
    {
        if (destroyedBricks >= totalBricks) // Check if this was the last brick
        {
            WinGame();
        }
    }

    void GameOver()
    {
        Debug.Log("Game Over! Final Score: " + score);
        // Implement game over UI and restart functionality
        Invoke("RestartGame", 2f);
    }

    void WinGame()
    {
        Debug.Log("You Win! Score: " + score);
        // Implement win UI and next level or restart functionality
        Invoke("RestartGame", 2f);
    }

    void RestartGame()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }

    void CreateWalls()
    {
        // Calculate wall positions based on camera viewport
        float screenHalfWidth = Camera.main.orthographicSize * Camera.main.aspect;
        float screenHalfHeight = Camera.main.orthographicSize;
        float wallX = screenHalfWidth + (wallThickness / 2f);
        float wallY = screenHalfHeight + (wallThickness / 2f);

        // Create left wall
        leftWall = CreateWall(-wallX, 0, wallThickness, wallHeight, "LeftWall");
        
        // Create right wall
        rightWall = CreateWall(wallX, 0, wallThickness, wallHeight, "RightWall");

        // Create top wall
        topWall = CreateWall(0, wallY, screenHalfWidth * 2, wallThickness, "TopWall");
    }

    GameObject CreateWall(float xPosition, float yPosition, float width, float height, string name)
    {
        GameObject wall = new GameObject(name);
        wall.transform.position = new Vector3(xPosition, yPosition, 0);
        
        // Add BoxCollider2D
        BoxCollider2D collider = wall.AddComponent<BoxCollider2D>();
        collider.size = new Vector2(width, height);
        
        // Add SpriteRenderer to make the wall visible
        SpriteRenderer renderer = wall.AddComponent<SpriteRenderer>();
        renderer.sprite = CreateWallSprite();
        renderer.color = wallColor;
        
        // Scale the wall to match the collider
        wall.transform.localScale = new Vector3(width, height, 1);

        // Add physics material for proper bouncing
        collider.sharedMaterial = new PhysicsMaterial2D
        {
            bounciness = 1f,
            friction = 0f
        };
        
        return wall;
    }

    Sprite CreateWallSprite()
    {
        // Create a 1x1 white texture that we can tint
        Texture2D texture = new Texture2D(1, 1);
        texture.SetPixel(0, 0, Color.white);
        texture.Apply();
        
        return Sprite.Create(texture, new Rect(0, 0, 1, 1), new Vector2(0.5f, 0.5f));
    }

    // Handle Telegram back button
    public void HandleBackButton()
    {
        // Pause the game
        Time.timeScale = 0;
        
        // Here you could show a pause menu or exit confirmation
        // For now, we'll just resume the game
        Time.timeScale = 1;
    }

    private void UpdateUI()
    {
        // Implement UI update logic here
    }
}
