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

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

        public void Publish(PublishSetting setting)
        {
            PublishResult result = new PublishResult();
            //切换到工程模式
            PublishTool.SwitchToProject();

            if (!UniEditor.GradleIsMatch())
            {
                UniEditor.ShowMessageBox($"未配置gradle,去配置？", PreferencesWindow.Open);
                return;
            }

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

            // UniEditor.TryDeleteFolder("Assets/Plugins/Android");
            // AssetDatabase.Refresh();
            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}");
            }

            // <activity[\s]*android:name="com.unity3d.player.UnityPlayerActivity".*[\s\=\|\w\:\|\"]*android:screenOrientation="[\w]*"
            //<activity[\s]*android:name="bee.union.sdk.BeeUnionAppActivity".*[\s\=\|\w\:\|\"]*android:screenOrientation="[\w]*"


            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,修改横竖屏失败");
            }
            else
            {
                // var screenOrientationString =
                //     ChinaAndroidConfig.Default.Orientation == ChinaAndroidConfig.ScreenOrientation.Portrait
                //         ? "portrait"
                //         : "landscape";
                // var replacement = $"android:screenOrientation=\"{screenOrientationString}\"";
                // var xml = File.ReadAllText(manifest);
                // var pattern1 =
                //     "<activity[\\s]*android:name=\"com.unity3d.player.UnityPlayerActivity\".*[\\s\\=\\|\\w\\:\\|\\\"]*android:screenOrientation=\"[\\w]*\"";
                // var match1 = Regex.Match(xml, pattern1).Value;
                // pattern1 = "android:screenOrientation[\\s]*=[\\s]*\"[\\w]*\"";
                // var part1 = Regex.Replace(match1, pattern1, replacement);
                //
                // var pattern2 =
                //     "<activity[\\s]*android:name=\"bee.union.sdk.BeeUnionAppActivity\".*[\\s\\=\\|\\w\\:\\|\\\"]*android:screenOrientation=\"[\\w]*\"";
                // var match2 = Regex.Match(xml, pattern2).Value;
                // pattern2 = "android:screenOrientation[\\s]*=[\\s]*\"[\\w]*\"";
                // var part2 = Regex.Replace(match2, pattern2, replacement);
                //
                // xml = xml.Replace(match1, part1);
                // xml = xml.Replace(match2, part2);
                // File.WriteAllText(manifest, xml);
                // Debug.Log("横竖屏修改成功");
            }


            //生成发布bat
            var gradle = Preferences.Default.GradlePath;

            var batTxt = $@"
call ""{gradle}""\\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' }");
                txt = Regex.Replace(txt, "jcenter[\\s]*\\(\\)",
                    "maven { url 'https://maven.aliyun.com/repository/jcenter' }");
                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 = $"{GetPublishProj(path)}/launcher/build/outputs/apk/release/launcher-release.apk";
            if (!File.Exists(output_apk))
            {
                throw new Exception($"发布失败，生成apk失败，找不到文件：{output_apk}");
            }

            //复制到当前目录
            var final = $"{Path.GetDirectoryName(path)}/{Path.GetFileName(path)}.apk";
            File.Copy(output_apk, final, true);
            Debug.Log($"发布成功：{final}");
            if (!ChinaAndroidConfig.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); // 删除空文件夹
            }
        }
    }
}