using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace TyphoonUnitySDK
{
    /// <summary>
    /// 发布流程-ChinaAndroidAAR
    /// </summary>
    public class PublishXiZhongYou : IPublish
    {
        private static string GetPublishProj(string exportProj) =>
            $"{Path.GetDirectoryName(exportProj)}/xzy.android.proj";

        public void Publish(PublishSetting setting)
        {
            PublishResult result = new PublishResult();
            //切换到工程模式
            PublishTool.SwitchToProject();
            if (!UniEditor.GradleIsMatch(out var error))
            {
                UniEditor.ShowMessageBox($"检查 gradle 环境失败！err:{error},去配置？",
                    UniEditor.OpenUnityPreferencesExternalTool);
                return;
            }

            var dateString = DateTime.Now.ToString("yyyyMMdd_HHmmss");
            var path = $".typhoonoutput/xzy_android_{dateString}";
            if (!UniEditor.IsAsciiPath(path))
            {
                UniEditor.ShowMessageBox($"路径不符合要求，不支持中文路径：\n当前：{path}", null);
                return;
            }

            PublishTool.InvokeOnPublishStart(setting);

            //导出前执行
            BuildPipeline.BuildPlayer(EditorBuildSettings.scenes, path, BuildTarget.Android, BuildOptions.None);
            if (!Directory.Exists(path))
            {
                return;
            }

            var launcher_folder = $"{path}/launcher";
            var unityLibrary_folder = $"{path}/unityLibrary";
            if (!Directory.Exists(launcher_folder))
            {
                throw new Exception($"发布失败，找不到：{launcher_folder}");
            }

            if (!Directory.Exists(unityLibrary_folder))
            {
                throw new Exception($"发布失败，找不到：{unityLibrary_folder}");
            }

            Debug.Log("修改横竖屏...");
            var manifest = $"{path}/unityLibrary/src/main/AndroidManifest.xml";
            if (!File.Exists(manifest))
            {
                var dir = new DirectoryInfo(path);
                var files = dir.GetFiles("AndroidManifest.xml", SearchOption.AllDirectories);
                foreach (FileInfo info in files)
                {
                    if (File.ReadAllText(info.FullName).Contains("bee.union.sdk.BeeUnionAppActivity"))
                    {
                        manifest = info.FullName;
                    }
                }
            }

            if (!File.Exists(manifest))
            {
                Debug.LogError("找不到AndroidManifest.xml,修改横竖屏失败");
            }

            //生成发布bat
            var gradle = UniEditor.GetGradlePath();
            var batTxt = $@"
call ""{gradle}\bin\gradle"" assembleRelease --console=plain -q --quiet
if %errorlevel% equ 0 (
    echo Build completed successfully.
    exit
) else (
    echo Build encountered an error.
    pause
)";
            var apk_publish_bat = $"{path}/publish.bat";
            File.WriteAllText(apk_publish_bat, batTxt); //$"{gradle}/gradle assembleRelease --max-workers=8"
            //生成unitylibrary发布批处理
            var unity_aar_publish_bat = $"{unityLibrary_folder}/publish.bat";
            File.WriteAllText(unity_aar_publish_bat, batTxt);

            //更换库
            var buildGradle = $"{path}/build.gradle";
            if (File.Exists(buildGradle))
            {
                Debug.Log("更换镜像仓库");
                var txt = File.ReadAllText(buildGradle);
                //更换镜像仓库
                txt = Regex.Replace(txt, "google[/s]*/(/)",
                    "maven { url 'https://maven.aliyun.com/repository/google' }\ngoogle()");
                txt = Regex.Replace(txt, "jcenter[/s]*/(/)",
                    "maven { url 'https://maven.aliyun.com/repository/jcenter' }\njcenter()");
                File.WriteAllText(buildGradle, txt);
            }

            //合并到china.android.proj
            MergeToChinaAndroidProj(path);

            //切换批处理目录
            // unity_aar_publish_bat = $"{GetPublishProj(path)}/unityLibrary/publish.bat";
            // apk_publish_bat = $"{GetPublishProj(path)}/publish.bat";
            //执行构建unitylibrary.aar
            // Debug.Log("构建unitylibrary.aar...");
            // if (File.Exists(unity_aar_publish_bat))
            // {
            //     UniEditor.RunBat(unity_aar_publish_bat);
            // }
            //
            // var output_aar = $"{GetPublishProj(path)}/unityLibrary/build/outputs/aar/unityLibrary-release.aar";
            // //检查是否
            // if (!File.Exists(output_aar))
            // {
            //     //复制到
            //     throw new Exception($"构建unityLibrary.aar失败，找不到文件：{output_aar}");
            // }
            //
            // Debug.Log("生成unity-game-package.aar到母包");
            // var bee_build_libs = $"{GetPublishProj(path)}/launcher/src/main/assets/bee-build-libs";
            // var bee_package_aar = $"{bee_build_libs}/unity-game-package.aar";
            // var folder = Path.GetDirectoryName(bee_package_aar);
            // if (!Directory.Exists(folder))
            // {
            //     Directory.CreateDirectory(folder);
            // }
            //
            // File.Copy(output_aar, bee_package_aar, true);
            //

            //复制第三方库到母包
            // Debug.Log("复制第三方库到母包");
            // UniEditor.CopyFolder($"{GetPublishProj(path)}/unityLibrary/libs", bee_build_libs);

            //生成说明配置
            // Debug.Log("生成资源配置");
            // var bee_union_lib_json = $"{bee_build_libs}/__apk.json";
            // var config = new { miniSdkVersion = PlayerSettings.Android.minSdkVersion };
            // File.WriteAllText(bee_union_lib_json, config.ToXJson());
            Debug.Log("生成apk...");
            UniEditor.RunBat(apk_publish_bat);
            var output_apk = $"{path}/launcher/build/outputs/apk/release/launcher-release.apk";
            if (!File.Exists(output_apk))
            {
                throw new Exception($"发布失败，生成apk失败，找不到文件：{output_apk}");
            }

            //复制到当前目录
            var final = string.IsNullOrEmpty(setting.PackageName)
                ? $"{Path.GetDirectoryName(path)}/{Path.GetFileName(path)}.apk"
                : $"{Path.GetDirectoryName(path)}/{setting.PackageName}_{dateString}.apk";
            File.Copy(output_apk, final, true);
            Debug.Log($"发布成功：{final}");
            Debug.Log("构建喜中游所需的android工程...");
            var xiZhongYouProj = $"{Path.GetDirectoryName(path)}/{Path.GetFileName(path)}_app";
            var buildFolder = $"{path}/launcher/build";
            Debug.Log($"删除{buildFolder}...");
            if (Directory.Exists(buildFolder))
            {
                UniEditor.DeleteFolder(buildFolder);
            }

            var buildUnityLibrary = $"{path}/unityLibrary/build";
            Debug.Log($"删除{buildUnityLibrary}...");
            if (Directory.Exists(buildUnityLibrary))
            {
                UniEditor.DeleteFolder(buildUnityLibrary);
            }

            //libil2cpp.dbg.so
            Debug.Log($"复制 {path} --> {xiZhongYouProj}");
            UniEditor.CopyFolder(path, xiZhongYouProj);
            if (Directory.Exists(xiZhongYouProj))
            {
                {
                    //删除union-sdk.aar
                    var unionSdk = $"{xiZhongYouProj}/unityLibrary/libs/union-sdk.aar";
                    File.Delete(unionSdk);
                }
                {
                    //复制UnionAppActivity.java
                    var fromPath = "Assets/Typhoon_Gen/TyphoonSDK/Runtime/XiZhongYou/Editor/UnionAppActivity.txt";
                    var toPath = $"{xiZhongYouProj}/unityLibrary/src/main/java/bee/union/sdk/UnionAppActivity.java";
                    UniEditor.CreateDirIfNotExist(Path.GetDirectoryName(toPath));
                    File.Copy(fromPath, toPath, true);
                }
                {
                    //build.gradle去除依赖
                    var unity_lib_build_gradle = $"{xiZhongYouProj}/unityLibrary/build.gradle";
                    var context = File.ReadAllText(unity_lib_build_gradle);
                    context = context.Replace("implementation(name: 'union-sdk', ext:'aar')", string.Empty);
                    File.WriteAllText(unity_lib_build_gradle, context);
                }
            }

            if (!XiZhongYouConfig.Default.KeepProj)
            {
                //删除文件夹
                UniEditor.DeleteFolder(path);
            }

            EditorUtility.RevealInFinder(final);
            result.IsSuccess = true;
            result.AndroidApk = final;
            PublishTool.InvokeOnPublishEnd(setting, result);
        }

        //融合到china.android.proj
        private void MergeToChinaAndroidProj(string exportProj)
        {
            //创建china.android.proj文件夹
            var proj = GetPublishProj(exportProj);
            if (!Directory.Exists(proj))
            {
                Directory.CreateDirectory(proj);
            }

            Debug.Log($"合并{exportProj}->{proj}");
            ClearBuildProjKeepBuildCache(proj);
            //复制发布资源和代码到打包目录下
            UniEditor.CopyFolder(exportProj, proj);
        }

        //清空打包工程，保持构建缓存
        private static void ClearBuildProjKeepBuildCache(string buildProj)
        {
            var cache = FindAllCacheBuildFolder(buildProj);
            var ignore = new HashSet<string>();
            foreach (var item in cache)
            {
                ignore.Add(Path.GetFullPath(item));
            }

            var dir = Path.GetFullPath(buildProj);
            ClearDirectoryExclude(dir, ignore, dir);
            //清理outputs文件夹
            foreach (var item in ignore)
            {
                var outputs = $"{item}/outputs";
                if (Directory.Exists(outputs))
                {
                    UniEditor.DeleteFolder(outputs);
                }
            }
        }

        private static List<string> FindAllCacheBuildFolder(string dir)
        {
            var match = new List<string>();
            var info = new DirectoryInfo(dir);
            var files = info.GetFiles("build.gradle", SearchOption.AllDirectories);
            foreach (var file in files)
            {
                var check = $"{Path.GetDirectoryName(file.FullName)}/build";
                if (Directory.Exists(check))
                {
                    match.Add(check);
                }
            }

            return match;
        }

        //清理文件夹，排除一些目录
        public static void ClearDirectoryExclude(string folderPath, HashSet<string> ignoredFolders, string rootPath)
        {
            if (!Directory.Exists(folderPath))
            {
                throw new DirectoryNotFoundException("指定的文件夹路径不存在");
            }

            // 遍历文件夹中的所有文件和子文件夹
            foreach (var file in Directory.GetFiles(folderPath))
            {
                try
                {
                    UniEditor.DeleteFile(file);
                }
                catch (Exception e)
                {
                }
            }

            foreach (var subDir in Directory.GetDirectories(folderPath))
            {
                string folderName = Path.GetFullPath(subDir);
                if (ignoredFolders.Contains(folderName))
                {
                    continue; // 忽略被忽略的文件夹
                }

                ClearDirectoryExclude(folderName, ignoredFolders, rootPath); // 递归删除子文件夹中的文件
            }

            // 判断文件夹是否为空
            if (Directory.GetFiles(folderPath).Length == 0 && Directory.GetDirectories(folderPath).Length == 0 &&
                folderPath != rootPath)
            {
                UniEditor.DeleteFolder(folderPath, false); // 删除空文件夹
            }
        }
    }
}