using ET;
using System.Collections.Generic;
using UnityEngine;
using YooAsset;
namespace GFGGame
{
    public class DressUpLayerOperation : DressUpOperationBase
    {
        internal enum EAction
        {
            Layer,
            Body,
            Head
        }
        public const int PRE_RENDER_FRAME = 1;
        internal ItemCfg itemCfg;
        internal GameObject parentObj;
        private int layerId;
        private bool needSetMask;
        private bool showAni;
        private string resPath;
        private string effectResPath;
        private int preRendering;
        private ResourceDownloaderOperation downloaderOperation;
        internal EAction actionType;
        private string[] locationsLoading;
        public DressUpLayerOperation(GameObject parentObj, bool needSetMask, bool showAni, string resPath, string effectResPath)
        {
            this.parentObj = parentObj;
            this.needSetMask = needSetMask;
            this.resPath = resPath;
            this.effectResPath = effectResPath;
            this.showAni = showAni;
            preRendering = 0;
        }
        public void InitLayer(ItemCfg itemCfg, int layerId)
        {
            //LogUtil.LogEditor($"add InitLayer {itemCfg.id} layerId {layerId}");
            this.itemCfg = itemCfg;
            this.layerId = layerId;
            actionType = EAction.Layer;
        }
        public void InitBody()
        {
            //LogUtil.LogEditor("update InitBody");
            actionType = EAction.Body;
        }
        public void InitHead()
        {
            //LogUtil.LogEditor("update InitHead");
            actionType = EAction.Head;
        }
        internal override bool CheckRepeated(DressUpOperationBase t)
        {
            DressUpLayerOperation layerOperation = t as DressUpLayerOperation;
            if (layerOperation != null && layerOperation.actionType == this.actionType)
            {
                if(actionType == EAction.Layer)
                {
                    return (layerOperation.parentObj == this.parentObj
                        && layerOperation.itemCfg == this.itemCfg
                        && layerOperation.layerId == this.layerId);
                }
                else
                {
                    return true;
                }
            }
            if(this.actionType == EAction.Layer)
            {
                DressUpRemoveOperation removeOperation = t as DressUpRemoveOperation;
                if(removeOperation != null && this.itemCfg != null)
                {
                    if(removeOperation.itemID == this.itemCfg.id)
                    {
                        if(removeOperation.parentObj == this.parentObj)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        /// 
        /// 取消下载
        /// 
        internal override void Cancel()
        {
            if (_steps != EDressUpSteps.Done)
            {
                if (downloaderOperation != null)
                {
                    downloaderOperation.CancelDownload();
                }
                if(_steps == EDressUpSteps.PreDrawing)
                {
                    //取消预渲染
                    PrefabManager.Instance.CancelPreDraw(resPath);
                }
                _steps = EDressUpSteps.Done;
            }
            Status = EOperationStatus.Failed;
            Error = "User cancel.";
        }
        internal override void UpdateView()
        {
            if (parentObj == null)
            {
                this.Release();
                return;
            }
            ViewManager.Hide();
            switch (actionType)
            {
                case EAction.Layer:
                    UpdateLayer();
                    break;
                case EAction.Body:
                    UpdateBody();
                    break;
                case EAction.Head:
                    UpdateHead();
                    break;
                default:
                    break;
            }
        }
        internal override void Release()
        {
            downloaderOperation = null;
            this.itemCfg = null;
            this.parentObj = null;
            locationsLoading = null;
        }
        internal override void Start()
        {
            _steps = EDressUpSteps.Check;
            Update();
        }
        internal override void Update()
        {
            if (_steps == EDressUpSteps.None || _steps == EDressUpSteps.Done)
                return;
            if (_steps == EDressUpSteps.Check)
            {
                CheckLoadRes();
            }
            if(_steps == EDressUpSteps.Loading)
            {
                Progress = downloaderOperation.Progress;
                if(downloaderOperation.IsDone)
                {
                    if (downloaderOperation.Status == EOperationStatus.Succeed)
                    {
                        foreach (var t in locationsLoading)
                        {
                            LoadManager.Instance.SetResDownloaded(t);
                        }
                        CheckPreDraw();
                    }
                    else
                    {
                        _steps = EDressUpSteps.Done;
                        Status = EOperationStatus.Failed;
                    }
                }
            }
            if(_steps == EDressUpSteps.PreDrawing)
            {
                //LogUtil.LogEditor($"preRendering {preRendering}    {resPath} {TimeHelper.ClientNow()}");
                if (preRendering <= 0)
                {
                    _steps = EDressUpSteps.Done;
                    Status = EOperationStatus.Succeed;
                }
                preRendering--;
            }
        }
        private void CheckLoadRes()
        {
            List locations = new List();
            if(!string.IsNullOrEmpty(resPath) && !LoadManager.Instance.CheckResExsited(resPath))
            {
                //需加载
                locations.Add(this.resPath);
            }
            if(!string.IsNullOrEmpty(effectResPath) && !LoadManager.Instance.CheckResExsited(effectResPath))
            {
                //需加载
                locations.Add(effectResPath);
            }
            if(locations.Count == 0)
            {
                //文件已在本地,不需要下载
                CheckPreDraw();
                return;
            }
            locationsLoading = locations.ToArray();
            downloaderOperation = YooAssets.CreateBundleDownloader(locationsLoading, 3, 3);
            if(downloaderOperation.TotalDownloadCount == 0)
            {
                //文件已在本地,不需要下载
                CheckPreDraw();
                return;
            }
            ViewManager.Show("资源加载中,请耐心等待...");
            //下载
            _steps = EDressUpSteps.Loading;
            downloaderOperation.BeginDownload();
        }
        private void CheckPreDraw()
        {
            if(!string.IsNullOrEmpty(resPath))
            {
                if (showAni)
                {
                    _steps = EDressUpSteps.PreDrawing;
                    //设置预渲染帧数
                    preRendering = PRE_RENDER_FRAME;
                    //预渲染
                    PrefabManager.Instance.PreDraw(resPath);
                    //LogUtil.LogEditor($"PreDraw    {resPath} {TimeHelper.ClientNow()}");
                    return;
                }
            }
            _steps = EDressUpSteps.Done;
            Status = EOperationStatus.Succeed;
        }
        private void UpdateLayer()
        {
            //LogUtil.LogEditor($"add UpdateLayer {itemCfg.id} layerId {layerId}");
            int sortingOrder = ItemTypeCfgArray.Instance.GetSortingOrder(itemCfg.subType, layerId);
            //清理旧的
            var spritObjName = DressUpUtil.GetSpriteName(itemCfg, layerId);
            DressUpUtil.TryRemoveSprite(parentObj, spritObjName);
            var aniObjName = string.Format(DressUpUtil.FORMAT_ANIMATION_NAME, itemCfg.id, layerId);
            DressUpUtil.TryRemoveObj(parentObj, aniObjName);
            string effectObjName = string.Format(DressUpUtil.FORMAT_EFFECT_OBJ_NAME, itemCfg.id, layerId);
            DressUpUtil.TryRemoveObj(parentObj, effectObjName);
            //添加新的
            if(!string.IsNullOrEmpty(this.resPath))
            {
                if (this.showAni)
                {
                    DressUpUtil.AddAnimationObj(resPath, aniObjName, parentObj, sortingOrder);
                }
                else
                {
                    string ext = ItemUtil.GetItemResExt(itemCfg.itemType, itemCfg.subType);
                    DressUpUtil.AddSpriteObj(resPath, spritObjName, parentObj, sortingOrder, needSetMask);
                }
            }
            if (!string.IsNullOrEmpty(effectResPath))
            {
                DressUpUtil.TryAddEffectObj(effectResPath, effectObjName, parentObj, sortingOrder);
            }
        }
        private void UpdateBody()
        {
            //LogUtil.LogEditor("update UpdateBody");
            var spritObjName = DressUpUtil.BODY_SPRITE_NAME;
            var aniObjName = DressUpUtil.BODY_ANIMATION_NAME;
            var effectObjName = DressUpUtil.BODY_EFFECT_OBJ_NAME;
            int sortingOrder = 0;
            var removeBodyAni = DressUpUtil.TryRemoveObj(parentObj, aniObjName);
            DressUpUtil.TryRemoveObj(parentObj, effectObjName);
            DressUpUtil.TryRemoveSprite(parentObj, spritObjName);
            if(!string.IsNullOrEmpty(this.resPath))
            {
                if (this.showAni)
                {
                    DressUpUtil.AddAnimationObj(this.resPath, aniObjName, parentObj, sortingOrder);
                }
                else
                {
                    DressUpUtil.AddSpriteObj(this.resPath, spritObjName, parentObj, sortingOrder, needSetMask);
                    if (removeBodyAni)
                    {
                        parentObj.transform.localPosition = Vector3.zero;
                        parentObj.transform.localRotation = Quaternion.identity;
                    }
                }
            }
            if (!string.IsNullOrEmpty(effectResPath))
            {
                DressUpUtil.TryAddEffectObj(effectResPath, effectObjName, parentObj, sortingOrder);
            }
        }
        private void UpdateHead()
        {
            LogUtil.LogEditor("update UpdateHead");
            var spritObjName = DressUpUtil.HEAD_SPRITE_NAME; 
            int sortingOrder = 1;
            Transform transform_t = parentObj.transform.Find(spritObjName);
            if (!string.IsNullOrEmpty(this.resPath))
            {
                if (transform_t != null)
                {
                    transform_t.gameObject.SetActive(true);
                    return;
                }
                DressUpUtil.AddSpriteObj(resPath, spritObjName, parentObj, sortingOrder, needSetMask);
            }
            else
            {
                if (transform_t == null)
                {
                    return;
                }
                transform_t.gameObject.SetActive(false);
            }
        }
    }
}