using Sirenix.Utilities.Editor;
using System;
using UnityEngine;
using Sirenix.OdinInspector.Editor;
using Sirenix.OdinInspector;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using Thousandto.Package;

namespace Thousandto.DaleSpeace
{
    public class PackRes : EditorWindow
    {
        #region //Title Time and Message
        [DetailedInfoBox("----点击查看使用详情----", "Multilingual : 多语言资源 需要选择要打包的语言 选中后出现多语言选择 默认是CH           " +
         "  Corresponding : 通用资源 不需要选择要打包的语言 勾选即视为要打包       Special  : 特殊的资源打包  ")]
        [ShowInInspector, DisplayAsString, PropertyOrder(-1)]
        public string CurrentTime
        {
            get
            {
                GUIHelper.RequestRepaint();
                return DateTime.Now.ToString();
            }
        }

        #endregion

        #region // 选择打包语言

        [BoxGroup("选择要打包的语言", true, false, 200)]
        [Space]
        [PropertyTooltip("是否是多语言")]
        public bool IsMultilingual = false;

        [BoxGroup("选择要打包的语言", true, false, 200)]
        [EnumToggleButtons, HideLabel]
        [Space]
        [HideIf("IsMultilingual")]
        public LanType lantype_ = LanType.CH;

        [BoxGroup("选择要打包的语言", true, false, 200)]
        [Space]
        [HorizontalGroup("选择要打包的语言/F")]
        [ShowIf("IsMultilingual")]
        public bool CH = false;

        [BoxGroup("选择要打包的语言", true, false, 200)]
        [HorizontalGroup("选择要打包的语言/F")]
        [Space]
        [ShowIf("IsMultilingual")]
        public bool TW = false;

        [BoxGroup("选择要打包的语言", true, false, 200)]
        [ShowIf("IsMultilingual")]
        [HorizontalGroup("选择要打包的语言/S")]
        public bool EN = false;

        [BoxGroup("选择要打包的语言", true, false, 200)]
        [ShowIf("IsMultilingual")]
        [HorizontalGroup("选择要打包的语言/S")]
        public bool TH = false;

        [BoxGroup("选择要打包的语言", true, false, 200)]
        [ShowIf("IsMultilingual")]
        [HorizontalGroup("选择要打包的语言/T")]
        public bool VIE = false;

        [BoxGroup("选择要打包的语言", true, false, 200)]
        [ShowIf("IsMultilingual")]
        [HorizontalGroup("选择要打包的语言/T")]
        public bool JP = false;

        [BoxGroup("选择要打包的语言", true, false, 200)]
        [ShowIf("IsMultilingual")]
        [HorizontalGroup("选择要打包的语言/Four")]
        public bool KR = false;

        #endregion

        #region // 资源列表
        [FoldoutGroup("所有游戏资源", 201)]
        [PropertyTooltip("打包游戏窗体.")]
        //[HorizontalGroup("Multilingual/HorizontalGameUI")]
        public bool PackageGameUI = false;

        //[HideLabel]
        //[ShowIf("PackageGameUI")]
        //[HorizontalGroup("Multilingual/HorizontalGameUI")]
        //[BoxGroup("Multilingual", true, false, 201)]
        //public LanType GameUILanType = LanType.CH;

        //======================GameUI===========================================//


        //[HorizontalGroup("Multilingual/HorizontalTexture")]
        [PropertyTooltip("打包Texture.")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageTexture = false;

        //[HideLabel]
        //[ShowIf("PackageTexture")]
        //[HorizontalGroup("Multilingual/HorizontalTexture")]
        //[BoxGroup("Multilingual", true, false, 201)]
        //public LanType TextureLanType = LanType.CH;

        //======================Texture===========================================//



        //[HorizontalGroup("Multilingual/HorizontalVFXTexture")]
        [PropertyTooltip("打包特效贴图.")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageVFXTexture = false;

        //[HideLabel]
        //[ShowIf("PackageVFXTexture")]
        //[HorizontalGroup("Multilingual/HorizontalVFXTexture")]
        //[BoxGroup("Multilingual", true, false, 201)]
        //public LanType VFXTextureLanType = LanType.CH;

        //======================VFXTexture===========================================//



        //[HorizontalGroup("Multilingual/HorizontalAtlasFont")]
        [PropertyTooltip("打包图集和字体.")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageAtlasFont = false;

        //[HideLabel]
        //[ShowIf("PackageAtlasFont")]
        //[HorizontalGroup("Multilingual/HorizontalAtlasFont")]
        //[BoxGroup("Multilingual", true, false, 201)]
        //public LanType AtlasFontLanType = LanType.CH;

        //======================VFXTexture===========================================//


        [PropertyTooltip("打包lua.")]
        //[HorizontalGroup("Multilingual/HorizontalLua")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageLua = false;

        //[HideLabel]
        //[ShowIf("PackageLua")]
        //[HorizontalGroup("Multilingual/HorizontalLua")]
        //[BoxGroup("Multilingual", true, false, 201)]
        //public LanType LuaLanType = LanType.CH;

        //======================VFXTexture===========================================//


        //[HorizontalGroup("Multilingual/HorizontalConfiguration")]
        [PropertyTooltip("打包配置文件")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageConfiguration = false;

        //[HideLabel]
        //[ShowIf("PackageConfiguration")]
        //[HorizontalGroup("Multilingual/HorizontalConfiguration")]
        //[BoxGroup("Multilingual", true, false, 201)]
        //public LanType ConfigurationLanType = LanType.CH;

        //======================Configuration===========================================//

        [PropertyTooltip("打包游戏场景")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageSence = false;

        [PropertyTooltip("打包默认场景")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageDefaultSence = false;

        [PropertyTooltip("打包TimeLine")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageTimeLine = false;

        [PropertyTooltip("打包玩家模型")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageModel = false;

        [PropertyTooltip("打包Shader")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageShader = false;

        [PropertyTooltip("打包游戏特效")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackageVFX = false;

        [PropertyTooltip("打包玩家动作")]
        [FoldoutGroup("所有游戏资源", 201)]
        public bool PackagePlayerAnimClip = false;

        #endregion

        #region // 打包按钮
    


        [BoxGroup("选择打包方式", true, false, 203)]
        [HorizontalGroup("选择打包方式/PackagePartRes")]
        [Button("打包选中资源", 30)]
        private void PackageChooseResClick()
        {
            Package(GetCurSelectLan());
        }

        [BoxGroup("选择打包方式", true, false, 203)]
        [HorizontalGroup("选择打包方式/PackagePartRes")]
        [Button("打包文件列表资源", 30)]
        private void PackageFileListClick()
        {
            string path = EditorUtility.OpenFilePanel("打开包含资源列表的文本文件", "", "txt");
            PackageFromTextFile(GetCurSelectLan(), path);
        }
        
        [BoxGroup("选择打包方式", true, false, 203)]
        [GUIColor(0.3f, 0.6f, 0.4f)]
        [HorizontalGroup("选择打包方式/PackagePartRes")]
        [Button("打包所有资源(不含动态库)",30)]
        private void PackageAllResClick()
        {
            Debug.Log("打包所有资源    " + GetCurSelectLan());
            Thousandto.Package.Tool.PackageOption.OnlyPackageResource(GetCurSelectLan());
            Thousandto.Package.UI.PackageWindow.Open();
        }

        [BoxGroup("选择打包方式", true, false, 203)]
        [PropertySpace(SpaceBefore = 10, SpaceAfter = 10)]
        [Button("打包以上选择的资源" , 40)]
        [GUIColor(1f, 0.8f, 0f)]
        [PropertyOrder(299)]
        private void PackageClick()
        {
            Thousandto.Package.Tool.PackageLocker.CloseLockFile(true);
            PackageManager.Reset();
            PackageManager.SetLanguage(GetCurSelectLan());

            if (PackageGameUI)
            {
                PackageManager.AddResource<NewGameUI>();
            }

            if (PackageGameUI == false && PackageAtlasFont)
            {
                var inst = new NewGameUI(false);
                inst.AddAllAtlas();
                inst.AddAllFont();
                PackageManager.AddResource(inst);
            }

            if (PackageTexture)
            {
                PackageManager.AddResource<Package.Texture>();
            }

            if (PackageVFX)
            {
                PackageManager.AddResource<VFX>();
            }

            if (PackageVFXTexture)
            {
                PackageManager.AddResource<VFXTexture>();
            }

            if (PackageTimeLine)
            {
                PackageManager.AddResource<TimeLine>();
            }

            if (PackageShader)
            {
                PackageManager.AddResource<ShaderPackage>();
            }

            if (PackageSence)
            {
                PackageManager.AddResource<Scene>();
            }

            if (PackageDefaultSence)
            {
                PackageManager.AddResource<SceneDefault>();
            }

            if (PackagePlayerAnimClip)
            {
                PackageManager.AddResource<PlayerAnimClip>();
            }

            if (PackageModel)
            {
                PackageManager.AddResource<Prefab>();
            }

            if (PackageLua)
            {
                LuaToZip.BetterLua(GetCurSelectLan());
            }

            if (PackageConfiguration)
            {
                DefaultAndConfigFiles.StartBuild();
            }

            PackageManager.Start();


        }

        #endregion

        #region //功能函数
        //打包选中资源
        private static void Package(string lan)
        {
            List<string> resFileList = new List<string>();
            UnityEngine.Object[] objs = Selection.objects;
            for (int i = 0; objs != null && i < objs.Length; ++i)
            {
                UnityEngine.Object obj = objs[i];
                string path = AssetDatabase.GetAssetOrScenePath(obj);
                UnityEngine.Debug.LogError(path);
                if (Directory.Exists(path))
                {
                    var files = Utils.GetFiles(path, "*.*", SearchOption.AllDirectories, PkgConstDefine.CommonExceptionEx);
                    foreach (string file in files)
                    {
                        if (!file.EndsWith(".meta"))
                        {
                            resFileList.Add(file);
                        }
                        UnityEngine.Debug.LogError(file);
                    }
                }
                else
                {
                    resFileList.Add(path);
                }
            }
            DoPackageFileList(lan, resFileList, false);
        }

        //对资源文件进行打包
        private static void DoPackageFileList(string lan, List<string> resFileList, bool isAll)
        {
            Thousandto.Package.Tool.PackageLocker.CloseLockFile(true);
            PackageManager.Reset();
            PackageManager.SetLanguage(lan);

            List<string> defaultFiles = new List<string>();
            var newUIList = new List<string>();
            var newAnimList = new List<string>();
            var prefabList = new List<string>();
            var uitexList = new List<string>();
            var vfxList = new List<string>();
            for (int i = 0; i < resFileList.Count; ++i)
            {
                UnityEngine.Debug.Log("start pkg: " + resFileList[i]);
                //要防止是文件夹的情况
                if (resFileList[i].Contains("GameUI") && resFileList[i].EndsWith(".prefab"))
                {
                    newUIList.Add(resFileList[i]);
                }
                else if (resFileList[i].IndexOf("Resources/Shader") >= 0)
                {
                    if (resFileList[i].IndexOf(".prefab") > 0)
                    {
                        PackageManager.AddResource(new ShaderPackage(resFileList[i]));
                    }
                    else
                    {
                        UnityEngine.Debug.Log("skip pkg: " + resFileList[i]);
                    }
                }
                else if (resFileList[i].IndexOf("Prefab") > 0)
                {
                    prefabList.Add(resFileList[i]);
                }
                else if (resFileList[i].IndexOf("Resources/Timeline") > 0)
                {
                    PackageManager.AddResource(new TimeLine(resFileList[i]));
                }
                else if (resFileList[i].IndexOf("Resources/VFX") > 0)
                {
                    vfxList.Add(resFileList[i]);
                }
                else if (resFileList[i].IndexOf(".unity") > 0)
                {
                    PackageManager.AddResource(new Scene(resFileList[i]));
                }
                else if (resFileList[i].IndexOf(".playable") > 0)
                {
                    PackageManager.AddResource(new TimeLine(resFileList[i]));
                }
                else if (resFileList[i].IndexOf(".anim") > 0)
                {
                    newAnimList.Add(resFileList[i]);
                }
                else if (resFileList[i].IndexOf("/Texture/UI") > 0)
                {
                    uitexList.Add(resFileList[i]);
                }
                else
                {
                    //if (BundleRecorder.IsNeedBundle(resFileList[i]))
                    defaultFiles.Add(resFileList[i]);
                }
            }
            if (newUIList.Count > 0)
            {
                PackageManager.AddResource(NewGameUI.CreateIns(newUIList));
            }
            if (newAnimList.Count > 0)
            {
                PackageManager.AddResource(PlayerAnimClip.CreateIns(newAnimList));
            }
            if (prefabList.Count > 0)
            {
                PackageManager.AddResource(Prefab.CreateIns(prefabList));
            }
            if (uitexList.Count > 0)
            {
                PackageManager.AddResource(Thousandto.Package.Texture.CreateIns(uitexList));
            }
            if (vfxList.Count > 0)
            {
                PackageManager.AddResource(VFX.CreateIns(vfxList));
            }

            PackageManager.Start();

            if (defaultFiles.Count > 0)
            {
                DIY.PackageUtils.BuildAssetBundle(defaultFiles, BasePkg.OutPath, PackageManager.BuildTarget, 200, false);
                //for (int i = 0; i < defaultFiles.Count; ++i)
                //{
                //    BundleRecorder.SaveRecorder(defaultFiles[i]);
                //}
            }
        }



        //根据文本文件获取打包信息
        private static void PackageFromTextFile(string lan, string path)
        {
            if (File.Exists(path))
            {
                HashSet<string> resFileList = new HashSet<string>();
                UnityEngine.Debug.Log("开始解析文件:" + path);
                var lines = File.ReadAllLines(path);
                bool isBuildCode = false;
                bool isBuildConfig = false;
                bool isShader = false;
                foreach (var line in lines)
                {
                    if (!string.IsNullOrEmpty(line) && !line.EndsWith(".meta"))
                    {
                        var tmp = line.Replace("\\", "/");
                        if (tmp.EndsWith(".lua") || tmp.EndsWith(".cs"))
                        {//代码有修改
                            isBuildCode = true;
                        }
                        else if (tmp.EndsWith(".xlsx"))
                        {//配置文件又修改
                            if (tmp.IndexOf("Gamedata/Config/") >= 0)
                            {
                                isBuildConfig = true;
                            }
                        }
                        else if (tmp.IndexOf("Main/Assets/GameAssets/") >= 0)
                        {
                            //只针对Main下面的资源
                            var idx = tmp.IndexOf("Assets/GameAssets/");
                            if (tmp.IndexOf("Assets/GameAssets/Resources") >= 0)
                            {
                                //配置文件
                                if (tmp.IndexOf("/Resources/Config") >= 0) continue;

                                if (tmp.IndexOf("/Resources/Shader") >= 0)
                                {
                                    isShader = true;
                                }
                                else
                                {
                                    //这两个比较特殊,是文件夹,GameUI那边会做拷贝,有异常,需要剔除这个文件夹
                                    if (!tmp.EndsWith("Form") && !tmp.EndsWith("GameUI"))
                                    {
                                        resFileList.Add(tmp.Substring(idx));
                                    }
                                }
                            }
                            else
                            {
                                if (tmp.IndexOf("Assets/GameAssets/ExportResources/Scene") >= 0)
                                {
                                    resFileList.Add(tmp.Substring(idx));
                                }
                                else if (tmp.IndexOf("Assets/GameAssets/RawResources/uinew/Local/") >= 0)
                                {
                                    if (tmp.IndexOf("/Atlas/") >= 0)
                                    {
                                        var name = GetFileNameWithOutExt(tmp);
                                        if (!string.IsNullOrEmpty(name))
                                        {
                                            var arr = name.Split(new char[] { '_' });
                                            resFileList.Add(string.Format("Assets/GameAssets/Resources/GameUI/Base/Atlas/{0}/{1}.prefab", arr[0], name));
                                        }
                                    }
                                    else if (tmp.IndexOf("/Font/") >= 0)
                                    {
                                        //字体有问题,字体与Prefab对应不上,在名字上                                        
                                        /*
                                        var name = GetFileNameWithOutExt(tmp);
                                        if (!string.IsNullOrEmpty(name))
                                        {
                                            resFileList.Add(string.Format("Assets/GameAssets/Resources/GameUI/Base/Font/{0}/{1}.prefab", name, name));
                                        }
                                        */
                                    }
                                }
                            }
                        }
                    }
                }
                //shader要打包
                if (isShader)
                {
                    resFileList.Add("Assets/GameAssets/Resources/Shader/ShaderFactory.prefab");
                }
                //打代码
                if (isBuildCode || isBuildConfig)
                {
                    UnityEngine.Debug.LogError("开始需要打代码!");
                    CodeAndDllPackage.Test(lan, isBuildConfig);
                }
                DoPackageFileList(lan, new List<string>(resFileList), false);
            }
            else
            {
                UnityEngine.Debug.LogError("没有找到文本文件:" + path);
            }

        }

        private static string GetFileNameWithOutExt(string path)
        {
            var lastidx = path.LastIndexOf("/");
            if (lastidx > 0)
            {
                var dotindex = path.IndexOf(".", lastidx);
                if (dotindex > 0)
                {
                    return path.Substring(lastidx + 1, dotindex - lastidx - 1);
                }
                return path.Substring(lastidx + 1);
            }
            else
            {
                var dotindex = path.IndexOf(".");
                if (dotindex >= 0)
                {
                    return path.Substring(0, dotindex);
                }
            }
            return path;
        }

        private string GetCurSelectLan()
        {
            string CurLan = "";
            if (IsMultilingual)
            {
                if (CH)
                    CurLan = CurLan + "CH_";
                if (TH)
                    CurLan = CurLan + "TH_";
                if (VIE)
                    CurLan = CurLan + "VIE_";
                if (JP)
                    CurLan = CurLan + "JP_";
                if (TW)
                    CurLan = CurLan + "TW_";
                if (KR)
                    CurLan = CurLan + "KR_";
                if (EN)
                    CurLan = CurLan + "EN_";

                if (CurLan == "")
                    CurLan = "CH";
                if (CurLan.StartsWith("_"))
                    CurLan = CurLan.Remove(1);
                if (CurLan.EndsWith("_"))
                    CurLan = CurLan.Remove(CurLan.Length - 1);
            }
            else
            {
                CurLan = lantype_.ToString();
            }


            if(CurLan == "")
            {
                CurLan = "CH";
            }
            return CurLan;
        }

        private List<string> GetCurSelectPack()
        {
            List<string> packs =new List<string>(); 


            return packs;
        }

        #endregion
    }

}