using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using GUI_Scripts.ProceduralGeneration;
using UnityEngine;
using UnityEngine.Tilemaps;
using Random = UnityEngine.Random;
using Vector2 = System.Numerics.Vector2;

public class TileMapGenerator : MonoBehaviour
{
    // Start is called before the first frame update

    public Tilemap ground, walls;
    public Tile ground1, wall1, corner_left_up, corner_left_down, corner_right_down, corner_right_up, left, right, up, down;
    public Graph graph;

    private void Start()
    {
        while (!Generate())
        {
            
        }
    }


    bool Generate()
    {
        Map map = new Map(new Vector2Int(100, 100));
        List<FloodFill> fillers = new List<FloodFill>();
        
        
        for (int i = 0; i < 70; i++)
        {
            FloodFill filler = new FloodFill(map, 1, new Vector2Int(Random.Range(0, 70), Random.Range(0, 70)));
            fillers.Add(filler);
        }
        map.Fill(fillers);
        
        Graph graph = new Graph(map);
        foreach (var filler in fillers)
        {
            graph.graphNodes.Add(filler);
        }
        graph.Connect();
        Debug.Log(graph.checkConnectivity());
        
        int count = fillers.Count;
        for (int i = 0; i < 101; i++)
        {
            GraphNode random = graph.graphNodes[Random.Range(0, graph.graphNodes.Count)];
            graph.removeNode(random);
            random.id = 2;
            
            if (!graph.checkConnectivity())
            {
                graph.AddNode(random);
                random.id = 1;
            }

            if (graph.graphNodes.Count < count / 2)
            {
                break;
            }
            
        }

        if (graph.graphNodes.Count > count * 0.8)
        {
            return false;
        }
        
        GraphNode playerPosStart = graph.graphNodes[Random.Range(0, graph.graphNodes.Count)];
        Vector2Int startPos = playerPosStart.positions.ElementAt(Random.Range(0, playerPosStart.positions.Count));
        Vector3 startPosOfPlayer = default;
        foreach (var filler in fillers)
        {
            int id = filler.id;
            foreach (var pos in filler.positions)
            {
                if (id == 1)
                {
                    ground.SetTile(new Vector3Int(pos.x,pos.y,0), ground1);
                    startPosOfPlayer = new Vector3Int(pos.x, pos.y, 0);
                }
                else if (id == 2)
                {
                    walls.SetTile(new Vector3Int(pos.x,pos.y,0), wall1);
                    
                }
            }
        }
        
        
        
        walls.SetTile(new Vector3Int(-1,-1,0), corner_left_down);
        walls.SetTile(new Vector3Int(-1,100,0), corner_left_up);
        walls.SetTile(new Vector3Int(100,100,0), corner_right_up);
        walls.SetTile(new Vector3Int(100,-1,0), corner_right_down);
        
        for (int i=0; i<100; i++){walls.SetTile(new Vector3Int(-1,i,0), left);}
        for (int i=0; i<100; i++){walls.SetTile(new Vector3Int(100,i,0), right);}
        for (int i=0; i<100; i++){walls.SetTile(new Vector3Int(i,-1,0), down);}
        for (int i=0; i<100; i++){walls.SetTile(new Vector3Int(i,100,0), up);}
        

        Debug.Log(startPos);
        Debug.Log("cell added");
        
        GameObject Player = GameObject.FindWithTag("Player");
        Player.transform.position = startPosOfPlayer;


        return true;
    }

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