using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using GUI_Scripts.ProceduralGeneration;
using UnityEditor.MemoryProfiler;
using UnityEngine;

public class Graph
{
    public List<GraphNode> graphNodes = new List<GraphNode>();
    public Dictionary<Vector2Int, GraphNode> nodesPositions = new Dictionary<Vector2Int, GraphNode>();
    public Map map;
    public Graph(Map map)
    {
        this.map = map;
    }
    
    public void Connect()
    {
        nodesPositions.Clear();
        foreach (var node in graphNodes)
        {
            node.neighbours.Clear();
            foreach (var pos in node.positions)
            {
                nodesPositions.Add(pos, node);
            }
        }
        Debug.Log(graphNodes.Count);
        Debug.Log(nodesPositions.Count);
        
        for (int i = 0; i < map.size.x-1; i++)
        {
            for (int j = 0; j < map.size.y-1; j++)
            {
                Vector2Int pos = new Vector2Int(i, j);
                Vector2Int right = new Vector2Int(i + 1, j);
                Vector2Int down = new Vector2Int(i, j + 1);
                
                if (!nodesPositions.ContainsKey(pos))
                {
                    continue;
                }

                GraphNode node = nodesPositions[pos];                
                
                if (nodesPositions.TryGetValue(right, out GraphNode nodeRight))
                {
                    if (node != nodeRight)
                    {
                        node.neighbours.Add(nodeRight);
                        nodeRight.neighbours.Add(node);
                    }
                }
                
                if (nodesPositions.TryGetValue(right, out GraphNode nodeDown))
                {
                    if (node != nodeDown)
                    {
                        node.neighbours.Add(nodeDown);
                        nodeDown.neighbours.Add(node);
                    }
                }



            }
        }
    }

    public void removeNode(GraphNode node)
    {
        graphNodes.Remove(node);
        Connect();
    }
    
    public void AddNode(GraphNode node)
    {
        graphNodes.Add(node);
        Connect();
    }
    
    public bool checkConnectivity()
    {
        GraphNode nodeStart = graphNodes[0];
        Queue<GraphNode> toCheck = new Queue<GraphNode>();
        List<GraphNode> visited = new List<GraphNode>();
        toCheck.Enqueue(nodeStart);
        while (toCheck.Count > 0)
        {
            GraphNode checkNow = toCheck.Dequeue();
            visited.Add(checkNow);
            foreach (var node in checkNow.neighbours)
            {
                if (!toCheck.Contains(node) && !visited.Contains(node))
                {
                    toCheck.Enqueue(node);
                }
            }
        }

        return visited.Count == graphNodes.Count;
    }

    // Start is called before the first frame update
    void Start()
    {
        
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}