using UnityEditor;
using UnityEngine;

namespace AlterchaseSDK.Editor
{
    [CustomEditor(typeof(PlayerSpawnReference))]
    public class PlayerSpawnReferenceEditor : UnityEditor.Editor
    {
        [MenuItem("GameObject/Alterchase SDK/Player Spawn Reference", false, 10)]
        private static void CreatePlayerSpawnReference(MenuCommand menuCommand)
        {
            GameObject go = new GameObject("PlayerSpawnReference");
            go.AddComponent<PlayerSpawnReference>();
            
            CreateVisualMarker(go);
            
            GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject);
            Undo.RegisterCreatedObjectUndo(go, "Create Player Spawn Reference");
            Selection.activeObject = go;
        }

        private static void CreateVisualMarker(GameObject parent)
        {
            GameObject visual = new GameObject("Visual (Editor Only)");
            visual.transform.SetParent(parent.transform);
            visual.transform.localPosition = Vector3.zero;
            visual.transform.localRotation = Quaternion.identity;
            visual.tag = "EditorOnly";
            
            GameObject platform = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
            platform.name = "Platform";
            platform.transform.SetParent(visual.transform);
            platform.transform.localPosition = new Vector3(0, 0.05f, 0);
            platform.transform.localRotation = Quaternion.identity;
            platform.transform.localScale = new Vector3(1.5f, 0.05f, 1.5f);
            
            MeshRenderer platformRenderer = platform.GetComponent<MeshRenderer>();
            Material platformMat = new Material(Shader.Find("Standard"));
            platformMat.color = new Color(0.2f, 0.7f, 1f, 1f);
            platformMat.SetFloat("_Metallic", 0.5f);
            platformMat.SetFloat("_Glossiness", 0.6f);
            platformRenderer.material = platformMat;
            
            DestroyImmediate(platform.GetComponent<Collider>());
            
            GameObject arrow = new GameObject("Arrow");
            arrow.transform.SetParent(visual.transform);
            arrow.transform.localPosition = new Vector3(0, 0.15f, 0);
            arrow.transform.localRotation = Quaternion.Euler(-90, 0, 0);
            
            GameObject arrowHead = GameObject.CreatePrimitive(PrimitiveType.Cube);
            arrowHead.name = "ArrowHead";
            arrowHead.transform.SetParent(arrow.transform);
            arrowHead.transform.localPosition = new Vector3(0, 0.6f, 0);
            arrowHead.transform.localRotation = Quaternion.Euler(0, 45, 0);
            arrowHead.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
            
            MeshRenderer arrowHeadRenderer = arrowHead.GetComponent<MeshRenderer>();
            Material arrowMat = new Material(Shader.Find("Standard"));
            arrowMat.color = new Color(1f, 0.8f, 0.2f, 1f);
            arrowMat.SetFloat("_Metallic", 0.3f);
            arrowMat.SetFloat("_Glossiness", 0.7f);
            arrowMat.EnableKeyword("_EMISSION");
            arrowMat.SetColor("_EmissionColor", new Color(1f, 0.8f, 0.2f, 1f) * 0.3f);
            arrowHeadRenderer.material = arrowMat;
            
            DestroyImmediate(arrowHead.GetComponent<Collider>());
            
            GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
            cylinder.name = "Shaft";
            cylinder.transform.SetParent(arrow.transform);
            cylinder.transform.localPosition = new Vector3(0, 0.2f, 0);
            cylinder.transform.localRotation = Quaternion.identity;
            cylinder.transform.localScale = new Vector3(0.1f, 0.4f, 0.1f);
            
            MeshRenderer cylinderRenderer = cylinder.GetComponent<MeshRenderer>();
            cylinderRenderer.material = arrowMat;
            
            DestroyImmediate(cylinder.GetComponent<Collider>());
            
            for (int i = 0; i < 4; i++)
            {
                GameObject pillar = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                pillar.name = $"Pillar_{i}";
                pillar.transform.SetParent(visual.transform);
                
                float angle = i * 90f * Mathf.Deg2Rad;
                Vector3 offset = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * 0.6f;
                pillar.transform.localPosition = offset + new Vector3(0, 0.35f, 0);
                pillar.transform.localRotation = Quaternion.identity;
                pillar.transform.localScale = new Vector3(0.08f, 0.35f, 0.08f);
                
                MeshRenderer pillarRenderer = pillar.GetComponent<MeshRenderer>();
                Material pillarMat = new Material(Shader.Find("Standard"));
                pillarMat.color = new Color(0.3f, 0.8f, 1f, 1f);
                pillarMat.SetFloat("_Metallic", 0.6f);
                pillarMat.SetFloat("_Glossiness", 0.5f);
                pillarRenderer.material = pillarMat;
                
                DestroyImmediate(pillar.GetComponent<Collider>());
            }
            
            GameObject rotator = arrow;
            PlayerSpawnRotator rotatorComponent = rotator.AddComponent<PlayerSpawnRotator>();
        }

        public override void OnInspectorGUI()
        {
            PlayerSpawnReference spawnRef = (PlayerSpawnReference)target;

            EditorGUILayout.HelpBox(
                "This marks where the player will spawn when your level loads in Alterchase.\n\n" +
                "The game will find this marker and spawn the player at this position and rotation.\n\n" +
                "Note: You don't need the player prefab in your SDK project - the game handles spawning.",
                MessageType.Info
            );

            EditorGUILayout.Space(10);

            DrawDefaultInspector();

            EditorGUILayout.Space(10);

            EditorGUILayout.BeginVertical("box");
            EditorGUILayout.LabelField("Spawn Preview", EditorStyles.boldLabel);
            
            EditorGUI.BeginDisabledGroup(true);
            EditorGUILayout.Vector3Field("Spawn Position", spawnRef.SpawnPosition);
            EditorGUILayout.Vector3Field("Spawn Rotation", spawnRef.SpawnRotation.eulerAngles);
            EditorGUI.EndDisabledGroup();
            
            EditorGUILayout.EndVertical();

            EditorGUILayout.Space(5);

            EditorGUILayout.BeginHorizontal();
            
            if (GUILayout.Button("Align to Ground", GUILayout.Height(25)))
            {
                AlignToGround(spawnRef);
            }
            
            if (GUILayout.Button("Recreate Visual", GUILayout.Height(25)))
            {
                RecreateVisual(spawnRef);
            }
            
            EditorGUILayout.EndHorizontal();
        }

        private void AlignToGround(PlayerSpawnReference spawnRef)
        {
            RaycastHit hit;
            if (Physics.Raycast(spawnRef.transform.position + Vector3.up * 10f, Vector3.down, out hit, 20f))
            {
                Undo.RecordObject(spawnRef.transform, "Align Spawn to Ground");
                spawnRef.transform.position = hit.point;
                EditorUtility.SetDirty(spawnRef.transform);
            }
            else
            {
                EditorUtility.DisplayDialog("No Ground Found", "Could not find ground below the spawn point.", "OK");
            }
        }

        private void RecreateVisual(PlayerSpawnReference spawnRef)
        {
            Transform existingVisual = spawnRef.transform.Find("Visual (Editor Only)");
            if (existingVisual != null)
            {
                Undo.DestroyObjectImmediate(existingVisual.gameObject);
            }
            
            Undo.RegisterCompleteObjectUndo(spawnRef.gameObject, "Recreate Visual");
            CreateVisualMarker(spawnRef.gameObject);
            EditorUtility.SetDirty(spawnRef.gameObject);
        }
    }

    public class PlayerSpawnRotator : MonoBehaviour
    {
        private void Update()
        {
            transform.Rotate(Vector3.up, 30f * Time.deltaTime, Space.Self);
        }
    }
}
