using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using static System.Linq.Enumerable;

public class GridSystem<TGridObject>
{
    private int width;
    private int height;
    private float cellSize;
    private TGridObject[,] gridObjectArray;
    public GridSystem(int width, int height, float cellSize, Func<GridSystem<TGridObject>,GridPosition,TGridObject> createGridObject)
    {
        this.height = height;
        this.width = width;
        this.cellSize = cellSize;
        gridObjectArray = new TGridObject[width,height];
        foreach (var x in Range(0, gridObjectArray.GetLength(0)))
        {
            foreach (var z in Range(0, gridObjectArray.GetLength(1)))
            {
                GridPosition gridPosition = new GridPosition(x,z);
                gridObjectArray[x,z] = createGridObject(this,gridPosition);
            }
        }
    }

    public Vector3 GetWorldPosition(GridPosition gridPosition)
    {
        //Debug.Log($"{gridPosition.x}, {gridPosition.z}");
        return new Vector3(gridPosition.x, 0, gridPosition.z) * cellSize;
    }

    public GridPosition GetGridPosition(Vector3 worldPosition)
    {
        return new GridPosition(
            Mathf.RoundToInt( worldPosition.x / cellSize),
            Mathf.RoundToInt( worldPosition.z / cellSize)
        );
    }

    public void CreateDebugObjects(Transform debugPrefab)
    {
        foreach (var x in Range(0, gridObjectArray.GetLength(0)))
        {
            foreach (var z in Range(0, gridObjectArray.GetLength(1)))
            {
                GridPosition gridPosition = new GridPosition(x,z);
                Transform debugTransform = GameObject.Instantiate(debugPrefab, GetWorldPosition(gridPosition), Quaternion.identity);
                DebugGridObject debugGridObject = debugTransform.GetComponent<DebugGridObject>();
                debugGridObject.SetGridObject(GetGridObject(gridPosition));
            }
        }
    }

    public TGridObject GetGridObject(GridPosition gridPosition)
    {
        return gridObjectArray[gridPosition.x, gridPosition.z];
    }

    public TGridObject GetGridObject(int x, int z)
    {
        return gridObjectArray[x, z];
    }


    public bool IsValidGridPosition(GridPosition gridPosition) {
        return (
            gridPosition.x < width &&
            gridPosition.z < height &&
            gridPosition.x >= 0 &&
            gridPosition.z >= 0
            );
        
    }

    public int GetWidth() {
        return width;
    }

    public int GetHeight() {
        return height;
    }
}