using System.Collections.Generic;
using Intrepid.Utilities;
using Sirenix.OdinInspector;
using UnityEngine;

namespace Intrepid.Gameplay.Prototyping
{
    public class GroundRampModelPrototype : GroundModelPrototype
    {
        [GroupConfigurations, SerializeField, ReadOnly] private int sizeX = 1;
        [GroupConfigurations, SerializeField, ReadOnly] private int sizeZ = 1;

        [GroupDebug, SerializeField, Min(1)] private int x = 1;
        [GroupDebug, SerializeField, Min(1)] private int z = 1;

        public override void SetSize(Vector2Int size)
        {
            x = size.x;
            z = size.y;
            SizeFitting();
        }

        protected override void DebugResize()
        {
            sizeX = Mathf.Max(1, x);
            sizeZ = Mathf.Max(1, z);
        }

        protected override void Generate()
        {
            PrototypeModel.BuildMesh(BuildRampMeshData(new Vector3(sizeX, sizeZ * 0.5f, sizeZ)));
            
            PrototypeModel.BoxCollider.transform.localEulerAngles = new Vector3(-26.5f, 0f, 0f);
            PrototypeModel.BoxCollider.center = new Vector3(0f, -0.02625f, 0f);
            PrototypeModel.BoxCollider.size = new Vector3(sizeX, 0.05f, sizeZ * 2.236125f * 0.5f);

            PrototypeModel.transform.localPosition = new Vector3(0f, sizeZ * .25f, 0f);
        }
        
        private static MeshData BuildRampMeshData(Vector3 size)
        {
            var halfX = size.x * 0.5f;
            var halfY = size.y * 0.5f;
            var halfZ = size.z * 0.5f;

            var bottomY = -halfY;
            var topY = halfY;

            var countX = Mathf.Max(1, Mathf.RoundToInt(size.x));
            var countZ = Mathf.Max(1, Mathf.RoundToInt(size.z));

            var vertices = new List<Vector3>();
            var triangles = new List<int>();
            var uvs = new List<Vector2>();

            var rampStep = new Vector3(
                0f,
                size.y / countZ,
                size.z / countZ
            );

            // Ramp surface
            MeshUtils.AddGridFace(
                vertices,
                triangles,
                uvs,
                origin: new Vector3(halfX, bottomY, -halfZ),
                axisU: Vector3.left,
                axisV: rampStep,
                countU: countX,
                countV: countZ);
            
            // Left
            MeshUtils.AddTriangle(
                vertices,
                triangles,
                uvs,
                new Vector3(-halfX, bottomY, -halfZ),
                new Vector3(-halfX, bottomY, halfZ),
                new Vector3(-halfX, topY, halfZ),
                new Vector2(0f, 0f),
                new Vector2(size.z, 0f),
                new Vector2(size.z, size.y)
            );

            // Right
            MeshUtils.AddTriangle(
                vertices,
                triangles,
                uvs,
                new Vector3(halfX, bottomY, -halfZ),
                new Vector3(halfX, topY, halfZ),
                new Vector3(halfX, bottomY, halfZ),
                new Vector2(0f, 0f),
                new Vector2(size.z, size.y),
                new Vector2(size.z, 0f)
            );

            return new MeshData(
                vertices.ToArray(),
                triangles.ToArray(),
                uvs.ToArray()
            );
        }
    }
}