using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using XRTool.Util;

namespace PublicTools.XMLDataBase
{
    /// <summary>
    /// 类的解析，主要做两件事，拆包/封包
    /// 拆包：将类的成员变量拆成Dictionary
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public static class ClazzFactory
    {
        /// <summary>
        /// 给定一个成员变量，获取bi
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static string GetPriKey<T>(T t, string priKey)
        {
            if (t == null)
            {
                UnityLog.LogError(typeof(T) + " is null" + priKey);
            }
            if (string.IsNullOrEmpty(priKey))
            {
                UnityLog.LogError(typeof(T) + "prikey is null:" + priKey);
            }
            var fields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance);
            UnityEngine.Debug.Log("priKey===>"+ priKey);
            if (fields == null || fields.Length < 1)
            {
                priKey=JsonConvert.SerializeObject(t.GetType().GetProperty(priKey).GetValue(t, null)).Replace("\"", "");
            }
            else
            {
                priKey = JsonConvert.SerializeObject(t.GetType().GetField(priKey).GetValue(t)).Replace("\"", "");
            }
            return priKey;
        }
        /// <summary>
        /// 拆包
        /// 使用反射和Json解析对象
        /// 默认解析公共成员变量（属性）
        /// 当不存在公共成员变量时，解析公共方法
        /// 二者只能存一
        /// 不解析Dictionary类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static Dictionary<string, string> ClazzAnalyze<T>(T t)
        {
            Dictionary<string, string> field = new Dictionary<string, string>();
            if (t == null)
            {
                t = default(T);
            }
            if (t != null)
            {
                ///解析成员变量
                var fields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance);
                bool isHas = false;
                ///存在成员变量时
                if (fields != null && fields.Length > 0)
                {
                    for (int i = 0; i < fields.Length; i++)
                    {
                        if (fields[i].FieldType.ToString().Contains("Dictionary"))
                        {
                            continue;
                        }
                        string value = "";
                        string key = fields[i].Name;
                        try
                        {
                            value = JsonConvert.SerializeObject(t.GetType().GetField(key).GetValue(t)).Replace("\"", "");
                        }
                        catch (Exception ex)
                        {
                            ///解包错误，无法解析类型
                            Debug.LogError(ex.ToString() + typeof(T).Name + "--" + fields[i].Name + " is error value");
                        }
                        field.Add(key, value);
                        isHas = true;
                    }
                }
                if (!isHas)
                {
                    ///不存在成员变量，检测公共赋值方法
                    var property = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
                    if (property != null && property.Length > 0)
                    {
                        for (int i = 0; i < property.Length; i++)
                        {
                            if (property[i].PropertyType.ToString().Contains("Dictionary"))
                            {
                                continue;
                            }
                            string value = "";
                            string key = property[i].Name;
                            try
                            {
                                value = JsonConvert.SerializeObject(t.GetType().GetProperty(key).GetValue(t, null)).Replace("\"", "");
                            }
                            catch (Exception ex)
                            {
                                ///解包错误，无法解析类型
                                Debug.LogError(ex.ToString() + typeof(T).Name + "--" + property[i].Name + " is error value");
                            }
                            //Debug.Log(key + value);
                            field.Add(key, value);
                        }
                    }
                }
            }
            else
            {
                UnityLog.LogError(typeof(T).Name + " is null");
            }
            return field;
        }
        /// <summary>
        /// 封包
        /// 使用反射和json封装对象
        /// 默认赋值公共成员变量，属性
        /// 当不存在可用的成员变量时，赋值公共方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="field"></param>
        /// <returns></returns>
        public static T ClazzPack<T>(Dictionary<string, string> field)
        {
            T t = (T)(Assembly.GetExecutingAssembly().CreateInstance(typeof(T).Namespace + "." + typeof(T).Name));
            var fields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance);
            bool isHas = false;
            ///存在成员变量时
            if (fields != null && fields.Length > 0)
            {
                for (int i = 0; i < fields.Length; i++)
                {
                    if (field.ContainsKey(fields[i].Name))
                    {
                        object tempArr;
                        try
                        {
                            if (field.ContainsKey(fields[i].Name))
                            {
                                string value = field[fields[i].Name];
                                ///Json对象
                                if (value.StartsWith("{") && value.EndsWith("}"))
                                {
                                    string realValue = "{";

                                    string nullFlag = value.Replace("{", "").Replace("}", "");
                                    string[] arr = nullFlag.Split(',');
                                    for (int j = 0; j < arr.Length; j++)
                                    {
                                        string[] tmpaar = arr[j].Split(':');
                                        string shuxing = tmpaar[0];
                                        shuxing = "\"" + shuxing + "\"";
                                        realValue += shuxing + ":" + tmpaar[1];
                                        if (j < arr.Length - 1)
                                        {
                                            realValue += ",";
                                        }
                                    }
                                    value = realValue + "}";
                                }
                                else if (value.StartsWith("[") && value.EndsWith("]"))
                                {
                                    string realValue = "[";

                                    string nullFlag = value.Replace("[", "").Replace("]", "");
                                    string[] arr = nullFlag.Split(',');
                                    for (int j = 0; j < arr.Length; j++)
                                    {
                                        realValue += "\"" + arr[j] + "\"";
                                        if (j < arr.Length - 1)
                                        {
                                            realValue += ",";
                                        }
                                    }
                                    value = realValue + "]";
                                }
                                else
                                {
                                    if (!value.StartsWith("\"") && !value.EndsWith("\""))
                                    {
                                        value = "\"" + value + "\"";
                                    }
                                }
                                //UnityLog.Log(value);
                                if (value == "null")
                                {
                                    tempArr = null;
                                }
                                else
                                {
                                    tempArr = JsonConvert.DeserializeObject(value, fields[i].FieldType);// StringToArr(property[i].PropertyType, field[property[i].Name].Split(new char[] { '|' }));
                                }
                                fields[i].SetValue(t, tempArr);
                                isHas = true;
                            }
                            else
                            {
                                UnityLog.LogError(fields[i].Name + " is null!");
                            }
                        }
                        catch (Exception ex)
                        {
                            ///装包失败，打印出具体的错误信息
                            UnityLog.LogError(ex.ToString() + typeof(T).Name + "--" + fields[i].Name + field[fields[i].Name] + " is error value");
                        }
                    }
                }
            }
            if (!isHas)
            {
                ///无有效的成员变量，开始解析赋值公共方法
                PropertyInfo[] property = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);
                for (int i = 0; i < property.Length; i++)
                {
                    if (field.ContainsKey(property[i].Name))
                    {
                        object tempArr;
                        try
                        {
                            if (field.ContainsKey(property[i].Name))
                            {
                                string value = field[property[i].Name];
                                ///Json对象
                                if (value.StartsWith("{") && value.EndsWith("}"))
                                {
                                    string realValue = "{";

                                    string nullFlag = value.Replace("{", "").Replace("}", "");
                                    string[] arr = nullFlag.Split(',');
                                    for (int j = 0; j < arr.Length; j++)
                                    {
                                        string[] tmpaar = arr[j].Split(':');
                                        string shuxing = tmpaar[0];
                                        shuxing = "\"" + shuxing + "\"";
                                        realValue += shuxing + ":" + tmpaar[1];
                                        if (j < arr.Length - 1)
                                        {
                                            realValue += ",";
                                        }
                                    }
                                    value = realValue + "}";
                                }
                                else
                                {
                                    if (!value.StartsWith("\"") && !value.EndsWith("\""))
                                    {
                                        value = "\"" + value + "\"";
                                    }
                                }
                                //UnityLog.Log(value);
                                if (value == "null")
                                {
                                    tempArr = null;
                                }
                                else
                                {
                                    tempArr = JsonConvert.DeserializeObject(value, property[i].PropertyType);// StringToArr(property[i].PropertyType, field[property[i].Name].Split(new char[] { '|' }));
                                }
                                property[i].SetValue(t, tempArr, null);
                            }
                            else
                            {
                                UnityLog.LogError(property[i].Name + " is null!");
                            }
                        }
                        catch (Exception ex)
                        {
                            ///装包失败，打印出具体的错误信息
                            UnityLog.LogError(ex.ToString() + typeof(T).Name + "--" + property[i].Name + " is error value");
                        }
                    }
                }
            }
            return t;
        }
    }
}