using Cysharp.Threading.Tasks;
using LitJson;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;

public class CharacterRender : MonoBehaviour
{
    public GameObject gameObject;
    /// <summary>����</summary>
    public Material eyes001;
    /// <summary>����</summary>
    public Material eyes002;
    public Material[] faceMaterial;

    public SkinnedMeshRenderer faceSkinnedMeshRenderer;
    public string[] m_bsNameAll;

    public Dictionary<string, CharacterDressRender> dressRenders = new Dictionary<string, CharacterDressRender>();

    private List<int> shoesShow;

    private void Awake()
    {
        eyes001 = transform.Find("eyes001").GetComponent<Renderer>().material;
        eyes002 = transform.Find("eyes002").GetComponent<Renderer>().material;
        faceMaterial = transform.Find("body").GetComponent<Renderer>().materials;
        faceSkinnedMeshRenderer = transform.Find("body").GetComponent<SkinnedMeshRenderer>();
        shoesShow = JsonMapper.ToObject<List<int>>(Resources.Load<TextAsset>("ShoesShow").text);
        m_bsNameAll = new string[faceSkinnedMeshRenderer.sharedMesh.blendShapeCount];
        for (int j = 0; j < faceSkinnedMeshRenderer.sharedMesh.blendShapeCount; j++)
        {
            m_bsNameAll[j] = faceSkinnedMeshRenderer.sharedMesh.GetBlendShapeName(j);
        }
    }


    /// <summary>
    /// ���ع���
    /// </summary>
    /// <param name="go"></param>
    /// <param name="type"></param>
    private  async void LoadBones(GameObject obj)
    {
        obj.transform.SetParent(faceSkinnedMeshRenderer.transform.parent);
        Transform[] trans = obj.GetComponentsInChildren<Transform>();
        Transform[] transList = gameObject.transform.GetComponentsInChildren<Transform>();
        for (int i = 0; i < trans.Length; i++)
        {
            List<Transform> bones = new List<Transform>();
            var skmr = trans[i].GetComponent<SkinnedMeshRenderer>();

            if (skmr != null)
            {
                List<string> names = trans[i].GetComponent<BonesName>().bones;

                for (int j = 0; j < names.Count; j++)
                {
                    for (int k = 0; k < transList.Length; k++)
                    {
                        if (names[j] == transList[k].name)
                        {
                            bones.Add(transList[k]);
                            //Debug.Log(names[j]);
                        }

                        if (skmr.rootBone == null && trans[i].GetComponent<BonesName>().rootBones == transList[k].name)
                        {
                            skmr.rootBone = transList[k];
                        }
                    }
                }
                skmr.bones = bones.ToArray();
            }
        }
        await UniTask.DelayFrame(1);
    }
    public  async UniTask SetPlayerCloth( Good config)
    {
        //Debug.Log(config.id);
        List<string> crDis = new List<string>();
        string[] numbersArray = config.mutex.Split(',');
        int[] mutex = numbersArray.Select(int.Parse).ToArray();
        foreach (var item in dressRenders)
        {
            if (mutex.Contains(item.Value.good.id / 10000))
            {
                crDis.Add(item.Value.good.id.ToString());
            }
        }
        for (int i = 0; i < crDis.Count; i++)
        {
            dressRenders[crDis[i]].Dispose();
            dressRenders.Remove(crDis[i]);
        }
        var cdr = gameObject.AddComponent<CharacterDressRender>();
        GameObject obj = await CharacterManager.Inst.CreatNewDress<GameObject>(config, cdr);
      
        dressRenders.Add(config.id.ToString(), cdr);
        obj.SetActive(true);
        LoadBones(obj);

        bool isShowFoot = true;
        foreach (var item in dressRenders)
        {
            int type = item.Value.good.id / 10000;
            if (type == 17)
            {
                isShowFoot = false;
            }
            if(type == 12)
            {
                for (int i = 0;i < shoesShow.Count;i++)
                {
                    if(item.Value.good.id== shoesShow[i])
                    {
                        isShowFoot = false;
                    }
                }
            }
        }
        if (isShowFoot)
        {
            faceMaterial[6] = faceMaterial[5];
            transform.Find("body").GetComponent<Renderer>().materials = faceMaterial;
        }
        else
        {
            var mat = await YooAssetManager.Instance.LoadAsset<Material>("Body_T");
            faceMaterial[6] = mat;
            transform.Find("body").GetComponent<Renderer>().materials = faceMaterial;
        }
        bool isShowPaints = true;
        foreach (var item in dressRenders)
        {
            int type = item.Value.good.id / 10000;
            if (type == 17)
            {
                for (int i = 0; i < shoesShow.Count; i++)
                {
                    if (item.Value.good.id == shoesShow[i])
                    {
                        isShowPaints = false;
                    }
                }
            }
            if (type == 11)
            {
                for (int i = 0; i < shoesShow.Count; i++)
                {
                    if (item.Value.good.id == shoesShow[i])
                    {
                        isShowPaints = false;
                    }
                }
            }
        }
        if (isShowPaints)
        {
            faceMaterial[4] = faceMaterial[5];
            transform.Find("body").GetComponent<Renderer>().materials = faceMaterial;
        }
        else
        {
            var mat = await YooAssetManager.Instance.LoadAsset<Material>("Body_T");
            faceMaterial[4] = mat;
            transform.Find("body").GetComponent<Renderer>().materials = faceMaterial;
        }

        //if (CharacterManager.Inst.selfRender == self)
        //{
        //    //UI
        //    var renderer = self.gameObject.GetComponentsInChildren<Renderer>();
        //    foreach (var item in renderer)
        //    {
        //        item.renderingLayerMask = 1 << 1;
        //        item.gameObject.layer = 10;
        //    }
        //}
        //else
        //{
        //    //�������
        //    var renderer = self.gameObject.GetComponentsInChildren<Renderer>();
        //    foreach (var item in renderer)
        //    {
        //        item.renderingLayerMask = 1 << 0;
        //        item.gameObject.layer = 0;
        //    }
        //}
    }
    public  async UniTask SetPlayerBlendShape(Good config)
    {
        List<string> crDis = new List<string>();
        string[] numbersArray = config.mutex.Split(',');
        int[] mutex = numbersArray.Select(int.Parse).ToArray();
        foreach (var item in dressRenders)
        {
            if (mutex.Contains(item.Value.good.id / 10000))
            {
                crDis.Add(item.Value.good.id.ToString());
            }
        }
        for (int i = 0; i < crDis.Count; i++)
        {
           dressRenders[crDis[i]].Dispose();
           dressRenders.Remove(crDis[i]);
        }
        int type = config.id / 10000;
        var cdr = gameObject.AddComponent<CharacterDressRender>();
        cdr.good = config;
        cdr.gameObject = config.assetsName;
        if (dressRenders.ContainsKey(config.id.ToString()))
        {
            dressRenders[config.id.ToString()] = cdr;
        }
        else
        {
            dressRenders.Add(config.id.ToString(), cdr);
        }
        await UniTask.DelayFrame(1);
        //����blendshape
        Dictionary<string, int> param = LitJson.JsonMapper.ToObject<Dictionary<string, int>>(config.assetsName);
        foreach (var item in param)
        {
            for (int i = 0; i < m_bsNameAll.Length; i++)
            {
                if (m_bsNameAll[i].Contains(item.Key))
                {
                    faceSkinnedMeshRenderer.SetBlendShapeWeight(i, item.Value * 100);
                }
            }
        }
    }
    public  async UniTask SetTextrue(Good config)
    {
        List<string> crDis = new List<string>();
        string[] numbersArray = config.mutex.Split(',');
        int[] mutex = numbersArray.Select(int.Parse).ToArray();
        foreach (var item in dressRenders)
        {
            if (mutex.Contains(item.Value.good.id / 10000))
            {
                crDis.Add(item.Value.good.id.ToString());
            }
        }
        for (int i = 0; i < crDis.Count; i++)
        {
           dressRenders[crDis[i]].Dispose();
            dressRenders.Remove(crDis[i]);
        }
        int type = config.id / 10000;
        var cdr = gameObject.AddComponent<CharacterDressRender>();
        var obj = await CharacterManager.Inst.CreatNewDress<Texture>(config, cdr);
        if (dressRenders.ContainsKey(config.id.ToString()))
        {
            dressRenders[config.id.ToString()] = cdr;
        }
        else
        {
            dressRenders.Add(config.id.ToString(), cdr);
        }
        await UniTask.DelayFrame(1);
        if (type == 1)//Ƥ��
        {
            for (int i = 0;i < faceMaterial.Length;i++) { faceMaterial[i].SetTexture("_Skin", obj); }
        }
        if (type == 4)//üë
        {
            //faceMaterial.SetTexture("_EyesBrow", obj);
            for (int i = 0; i < faceMaterial.Length; i++) { faceMaterial[i].SetTexture("_EyesBrow", obj); }
        }
        if (type == 9)//���/����
        {
            //faceMaterial.SetTexture("_Beard", obj);
            for (int i = 0; i < faceMaterial.Length; i++) { faceMaterial[i].SetTexture("_Beard", obj); }
        }
        if (type == 15)//����
        {
            //faceMaterial.SetTexture("_Tattoo", obj);
            for (int i = 0; i < faceMaterial.Length; i++) { faceMaterial[i].SetTexture("_Tattoo", obj); }
        }
    }
    public  async UniTask SetEyeTextrue(Good config)
    {
        List<string> crDis = new List<string>();
        string[] numbersArray = config.mutex.Split(',');
        int[] mutex = numbersArray.Select(int.Parse).ToArray();
        foreach (var item in dressRenders)
        {
            if (mutex.Contains(item.Value.good.id / 10000))
            {
                crDis.Add(item.Value.good.id.ToString());
            }
        }
        for (int i = 0; i < crDis.Count; i++)
        {
            dressRenders[crDis[i]].Dispose();
            dressRenders.Remove(crDis[i]);
        }
        int type = config.id / 10000;
        var cdr = gameObject.AddComponent<CharacterDressRender>();
        var objL = await CharacterManager.Inst.CreatNewDress<Texture>(config, cdr, "L");
        var objR = await CharacterManager.Inst.CreatNewDress<Texture>(config, cdr, "R");
        if (dressRenders.ContainsKey(config.id.ToString()))
        {
            dressRenders[config.id.ToString()] = cdr;
        }
        else
        {
            dressRenders.Add(config.id.ToString(), cdr);
        }
        await UniTask.DelayFrame(1);
        eyes001.SetTexture("_BaseMap", objL);
        eyes002.SetTexture("_BaseMap", objR);

    }
    public  void DestoryEquip()
    {
        foreach (var item in dressRenders)
        {
            item.Value.Dispose();
        }
        dressRenders.Clear();
    }
    public  void UnLoadEquip( Good config)
    {
        string dressRender = "";
        foreach (var item in dressRenders)
        {
            if (item.Value.good.id == config.id)
            {
                dressRender = item.Key;
            }
        }
        if (!string.IsNullOrEmpty(dressRender))
        {
            dressRenders[dressRender].Dispose();
            dressRenders.Remove(dressRender);
        }
    }

}