using System;
using UnityEditor;
using UnityEngine;
using Newtonsoft.Json;
using System.Collections.Generic;
using Object = UnityEngine.Object;

namespace LLM.Editor.Helper
{
    public static class UnityTypeConverters
    {
        public static readonly List<JsonConverter> Converters = new()
        {
            new ObjectConverter(),
            new Vector3Converter(),
            new QuaternionConverter(),
            new ColorConverter(),
            new Vector2Converter(),
            new Vector4Converter(),
            new RectConverter(),
            new AnimationCurveConverter(),
            new BoundsConverter(),
            new Vector2IntConverter(),
            new Vector3IntConverter(),
            new RectIntConverter(),
            new BoundsIntConverter()
        };
        
        private class ObjectConverter : JsonConverter<Object>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Object value, JsonSerializer serializer)
            {
                if (value == null)
                {
                    writer.WriteNull();
                    return;
                }

                writer.WriteStartObject();
                writer.WritePropertyName("name");
                writer.WriteValue(value.name);
                writer.WritePropertyName("instanceId");
                writer.WriteValue(value.GetInstanceID());
                writer.WritePropertyName("type");
                writer.WriteValue(value.GetType().FullName);

                if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(value, out var guid, out long _))
                {
                    if (!string.IsNullOrEmpty(guid) && guid != "00000000000000000000000000000000")
                    {
                        writer.WritePropertyName("guid");
                        writer.WriteValue(guid);
                    }
                }
                writer.WriteEndObject();
            }

            public override Object ReadJson(JsonReader reader, Type objectType, Object existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }
        
        private class Vector3Converter : JsonConverter<Vector3>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Vector3 value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("x");
                writer.WriteValue(value.x);
                writer.WritePropertyName("y");
                writer.WriteValue(value.y);
                writer.WritePropertyName("z");
                writer.WriteValue(value.z);
                writer.WriteEndObject();
            }

            public override Vector3 ReadJson(JsonReader reader, Type objectType, Vector3 existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }
    
        private class QuaternionConverter : JsonConverter<Quaternion>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Quaternion value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("x");
                writer.WriteValue(value.x);
                writer.WritePropertyName("y");
                writer.WriteValue(value.y);
                writer.WritePropertyName("z");
                writer.WriteValue(value.z);
                writer.WritePropertyName("w");
                writer.WriteValue(value.w);
                writer.WriteEndObject();
            }

            public override Quaternion ReadJson(JsonReader reader, Type objectType, Quaternion existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        private class ColorConverter : JsonConverter<Color>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Color value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("r");
                writer.WriteValue(value.r);
                writer.WritePropertyName("g");
                writer.WriteValue(value.g);
                writer.WritePropertyName("b");
                writer.WriteValue(value.b);
                writer.WritePropertyName("a");
                writer.WriteValue(value.a);
                writer.WriteEndObject();
            }

            public override Color ReadJson(JsonReader reader, Type objectType, Color existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        private class Vector2Converter : JsonConverter<Vector2>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Vector2 value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("x");
                writer.WriteValue(value.x);
                writer.WritePropertyName("y");
                writer.WriteValue(value.y);
                writer.WriteEndObject();
            }

            public override Vector2 ReadJson(JsonReader reader, Type objectType, Vector2 existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        private class Vector4Converter : JsonConverter<Vector4>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Vector4 value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("x");
                writer.WriteValue(value.x);
                writer.WritePropertyName("y");
                writer.WriteValue(value.y);
                writer.WritePropertyName("z");
                writer.WriteValue(value.z);
                writer.WritePropertyName("w");
                writer.WriteValue(value.w);
                writer.WriteEndObject();
            }

            public override Vector4 ReadJson(JsonReader reader, Type objectType, Vector4 existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        private class RectConverter : JsonConverter<Rect>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Rect value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("x");
                writer.WriteValue(value.x);
                writer.WritePropertyName("y");
                writer.WriteValue(value.y);
                writer.WritePropertyName("width");
                writer.WriteValue(value.width);
                writer.WritePropertyName("height");
                writer.WriteValue(value.height);
                writer.WriteEndObject();
            }

            public override Rect ReadJson(JsonReader reader, Type objectType, Rect existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        private class AnimationCurveConverter : JsonConverter<AnimationCurve>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, AnimationCurve value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("keys");
                serializer.Serialize(writer, value.keys);
                writer.WritePropertyName("preWrapMode");
                writer.WriteValue(value.preWrapMode.ToString());
                writer.WritePropertyName("postWrapMode");
                writer.WriteValue(value.postWrapMode.ToString());
                writer.WriteEndObject();
            }

            public override AnimationCurve ReadJson(JsonReader reader, Type objectType, AnimationCurve existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        private class BoundsConverter : JsonConverter<Bounds>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Bounds value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("center");
                serializer.Serialize(writer, value.center);
                writer.WritePropertyName("size");
                serializer.Serialize(writer, value.size);
                writer.WriteEndObject();
            }

            public override Bounds ReadJson(JsonReader reader, Type objectType, Bounds existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        private class Vector2IntConverter : JsonConverter<Vector2Int>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Vector2Int value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("x");
                writer.WriteValue(value.x);
                writer.WritePropertyName("y");
                writer.WriteValue(value.y);
                writer.WriteEndObject();
            }

            public override Vector2Int ReadJson(JsonReader reader, Type objectType, Vector2Int existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        private class Vector3IntConverter : JsonConverter<Vector3Int>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Vector3Int value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("x");
                writer.WriteValue(value.x);
                writer.WritePropertyName("y");
                writer.WriteValue(value.y);
                writer.WritePropertyName("z");
                writer.WriteValue(value.z);
                writer.WriteEndObject();
            }

            public override Vector3Int ReadJson(JsonReader reader, Type objectType, Vector3Int existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        private class RectIntConverter : JsonConverter<RectInt>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, RectInt value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("x");
                writer.WriteValue(value.x);
                writer.WritePropertyName("y");
                writer.WriteValue(value.y);
                writer.WritePropertyName("width");
                writer.WriteValue(value.width);
                writer.WritePropertyName("height");
                writer.WriteValue(value.height);
                writer.WriteEndObject();
            }

            public override RectInt ReadJson(JsonReader reader, Type objectType, RectInt existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }

        private class BoundsIntConverter : JsonConverter<BoundsInt>
        {
            public override void WriteJson(Newtonsoft.Json.JsonWriter writer, BoundsInt value, JsonSerializer serializer)
            {
                writer.WriteStartObject();
                writer.WritePropertyName("position");
                serializer.Serialize(writer, value.position);
                writer.WritePropertyName("size");
                serializer.Serialize(writer, value.size);
                writer.WriteEndObject();
            }

            public override BoundsInt ReadJson(JsonReader reader, Type objectType, BoundsInt existingValue, bool hasExistingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }
    }
}