using System;
using Intrepid.Utilities;
using UnityEngine;

namespace Intrepid.Gameplay.Prototyping
{
    public struct MeshData
    {
        public Vector3[] Vertices { get; }
        public int[] triangles { get; }
        public Vector2[] UVs { get; }

        public MeshData(Vector3[] vertices, int[] triangles, Vector2[] uVs)
        {
            Vertices = vertices;
            this.triangles = triangles;
            UVs = uVs;
        }
    }
    
    public class PrototypeModel : MonoBehaviour
    {
        [GroupInjections, SerializeField] private MeshFilter debugMeshFilter;
        [GroupInjections, SerializeField] private MeshRenderer debugRenderer;
        [GroupInjections, SerializeField] private BoxCollider boxCollider;

        public MeshFilter DebugMeshFilter => debugMeshFilter;
        public MeshRenderer DebugRenderer => debugRenderer;
        public BoxCollider BoxCollider => boxCollider;

        private Mesh mesh;
        
        public void SetupDebugVisibility()
        {
            if (DebugRenderer.IsNull()) return;
            if (DebugRenderer.gameObject.activeSelf && DebugRenderer.enabled)
            {
                DebugRenderer.enabled = GonConstants.Prototyping.DebugPrototyping;
            }
        }
        
        public void ForceBuildMesh()
        {
            if (mesh.IsNotNull()) ForceDestroyMesh();
            mesh = new Mesh
            {
                name = "Procedural Debug Cube Instance"
            };
            DebugMeshFilter.mesh = mesh;
        }

        private void ForceDestroyMesh()
        {
            if (Application.isPlaying)
            {
                Destroy(mesh);
            }
            else
            {
                DestroyImmediate(mesh);
            }
        }
        
        public void BuildMesh(MeshData meshData)
        {
            ForceBuildMesh();
            mesh.Clear();
            mesh.vertices = meshData.Vertices;
            mesh.triangles = meshData.triangles;
            mesh.uv = meshData.UVs;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
        }
        
        private void OnDestroy()
        {
            ForceDestroyMesh();
        }
    }
}