using System.Collections.Generic;
using System.IO;
using TEngine.Editor.Resource;
using UnityEditor;
using UnityEditor.U2D;
using UnityEngine;
using UnityEngine.U2D;
using YooAsset.Editor;

public static class BuildBundlesHelper
{
    private static BuildParameters GetParametersFromParams(BuildTarget buildTarget, string buildVersion)
    {
        BuildParameters buildParameters = new BuildParameters()
        {
            StreamingAssetsRoot = AssetBundleBuilderHelper.GetDefaultStreamingAssetsRoot(),
            BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(),
            BuildTarget = buildTarget,
            BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline,
            BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode,
            PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage,
            PackageVersion = buildVersion,
            VerifyBuildingResult = true,
            SharedPackRule = new ZeroRedundancySharedPackRule(),
            EncryptionServices = new FileStreamEncryption(),
            CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption,
            OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle,
            CopyBuildinFileOption = ECopyBuildinFileOption.None,
            CopyBuildinFileTags = AssetBundleBuilderSettingData.Setting.CopyBuildinFileTags,
            EnableLog = false,
        };

        if (AssetBundleBuilderSettingData.Setting.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
        {
            buildParameters.SBPParameters = new BuildParameters.SBPBuildParameters();
            buildParameters.SBPParameters.WriteLinkXML = true;
        }

        return buildParameters;
    }

    [MenuItem("Tools/TestBuildBundles")]
    public static void TestBuildBundles()
    {
        
        Debug.LogWarning("MakeAtlas Start ==================");
        MakeAtlas();
        AssetDatabase.Refresh();
        Debug.LogWarning("MakeAtlas End ==================");
        
        Debug.LogWarning("Create YooAsset Package Start ==========");
        CreateYooAssetPackage();
        AssetDatabase.Refresh();
        Debug.LogWarning("Create YooAsset Package End ==========");
     
        Debug.LogWarning("BuildBundles Start ==================");
        AssetBundleCollectorSetting setting = AssetDatabase.LoadAssetAtPath<AssetBundleCollectorSetting>("Assets/AssetBundleCollectorSetting.asset");
        if (setting == null)
        {
            Debug.LogError("不存在的AssetBundleCollectorSetting.asset");
            return;
        }
        var bundleBuilder = new AssetBundleBuilder();
        BuildParameters buildParameters = GetParametersFromParams(BuildTarget.Android, "1.0.0");
        string outputDir = $"{buildParameters.BuildOutputRoot}/{buildParameters.BuildTarget.ToString()}";
        Debug.LogError($"bundle资源输出目录:{outputDir}");
        if (Directory.Exists(outputDir))
            Directory.Delete(outputDir, true);

        for (int i = 0; i < setting.Packages.Count; i++)
        {
            var package = setting.Packages[i];
            if(package.PackageName == "DefaultPackage")
                continue;

            buildParameters.PackageName = package.PackageName;
            bundleBuilder.Run(buildParameters);
        }
        Debug.LogWarning("BuildBundles End ==================");
    }

    public static void BuildBundles()
    {
        Debug.LogWarning("MakeAtlas Start ==================");
        MakeAtlas();
        AssetDatabase.Refresh();
        Debug.LogWarning("MakeAtlas End ==================");
        
        Debug.LogWarning("Create YooAsset Package Start ==========");
        CreateYooAssetPackage();
        AssetDatabase.Refresh();
        Debug.LogWarning("Create YooAsset Package End ==========");
        
        Debug.LogWarning("BuildBundles Start ==================");
        AssetBundleCollectorSetting setting = AssetDatabase.LoadAssetAtPath<AssetBundleCollectorSetting>("Assets/AssetBundleCollectorSetting.asset");
        if (setting == null)
        {
            Debug.LogError("不存在的AssetBundleCollectorSetting.asset");
            return;
        }
        BuildParams bp = BuildParamsHelper.GetBuildParams();
        bp.Description();
        var bundleBuilder = new AssetBundleBuilder();
        BuildParameters buildParameters = null;
        if (bp.Platform == "Android")
            buildParameters = GetParametersFromParams(BuildTarget.Android, bp.BuildVersion);
        else if (bp.Platform == "iOS")
            buildParameters = GetParametersFromParams(BuildTarget.iOS, bp.BuildVersion);
        if (buildParameters == null)
        {
            Debug.LogError($"不支持的平台:{bp.Platform}");
            return;
        }
        
        string outputDir = $"{buildParameters.BuildOutputRoot}/{buildParameters.BuildTarget.ToString()}";
        Debug.LogError($"bundle资源输出目录:{outputDir}");
        if (Directory.Exists(outputDir))
            Directory.Delete(outputDir, true);
        
        for (int i = 0; i < setting.Packages.Count; i++)
        {
            var package = setting.Packages[i];
            if(package.PackageName == "DefaultPackage")
                continue;

            buildParameters.PackageName = package.PackageName;
            bundleBuilder.Run(buildParameters);
        }
        Debug.LogWarning("BuildBundles End ==================> exe");
    }

    #region 创建图集
    
    private static void MakeAtlas()
    {
        for (int i = 0; i < (int)GamePlay.end; i++)
        {
            GamePlay playType = (GamePlay)i;
            string dir = $"Assets/AssetRaw/UIRaw/Raw/Level/{playType.ToString()}";
            if (!AssetDatabase.IsValidFolder(dir))
            {
                Debug.LogError($"不存在的目录:{dir}");
                continue;
            }
            
            var playTypeAllLevelDirs = AssetDatabase.GetSubFolders(dir);
            foreach (var levelDir in playTypeAllLevelDirs)
            {
                string levelName = levelDir.Substring(levelDir.LastIndexOf('/') + 1);
                MakeLevelAtlas(levelDir, levelName);
                string itemDirPath = $"{levelDir}/titem";
                if (!AssetDatabase.IsValidFolder(itemDirPath))
                {
                    Debug.LogError($"不存在的道具图:{itemDirPath}");
                    continue;
                }
                MakeItemAtlas(itemDirPath, levelName);
            }
        }
    }
    
    private static void MakeItemAtlas(string dirPath, string levelName)
    {
        string[] allPics = Directory.GetFiles(dirPath, "*.png", SearchOption.TopDirectoryOnly);
        if (allPics.Length == 0)
        {
            Debug.LogError($"不存在的道具图:{dirPath}");
            return;
        }
        
        List<Sprite> sprites = new List<Sprite>();
        foreach (var picPath in allPics)
        {
            if(picPath.EndsWith(".meta"))
                continue;

            if (picPath.Contains("_titem_"))
            {
                var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(picPath);
                if (sprite != null)
                {
                    sprites.Add(sprite);
                }
            }
        }
        AtlasUtils.CreateAtlas($"{levelName}_atlasItem", sprites, dirPath);
    }

    private static void MakeLevelAtlas(string levelDir, string levelName)
    {
        string[] allPics = Directory.GetFiles(levelDir, "*.png", SearchOption.TopDirectoryOnly);
        if (allPics.Length == 0)
        {
            Debug.LogError($"不存在的关卡图:{levelDir}");
            return;
        }

        List<Sprite> sprites = new List<Sprite>();
        foreach (var picPath in allPics)
        {
            if(picPath.EndsWith(".meta"))
                continue;

            if (picPath.Contains("_tfull_") || picPath.Contains("_tmask_") || picPath.Contains("_tlight_") || picPath.Contains("_tshadow_"))
            {
                var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(picPath);
                if (sprite != null)
                {
                    sprites.Add(sprite);
                }
            }
        }
        AtlasUtils.CreateAtlas($"{levelName}_atlasLevel", sprites, levelDir);
    }
    
    #endregion

    private static void CreateYooAssetPackage()
    {
        AssetBundleCollectorSetting setting = AssetDatabase.LoadAssetAtPath<AssetBundleCollectorSetting>("Assets/AssetBundleCollectorSetting.asset");
        if (setting == null)
        {
            Debug.LogError("不存在的AssetBundleCollectorSetting.asset");
            return;
        }

        //重置配置
        for (int i = 0; i < setting.Packages.Count; i++)
        {
            if(setting.Packages[i].PackageName == "DefaultPackage")
                continue;
            
            setting.Packages.RemoveAt(i);
            i--;
        }
        Debug.Log($"packge count:{setting.Packages.Count}");
        
        //创建关卡资源package
        for (int i = 0; i < (int)GamePlay.end; i++)
        {
            GamePlay playType = (GamePlay)i;
            string dir = $"Assets/AssetRaw/UIRaw/Raw/Level/{playType.ToString()}";
            if (!AssetDatabase.IsValidFolder(dir))
            {
                Debug.LogError($"不存在的目录:{dir}");
                continue;
            }
            
            var playTypeAllLevelDirs = AssetDatabase.GetSubFolders(dir);
            foreach (var levelDir in playTypeAllLevelDirs)
            {
                string levelName = levelDir.Substring(levelDir.LastIndexOf('/') + 1);
                AssetBundleCollectorPackage package = new AssetBundleCollectorPackage();
                package.PackageName = levelName;
                package.PackageDesc = $"{levelName}关卡资源包";
                package.Groups = new List<AssetBundleCollectorGroup>();
                
                AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
                group.GroupName = "default";
                group.AssetTags = levelName;
                group.ActiveRuleName = "EnableGroup";
                group.Collectors = new List<AssetBundleCollector>();
                
                AssetBundleCollector collector = new AssetBundleCollector();
                collector.CollectPath = levelDir;
                collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
                collector.CollectorType = ECollectorType.MainAssetCollector;
                collector.AddressRuleName = nameof(AddressByFileName);
                collector.PackRuleName = nameof(PackCollector);
                collector.FilterRuleName = nameof(CollectAll);
                collector.AssetTags = levelName;
                
                group.Collectors.Add(collector);
                package.Groups.Add(group);
                
                setting.Packages.Add(package);
            }
        }
        
        //创建关卡缩略图package
        for (int i = 0; i < (int)GamePlay.end; i++)
        {
            GamePlay playType = (GamePlay)i;
            string dir = $"Assets/AssetRaw/UIRaw/Raw/Thum/{playType.ToString()}";
            if (!AssetDatabase.IsValidFolder(dir))
            {
                Debug.LogError($"不存在的目录:{dir}");
                continue;
            }
            
            var thumFiles = Directory.GetFiles(dir);
            foreach (var thumFile in thumFiles)
            {
                if(thumFile.EndsWith(".meta"))
                    continue;
                
                string levelName = Path.GetFileNameWithoutExtension(thumFile);
                AssetBundleCollectorPackage package = new AssetBundleCollectorPackage();
                package.PackageName = levelName;
                package.PackageDesc = $"{levelName}缩略图资源包";
                package.Groups = new List<AssetBundleCollectorGroup>();
                
                AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
                group.GroupName = "default";
                group.AssetTags = levelName;
                group.ActiveRuleName = "EnableGroup";
                group.Collectors = new List<AssetBundleCollector>();
                
                AssetBundleCollector collector = new AssetBundleCollector();
                collector.CollectPath = thumFile;
                collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
                collector.CollectorType = ECollectorType.MainAssetCollector;
                collector.AddressRuleName = nameof(AddressByFileName);
                collector.PackRuleName = nameof(PackDirectory);
                collector.FilterRuleName = nameof(CollectAll);
                collector.AssetTags = levelName;
                
                group.Collectors.Add(collector);
                package.Groups.Add(group);
                
                setting.Packages.Add(package);
            }
        }
        
        AssetDatabase.SaveAssetIfDirty(setting);
    }
}