using System.Runtime.CompilerServices;
using UnityEngine;

public class MapMakerMain : MonoBehaviour
{

    // Terrain width and height must be a power of two (e.g., 64, 128, 256)
    // for a valid heightmap resolution (power of two + 1).
    [SerializeField] private int mapWidth = 128;
    [SerializeField] private int mapHeight = 128;
    [SerializeField] private BFMTerrainType initialTerrainType = BFMTerrainType.Plain;
    [SerializeField][Range(0.1f, 5.0f)] private float hilliness = 1.0f;
    [SerializeField][Range(1f, 20f)] private float noiseScale = 10f;
    [SerializeField][Range(10f, 200f)] private float terrainMaxHeight = 20f;

    private BFMTerrainGenerator terrainGenerator;
    private NavMeshGenerator navMeshGenerator;
    private Terrain currentTerrain;

    void Start()
    {
        terrainGenerator = gameObject.AddComponent<BFMTerrainGenerator>();
        navMeshGenerator = gameObject.AddComponent<NavMeshGenerator>();

        // Initialize the map with specified dimensions
        InitializeComponents();
        GenerateMap(mapWidth, mapHeight);
    }



#if UNITY_EDITOR
    private bool m_DelayedUpdateScheduled = false;
    private void OnValidate()
    {
        if (m_DelayedUpdateScheduled) return;

        UnityEditor.EditorApplication.delayCall += () =>
        {
            m_DelayedUpdateScheduled = false;

            // OnValidate can be called on prefabs, or when the component is not fully initialized.
            // We only want to run this on scene objects that are not being destroyed.
            if (this == null || !gameObject.scene.IsValid())
            {
                return;
            }

            InitializeComponents();
            GenerateMap(mapWidth, mapHeight);
        };

        m_DelayedUpdateScheduled = true;
    }
#endif

    private void InitializeComponents()
    {
        // Use GetComponent first to avoid adding multiple components if they already exist
        if (terrainGenerator == null)
        {
            terrainGenerator = GetComponent<BFMTerrainGenerator>();
            if (terrainGenerator == null)
            {
                terrainGenerator = gameObject.AddComponent<BFMTerrainGenerator>();
            }

            navMeshGenerator = GetComponent<NavMeshGenerator>();
            if (navMeshGenerator == null)
            {
                navMeshGenerator = gameObject.AddComponent<NavMeshGenerator>();
            }

        }
    }

    private void GenerateMap(int width, int height)
    {
        // Cleanup old terrain if it exists
        if (currentTerrain != null)
        {
            if (Application.isPlaying)
            {
                Destroy(currentTerrain.gameObject);
            }
            else
            {
                // Use DestroyImmediate when in the editor and not in play mode.
                DestroyImmediate(currentTerrain.gameObject);
            }
        }

        // Configure TerrainGenerator from MapMakerMain settings
        terrainGenerator.terrainType = initialTerrainType;
        terrainGenerator.hilliness = hilliness;
        terrainGenerator.noiseScale = noiseScale;
        terrainGenerator.terrainMaxHeight = terrainMaxHeight;

        // Generate terrain and NavMesh based on specified dimensions
        // Adjust the arguments below to match the correct overload of GenerateTerrain
        currentTerrain = terrainGenerator.GenerateTerrain(width, height);
        if (currentTerrain == null)
        {
            Debug.LogError("Terrain generation failed. Aborting map generation.");
            return;
        }
        navMeshGenerator.terrain = currentTerrain;
        navMeshGenerator.GenerateNavMesh();
    }
}