using System.Collections.Generic;
using UnityEngine;

public class SpawnRandomObjectsScript : MonoBehaviour
{
    [SerializeField] private List<GameObject> _Prefabs = new List<GameObject>();
    [SerializeField] private Vector3 _SpawnArea;

    [SerializeField] private float fixedDistance = 1f; // фиксированное расстояние между точками
    private float MinX;  // минимальная координата X
    private float MaxX;  // максимальная координата X
    private float MinZ;  // минимальная координата Z
    private float MaxZ;  // максимальная координата Z

    private float Y;

    // кол-во повторных проходов
    [SerializeField] private int NumOfRep = 1;

    // Структура Point теперь на плоскости X-Z
    // Структура Point теперь на плоскости X-Z
    public struct Point
    {
        public Vector3 Position; // позиция точки

        public Point(float x, float y, float z)
        {
            Position = new Vector3(x, y, z); // плоскость 2D, Y-координата всегда 0
        }

        public float DistanceTo(Point other)
        {
            return Vector3.Distance(Position, other.Position); // возвращаем расстояние между точками
        }
    }
    private List<Point> points = new List<Point>();


    void Start()
    {
        MinX = -_SpawnArea.x / 2 + transform.position.x;
        MaxX = _SpawnArea.x / 2 + transform.position.x;
        MinZ = -_SpawnArea.z / 2 + transform.position.z;
        MaxZ = _SpawnArea.z / 2 + transform.position.z;

        Y = -_SpawnArea.y / 2 + transform.position.y;

        GeneratePoints();
        foreach (var point in points)
        {
            GameObject prefab = GetRandomObject<GameObject>(_Prefabs);


            // Случайный поворот только по оси Y
            Quaternion randomRotation = Quaternion.Euler(
                0f,  // угол по оси X
                Random.Range(0f, 360f), // случайный угол по оси Y
                0f   // угол по оси Z
            );

            // Инстанцируем объект с случайным поворотом
            Transform child = Instantiate(prefab, point.Position, randomRotation).transform;
            child.SetParent(transform);

        }

    }

    public void GeneratePoints()
    {
        // Размещение первой точки случайным образом в указанном диапазоне
        points.Add(new Point(Random.Range(MinX, MaxX), Y, Random.Range(MinZ, MaxZ)));

        for (int i = 0; i < NumOfRep; i++)
        {
            bool canAddPoint = true;

            while (canAddPoint)
            {
                canAddPoint = false;
                // Пробуем случайно разместить следующую точку в пределах нового диапазона
                float newX = Random.Range(MinX, MaxX);
                float newZ = Random.Range(MinZ, MaxZ);
                Point newPoint = new Point(newX, Y, newZ);

                bool valid = true;

                foreach (var point in points)
                {
                    if (newPoint.DistanceTo(point) < fixedDistance) // фиксированное расстояние
                    {
                        valid = false;
                        break;
                    }
                }

                // Если точка валидна (удовлетворяет условиям), добавляем её
                if (valid)
                {
                    points.Add(newPoint);
                    canAddPoint = true;
                }
            }
        }
    }

    void OnDrawGizmos()
    {
        // Устанавливаем цвет Gizmos
        Gizmos.color = Color.red;

        // Рисуем сферу
        Gizmos.DrawWireCube(transform.position, _SpawnArea);
    }
    T GetRandomObject<T>(List<T> list)
    {
        // проверка на пустоту списка
        if (list == null || list.Count == 0)
        {
            return default;
        }

        // Генерация случайного индекса
        int randomIndex = UnityEngine.Random.Range(0, list.Count);
        return list[randomIndex];
    }
}
