using Microsoft.AspNetCore.Http;

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace CloudGaming.Code.AppExtend.JsonConverHelper
{
    public class LanguageContractResolver(IServiceCollection serviceProvider) : CamelCasePropertyNamesContractResolver
    {

        //public LanguageContractResolver
        //{
        //    //_httpContextAccessor = httpContextAccessor;
        //    //CloudGamingBase cloudGamingBase = new CloudGamingBase(serviceProvider);
        //    //var x = cloudGamingBase.AppConfig;
        //}


        protected override IValueProvider CreateMemberValueProvider(MemberInfo member)
        {
            if (DynamicCodeGeneration)
            {
                if (member.MemberType == MemberTypes.Property)
                {
                    Type propType = ((PropertyInfo)member).PropertyType;

                }
            }
            return base.CreateMemberValueProvider(member);
        }

        protected override JsonStringContract CreateStringContract(Type objectType)
        {
            return base.CreateStringContract(objectType);
        }

        protected override string ResolvePropertyName(string propertyName)
        {
            return base.ResolvePropertyName(propertyName);
        }


        private readonly Stack<string> _propertyPathStack = new Stack<string>();

        public string CurrentPath => string.Join(".", _propertyPathStack);
        //protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        protected override JsonProperty CreateProperty(System.Reflection.MemberInfo member, MemberSerialization memberSerialization)
        {



            //JsonPropertyAttribute? propertyAttribute = JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(member);


            var property = base.CreateProperty(member, memberSerialization);

            var originalWriteJson = property.ValueProvider;
            property.ValueProvider = new PathTrackingValueProvider(originalWriteJson, property.PropertyName, this);

            return property;
        }

        private class PathTrackingValueProvider : IValueProvider
        {
            private readonly IValueProvider _innerValueProvider;
            private readonly string _propertyName;
            private readonly LanguageContractResolver _resolver;

            public PathTrackingValueProvider(IValueProvider innerValueProvider, string propertyName, LanguageContractResolver resolver)
            {
                _innerValueProvider = innerValueProvider;
                _propertyName = propertyName;
                _resolver = resolver;
            }

            public object GetValue(object target)
            {
                _resolver._propertyPathStack.Push(_propertyName);
                var value = _innerValueProvider.GetValue(target);

                if (value is IEnumerable collection && !(value is string))
                {
                    int index = 0;
                    foreach (var item in collection)
                    {
                        _resolver._propertyPathStack.Push($"[{index}]");
                        // 递归处理集合中的每个元素
                        ProcessValue(item, _resolver);
                        _resolver._propertyPathStack.Pop();
                        index++;
                    }
                }
                else if (value is not null && !(value is string) && !value.GetType().IsPrimitive)
                {
                    // 递归处理嵌套的对象
                    ProcessValue(value, _resolver);
                }
                else
                {
                    // 处理基本类型（如字符串、整数等）
                    Console.WriteLine($"Serializing property path: {_resolver.CurrentPath}");
                }

                _resolver._propertyPathStack.Pop();
                return value;
            }

            public void SetValue(object target, object value)
            {
                _innerValueProvider.SetValue(target, value);
            }

            private void ProcessValue(object value, LanguageContractResolver resolver)
            {
                var contract = resolver.ResolveContract(value.GetType());
                if (contract is JsonObjectContract objectContract)
                {
                    foreach (var property in objectContract.Properties)
                    {
                        var provider = property.ValueProvider;
                        var propertyValue = provider?.GetValue(value);
                        if (propertyValue != null)
                        {
                            resolver._propertyPathStack.Push(property.PropertyName);
                            Console.WriteLine($"Serializing property path: {resolver.CurrentPath}");
                            resolver._propertyPathStack.Pop();
                        }
                    }
                }
            }
        }


    }
}
