using Unity.VisualScripting;
using Unity.VisualScripting.Antlr3.Runtime.Tree;
using UnityEngine;

public class BFMTerrainGenerator : MonoBehaviour
{
    [Header("Terrain Settings")]
    public float terrainMaxHeight = 20f;
    public float hilliness = 1.0f;
    public float noiseScale = 20f;
    public BFMTerrainType terrainType;

    public Terrain GenerateTerrain(int width, int height)
    {
        TerrainData terrainData = new TerrainData();

        int heightmapResolution = width + 1;
        terrainData.heightmapResolution = heightmapResolution;
        terrainData.size = new Vector3(width, terrainMaxHeight, height);

        // Generate heightmap
        float[,] heights = GenerateHeights(heightmapResolution, heightmapResolution);
        terrainData.SetHeights(0, 0, heights);

        // Create terrain GameObject
        GameObject terrainObject = Terrain.CreateTerrainGameObject(terrainData);
        if (terrainObject == null)
        {
            Debug.LogError("Failed to create terrain object. Check if the terrain width and height are a power of two (e.g., 128, 256, 512).");
            return null;
        }
        terrainObject.transform.parent = transform;

        // Add a Terrain Collider
        terrainObject.GetComponent<TerrainCollider>().terrainData = terrainData;

        return terrainObject.GetComponent<Terrain>();
    }

    private float[,] GenerateHeights(int mapWidth, int mapHeight)
    {
        float[,] heights = new float[mapWidth, mapHeight];
        float seed = Random.Range(0, 10000);

        // adjust noise parameters based on terrain type
        float currentNoiseScale = noiseScale;
        float currentHilliness = hilliness;

        switch (terrainType)
        {
            case BFMTerrainType.Forest:
                currentHilliness *= 0.5f;
                break;
            case BFMTerrainType.Mountain:
                currentNoiseScale *= 0.5f; // more frequent peaks
                currentHilliness *= 2.0f;
                break;
            case BFMTerrainType.Plain:
                currentHilliness *= 0.1f;
                break;
        }

        for (int x = 0; x < mapWidth; x++)
        {
            for (int y = 0; y < mapHeight; y++)
            {
                float xCoord = (float)x / mapWidth * currentNoiseScale + seed;
                float yCoord = (float)y / mapHeight * currentNoiseScale + seed;

                // Generate height using Perlin noise
                heights[x, y] = Mathf.PerlinNoise(xCoord, yCoord) * currentHilliness;
            }
        }
        return heights;
    }

    public void SetTerrainType(BFMTerrainType type)
    {
        terrainType = type;
        // To see the changes, the terrain needs to be regenerated.
    }

    // Additional methods for generating specific terrain features can be added here
}