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


public class GameManager : MonoBehaviour
{
    public GameObject linePrefab;
    public GameObject dotPrefab;
    public GameObject boxPrefab;
    public int numRows = 4;
    public int numColumns = 4;

    private List<Dot> dots = new List<Dot>();

    private Player currentPlayer;
    public Player player1;
    public Player player2;
    public Text player1ScoreText;
    public Text player2ScoreText;
    public Text TurnMessageText;

    private void Start()
    {
        GenerateDots();
        currentPlayer = player1;
        UpdateScoreUI();
        UpdateTurnUI();
    }

private void GenerateDots()
{
    float xOffset = 1.5f;
    float yOffset = 1.5f;

    float startX = -numColumns * xOffset / 2f + xOffset / 2f;
    float startY = numRows * yOffset / 2f - yOffset / 2f;

    for (int row = 0; row < numRows; row++)
    {
        for (int col = 0; col < numColumns; col++)
        {
            Vector3 dotPosition = new Vector3(startX + col * xOffset, startY - row * yOffset, 0);
            GameObject dotGO = Instantiate(dotPrefab, dotPosition, Quaternion.identity);
            Dot dot = dotGO.GetComponent<Dot>();
            dots.Add(dot);

            if (row < numRows - 1 && col < numColumns - 1)
            {
            Vector3 boxPosition = dotPosition + new Vector3(xOffset / 2f, -yOffset / 2f, 0);
            GameObject boxGO = Instantiate(boxPrefab, boxPosition, Quaternion.identity);
            Box box = boxGO.GetComponent<Box>();
            box.IsClaimed = false; // The box is not claimed initially
            boxGO.GetComponent<SpriteRenderer>().color = new Color(1f, 1f, 1f, 0f); // Transparent color
            }

            if (row > 0)
            {
                int prevRowDotIndex = (row - 1) * numColumns + col;
                if (prevRowDotIndex >= 0 && prevRowDotIndex < dots.Count)
                {
                    Dot prevRowDot = dots[prevRowDotIndex];
                    GameObject lineGO = Instantiate(linePrefab);
                    Line horizontalLine = lineGO.GetComponent<Line>();
                    horizontalLine.Dot1 = prevRowDot;
                    horizontalLine.Dot2 = dot;
                    prevRowDot.connectedLines.Add(horizontalLine); 
                    dot.connectedLines.Add(horizontalLine); 


                    Vector3 linePosition = (prevRowDot.transform.position + dot.transform.position) / 2f;
                    lineGO.transform.position = linePosition;
                    lineGO.transform.rotation = Quaternion.Euler(0, 0, 90f);
                }
            }

            if (col > 0)
            {
                int prevColDotIndex = row * numColumns + col - 1;
                if (prevColDotIndex >= 0 && prevColDotIndex < dots.Count)
                {
                    Dot prevColDot = dots[prevColDotIndex];
                    GameObject lineGO = Instantiate(linePrefab); 
                    Line verticalLine = lineGO.GetComponent<Line>();
                    verticalLine.Dot1 = prevColDot;
                    verticalLine.Dot2 = dot;

                    prevColDot.connectedLines.Add(verticalLine); 
                    dot.connectedLines.Add(verticalLine); 

                    
                    Vector3 linePosition = (prevColDot.transform.position + dot.transform.position) / 2f;
                    lineGO.transform.position = linePosition;
                    lineGO.transform.rotation = Quaternion.identity;
                }
            }
        }
    }
}



public void ClaimLine(Line line)
{
    if (!line.IsClaimed)
    {
        line.ClaimLine(GetCurrentPlayerColor());
        CheckForBoxes(line);
        SwitchPlayers();
    }
}

private void CheckForBoxes(Line claimedLine)
{
    Debug.Log("Checking for boxes...");
    foreach (Dot dot in dots)
    {
        int claimedLinesCount = 0;
        Line potentialBoxLine = null;

        foreach (Line line in dot.connectedLines)
        {
            if (line.IsClaimed)
            {
                claimedLinesCount++;

                if (line != claimedLine)
                {
                    potentialBoxLine = line;
                }
            }
        }
        Debug.Log("Dot: " + dot.name + ", Claimed Lines Count: " + claimedLinesCount);

        if (claimedLinesCount == 3)
        {
            Debug.Log("Potential box found at dot: " + dot.name);
            // All three adjacent lines are claimed
            Dot fourthDot = potentialBoxLine.GetOtherDot(dot);

            if (fourthDot != null)
            {
                Box box = GetBoxFromDots(dot, claimedLine.Dot1, claimedLine.Dot2, fourthDot);

                if (box != null && !box.IsClaimed)
                {
                    Debug.Log("Claiming box.");
                    box.IsClaimed = true;
                    box.GetComponent<SpriteRenderer>().color = GetCurrentPlayerColor();
                    currentPlayer.Score++;
                    UpdateScoreUI();
                }
            }
        }
    }
}



private Box GetBoxFromDots(Dot dot1, Dot dot2, Dot dot3, Dot dot4)
{
   
    foreach (Box box in FindObjectsOfType<Box>())
    {
        Vector3 boxCenter = (box.transform.position + dot1.transform.position + dot2.transform.position + dot3.transform.position + dot4.transform.position) / 5f;
        float boxWidth = Mathf.Abs(dot2.transform.position.x - dot1.transform.position.x);
        float boxHeight = Mathf.Abs(dot3.transform.position.y - dot1.transform.position.y);

       
        if (Vector3.Distance(boxCenter, dot1.transform.position) < boxWidth &&
            Vector3.Distance(boxCenter, dot1.transform.position) < boxHeight)
        {
            return box; 
        }
    }

    return null; 
}



private void InstantiateBox(Dot dot1, Dot dot2, Dot dot3, Dot dot4)
{

    Vector3 boxPosition = (dot1.transform.position + dot2.transform.position + dot3.transform.position + dot4.transform.position) / 4f;

    GameObject boxGO = Instantiate(boxPrefab, boxPosition, Quaternion.identity);
    Box box = boxGO.GetComponent<Box>();
    box.IsClaimed = true;
    boxGO.GetComponent<SpriteRenderer>().color = GetCurrentPlayerColor(); 
    currentPlayer.Score++;
    UpdateScoreUI();
}




//     private void CheckBox(Dot dot1, Dot dot2, Line line)
// {
//     if (line.Dot1 != dot1 && line.Dot1 != dot2 && line.Dot2 != dot1 && line.Dot2 != dot2)
//     {
//         Vector3 boxPosition = new Vector3((dot1.transform.position.x + dot2.transform.position.x) / 2f, (dot1.transform.position.y + line.transform.position.y) / 2f, 0);
//         GameObject boxGO = Instantiate(boxPrefab, boxPosition, Quaternion.identity);
//         Box box = boxGO.GetComponent<Box>();
//         box.IsClaimed = true;
//         currentPlayer.Score++;
//         Debug.Log("Box Claimed");
//         UpdateScoreUI();
//     }
// }

    private void UpdateScoreUI()
    {
        Debug.Log("updated score");
        player1ScoreText.text = "Player 1 Score: " + player1.Score.ToString();
        player2ScoreText.text = "Player 2 Score: " + player2.Score.ToString();
    }

    private void UpdateTurnUI()
    {
        TurnMessageText.text = "Turn: " + currentPlayer.playerName;
    }

    public Color GetCurrentPlayerColor()
    {
        return currentPlayer.playerColor;
    }

    private void SwitchPlayers()
    {
        currentPlayer = (currentPlayer == player1) ? player2 : player1;
        UpdateTurnUI();
    }

    public void ClaimLineForDot(Dot dot)
    {   Debug.Log("Claiming line for: "+dot.name);
        foreach (Line line in dot.connectedLines)
        {
            ClaimLine(line);
        }
    }

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