using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using EngineSdkConverter.Unity.Plugins.WebGL;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
public class TYPreProcessWeb : IPreprocessBuildWithReport
{
    // 定义回调的顺序
    public int callbackOrder => 0;
    private string configFilePath;
    private string configJsonString;
    private ConfigData configData;
    private static string channelType;

    // 构建前的回调方法
    public void OnPreprocessBuild(BuildReport report)
    {
        string platform = report.summary.platform.ToString();
        if (platform == "WebGL" || platform == "MiniGame")
        {
            configFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_GAMECONFIG_DIR);
            configJsonString = File.ReadAllText(configFilePath);
            configData = JsonUtility.FromJson<ConfigData>(configJsonString);
            channelType = configData.tuyooParam.channelType;
            CopyTyConfigFile();
            CopyTyBridgeFile();
            if (channelType == TYWebBuildConfig.MiniGameChannelType.WeiXin)
            {
                CopyTywxToWXTemplate();
                if (configData.login.tywx.txAdSetId != 0 && !string.IsNullOrEmpty(configData.login.tywx.txAdSetKey))
                {
                    // copy 广点通归因上报sdk的资源
                    CopyDnSdkResouce();
                }
                InsertTywx();
            }
            if (channelType == TYWebBuildConfig.MiniGameChannelType.BYTEDANCE)
            {
                string zjDirectoryPath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, "zijieminigame");
                string[] files = Directory.GetFiles(zjDirectoryPath, "tuyoosdk_zijiegame*.js");
                string sourceFile = files[0];
                CopyBytedanceResource(sourceFile);
                InsertBytedanceTuyooSdk(sourceFile);
            }
            if (channelType == TYWebBuildConfig.MiniGameChannelType.JINGDONG)
            {
                string jdDirectoryPath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, "jingdongminigame");
                string[] files = Directory.GetFiles(jdDirectoryPath, "tuyoosdk_jingdong*.js");
                string sourceFile = files[0];
                CopyTuyooSdkJdRes(sourceFile);
                InsertJDTuyooSdk(sourceFile);
            }
            if (channelType == TYWebBuildConfig.MiniGameChannelType.OPPO)
            {
                string oppoDirectoryPath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, "oppominigame");
                string[] files = Directory.GetFiles(oppoDirectoryPath, "tuyoosdk_oppo*.js");
                string sourceFile = files[0];
                CopyTuyooSdkOppoRes(sourceFile);
                InsertOppoTuyooSdk(sourceFile);
            }
            if (channelType == TYWebBuildConfig.MiniGameChannelType.MEITUAN)
            {
                string mtDirectoryPath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, "meituanminigame");
                string[] files = Directory.GetFiles(mtDirectoryPath, "tuyoosdk_meituan*.js");
                string sourceFile = files[0];
                CopyTuyooSdkMtRes(sourceFile);
                InsertMtTuyooSdk(sourceFile);
            }
            if (channelType == TYWebBuildConfig.MiniGameChannelType.KUAISHOU)
            {
                string mtDirectoryPath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, "kuaishouminigame");
                string[] files = Directory.GetFiles(mtDirectoryPath, "tuyoosdk_kuaishou*.js");
                string sourceFile = files[0];
                CopyTuyooSdkKSRes(sourceFile);
                InsertKSTuyooSdk(sourceFile);
            }
            if (channelType == TYWebBuildConfig.MiniGameChannelType.XIAOMI)
            {
                string mtDirectoryPath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, "xiaomiminigame");
                string[] files = Directory.GetFiles(mtDirectoryPath, "tuyoosdk_xiaomi*.js");
                string sourceFile = files[0];
                CopyTuyooSdkMIRes(sourceFile);
                InsertMITuyooSdk(sourceFile);
            }
        }
    }

    public static string GetBuildChannelType()
    {
        return channelType;
    }

    private void CopyTyConfigFile()
    {
        string destinationPath = Path.Combine(Application.dataPath, "Resources/tygameconfig.json");
        CopyFileContent(configFilePath, destinationPath);
    }

    private void CopyTyBridgeFile()
    {
        if (channelType == TYWebBuildConfig.MiniGameChannelType.ALI)
        {
            // 阿里小游戏
            CopyBridgeContent("aliminigame");
        }
        else if (channelType == TYWebBuildConfig.MiniGameChannelType.WeiXin)
        {
            // 微信小游戏
            CopyBridgeContent("tywx");
            InsertTywx();
        }
        else if (channelType == TYWebBuildConfig.MiniGameChannelType.BYTEDANCE)
        {
            // 字节小游戏
            CopyBridgeContent("zijieminigame");
        }
        else if (channelType == TYWebBuildConfig.MiniGameChannelType.JINGDONG)
        {
            // 京东小游戏
            CopyBridgeContent("jingdongminigame");
        }
        else if (channelType == TYWebBuildConfig.MiniGameChannelType.OPPO)
        {
            // oppo小游戏
            CopyBridgeContent("oppominigame");
        }
        else if (channelType == TYWebBuildConfig.MiniGameChannelType.MEITUAN)
        {
            CopyBridgeContent("meituanminigame");
        }
        else if (channelType == TYWebBuildConfig.MiniGameChannelType.KUAISHOU)
        {
            CopyBridgeContent("kuaishouminigame");
        }
        else if (channelType == TYWebBuildConfig.MiniGameChannelType.XIAOMI)
        {
            CopyBridgeContent("xiaomiminigame");
        }
        else
        {
            // 打一个的默认jslib,可以直接导出WebGL
            CopyBridgeContent("tywx");
        }
    }

    public void CopyBridgeContent(string filePath)
    {
        string sourceFile = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, filePath, "TyJsBridge.js");
        string targetFile = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_JSBRIDGE_DIR);
        CopyFileContent(sourceFile, targetFile);
    }

    // https://wechat-miniprogram.github.io/minigame-unity-webgl-transform/Design/BuildTemplate.html
    private void CopyTywxToWXTemplate()
    {
        string sourceFile = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, "tywx/tywx.js");
        string targetFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_WX_DEFULT_DIR, "tysdk");
        CheckAndDeletePath(targetFilePath);
        string targetFile = Path.Combine(targetFilePath, Path.GetFileName(sourceFile));
        CopyFileContent(sourceFile, targetFile);
    }

    private void CopyDnSdkResouce()
    {
        string sourcePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, "tywx/dn-sdk-minigame-1.5.4");
        string targetPath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_WX_DEFULT_DIR, "tysdk/dn-sdk-minigame-1.5.4");
        CopyDirectoryAllFiles(sourcePath, targetPath);
    }

    private void InsertTywx()
    {
        string wxGameJSFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_WX_DEFULT_DIR, "game.js");
        string content = "import { tywx } from \"./tysdk/tywx.js\";\nGameGlobal.tywx = tywx;";
        string[] keyword = new string[] { "GameGlobal.tywx = tywx;", "GameGlobal.TuyooSdk = TuyooSdk;" };
        InsertContentToFile(wxGameJSFilePath, 2, content, keyword);
    }

    private void CopyBytedanceResource(string sourceFile)
    {
        string targetFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_ZIJIE_DEFULT_DIR, "tysdk");
        // 如果已经存在了，删除里面的tysdk，避免重复copy不同版本
        CheckAndDeletePath(targetFilePath);
        string targetFile = Path.Combine(targetFilePath, Path.GetFileName(sourceFile));
        CopyFileContent(sourceFile, targetFile);
    }

    private void InsertBytedanceTuyooSdk(string sourceFile)
    {
        string zjGameJSDefaultFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_ZIJIE_DEFULT_DIR, "game.js");
        string tyfileName = "./tysdk/" + Path.GetFileName(sourceFile);
        string content = $"var TuyooSdk = require(\"{tyfileName}\");\nGameGlobal.TuyooSdk = TuyooSdk;";
        string[] keyword = new string[] { "GameGlobal.TuyooSdk = TuyooSdk;" };
        InsertContentToFile(zjGameJSDefaultFilePath, 2, content, keyword);
    }

    private void CopyTuyooSdkJdRes(string sourceFile)
    {
        string targetFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_JD_DEFULT_DIR, "tysdk");
        // 如果已经存在了，删除里面的tysdk，避免重复copy不同版本
        CheckAndDeletePath(targetFilePath);
        string targetFile = Path.Combine(targetFilePath, Path.GetFileName(sourceFile));
        CopyFileContent(sourceFile, targetFile);
        if (configData.login.jingdongminigame.packageType == "wasmsplit")
        {
            string tywxSourceFile = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, "tywx/tywx.js");
            string tywxTargetFilePath = Path.Combine(targetFilePath, "tywx.js");
            CopyFileContent(tywxSourceFile, tywxTargetFilePath);
        }
    }

    private void InsertJDTuyooSdk(string sourceFile)
    {
        string jdGameJSDefaultFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_JD_DEFULT_DIR, "game.js");
        string tyfileName = "./tysdk/" + Path.GetFileName(sourceFile);
        string content = $"var TuyooSdk = require(\"{tyfileName}\");\nGameGlobal.TuyooSdk = TuyooSdk;";
        string[] keyword = new string[] { "GameGlobal.tywx = tywx;", "GameGlobal.TuyooSdk = TuyooSdk;" };
        InsertContentToFile(jdGameJSDefaultFilePath, 2, content, keyword);
        if (configData.login.jingdongminigame.packageType == "wasmsplit")
        {
            string tywxContent = "import { tywx } from \"./tysdk/tywx.js\";\nGameGlobal.tywx = tywx;";
            InsertContentToFile(jdGameJSDefaultFilePath, 2, tywxContent, new string[] { });
        }
    }

    private void CopyTuyooSdkOppoRes(string sourceFile)
    {
        string targetFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_WX_DEFULT_DIR, "tysdk");
        // 如果已经存在了，删除里面的tysdk，避免重复copy不同版本
        CheckAndDeletePath(targetFilePath);
        string targetFile = Path.Combine(targetFilePath, Path.GetFileName(sourceFile));
        CopyFileContent(sourceFile, targetFile);
        if (configData.login.oppominigame.packageType == "wasmsplit")
        // 因为oppo小游戏需要用微信小游戏的开发者工具跑分包，所以需要把微信的资源脚本也打到包里
        {
            string tywxSourceFile = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_CHANNEL_RESOURCE_DIR, "tywx/tywx.js");
            string tywxTargetFilePath = Path.Combine(targetFilePath, "tywx.js");
            CopyFileContent(tywxSourceFile, tywxTargetFilePath);
        }
    }

    private void InsertOppoTuyooSdk(string sourceFile)
    {
        string gameJSDefaultFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_WX_DEFULT_DIR, "game.js");
        string tyfileName = "./tysdk/" + Path.GetFileName(sourceFile);
        string content = $"var TuyooSdk = require(\"{tyfileName}\");\nGameGlobal.TuyooSdk = TuyooSdk;";
        string[] keyword = new string[] { "GameGlobal.tywx = tywx;", "GameGlobal.TuyooSdk = TuyooSdk;" };
        InsertContentToFile(gameJSDefaultFilePath, 2, content, keyword);
        if (configData.login.oppominigame.packageType == "wasmsplit")
        {
            string tywxContent = "import { tywx } from \"./tysdk/tywx.js\";\nGameGlobal.tywx = tywx;";
            InsertContentToFile(gameJSDefaultFilePath, 2, tywxContent,  new string[] { });
        }
    }

    private void CopyTuyooSdkMtRes(string sourceFile)
    {
        string targetFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_MT_DEFULT_DIR, "tysdk");
        // 如果已经存在了，删除里面的tysdk，避免重复copy不同版本
        CheckAndDeletePath(targetFilePath);
        string targetFile = Path.Combine(targetFilePath, Path.GetFileName(sourceFile));
        CopyFileContent(sourceFile, targetFile);
    }

    private void InsertMtTuyooSdk(string sourceFile)
    {
        string tyfileName = "./tysdk/" + Path.GetFileName(sourceFile);
        string mtGameJSFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_MT_DEFULT_DIR, "game.js");
        string content = $"var TuyooSdk = require(\"{tyfileName}\");\nGameGlobal.TuyooSdk = TuyooSdk;";
        string[] keyword = new string[] { "GameGlobal.TuyooSdk = TuyooSdk;" };
        InsertContentToFile(mtGameJSFilePath, 2, content, keyword);
    }

    private void CopyTuyooSdkKSRes(string sourceFile)
    {
        string targetFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_KS_DEFULT_DIR, "tysdk");
        // 如果已经存在了，删除里面的tysdk，避免重复copy不同版本
        CheckAndDeletePath(targetFilePath);
        string targetFile = Path.Combine(targetFilePath, Path.GetFileName(sourceFile));
        CopyFileContent(sourceFile, targetFile);
    }

    private void InsertKSTuyooSdk(string sourceFile)
    {
        string tyfileName = "./tysdk/" + Path.GetFileName(sourceFile);
        string ksGameJSFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_KS_DEFULT_DIR, "game.js");
        string content = $"var TuyooSdk = require(\"{tyfileName}\");\nGameGlobal.TuyooSdk = TuyooSdk;";
        string[] keyword = new string[] { "GameGlobal.TuyooSdk = TuyooSdk;" };
        InsertContentToFile(ksGameJSFilePath, 2, content, keyword);
    }

    private void CopyTuyooSdkMIRes(string sourceFile)
    {
        string targetFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_MI_DEFULT_DIR, "tysdk");
        // 如果已经存在了，删除里面的tysdk，避免重复copy不同版本
        CheckAndDeletePath(targetFilePath);
        string targetFile = Path.Combine(targetFilePath, Path.GetFileName(sourceFile));
        CopyFileContent(sourceFile, targetFile);
    }

    private void InsertMITuyooSdk(string sourceFile)
    {
        string tyfileName = "./tysdk/" + Path.GetFileName(sourceFile);
        string miGameJSFilePath = Path.Combine(Application.dataPath, TYWebBuildConfig.TY_WEB_MI_DEFULT_DIR, "game.js");
        string content = $"var TuyooSdk = require(\"{tyfileName}\");\nwindow.TuyooSdk = TuyooSdk;";
        string[] keyword = new string[] { "window.TuyooSdk = TuyooSdk;" };
        InsertContentToFile(miGameJSFilePath, 1, content, keyword);
    }

    public void CheckAndDeletePath(string targetPath)
    {
        if (Directory.Exists(targetPath))
        {
            string[] files = Directory.GetFiles(targetPath, "*", SearchOption.AllDirectories);
            foreach (string file in files)
            {
                File.Delete(file);
            }
        }
    }

    public void CopyDirectoryAllFiles(string sourcePath, string targetPath)
    {
        if (!Directory.Exists(targetPath))
        {
            Directory.CreateDirectory(targetPath);
        }
        string[] files = Directory.GetFiles(sourcePath);

        foreach (string file in files)
        {
            string fileName = Path.GetFileName(file);
            if (fileName.EndsWith(".meta"))
            {
                continue;
            }
            string destFile = Path.Combine(targetPath, fileName);

            try
            {
                File.Copy(file, destFile, true);
            }
            catch (System.Exception e)
            {
                Debug.Log($"Failed to copy file {fileName}: {e.Message}");
            }
        }
    }

    public void CopyFileContent(string sourceFile, string targetFile)
    {
        if (!File.Exists(sourceFile))
        {
            Debug.LogError($"源文件不存在: {sourceFile}");
            return;
        }

        // 确保目标目录存在
        string targetDirectory = Path.GetDirectoryName(targetFile);
        if (!Directory.Exists(targetDirectory))
        {
            Directory.CreateDirectory(targetDirectory);
        }

        // 读取源文件内容并写入目标文件（覆盖方式）
        File.Copy(sourceFile, targetFile, true);

        Debug.Log($"已复制 {sourceFile} 的内容到 {targetFile}");
    }

    public void InsertContentToFile(string filePath, int targetLine, string insertContent, string[] checkKeyword)
    {
        try
        {
            if (!File.Exists(filePath))
            {
                Debug.LogError("文件不存在: " + filePath);
                return;
            }

            var fileLines = new List<string>(File.ReadAllLines(filePath));

            foreach (string keyword in checkKeyword)
            {
                int matchIndex = fileLines.FindIndex(line => line.Trim() == keyword);
                if (matchIndex >= 1)
                {
                    // 删除该行和它上面一行，如： "import { tywx } from \"./tysdk/tywx.js\";\nGameGlobal.tywx = tywx;"; 
                    fileLines.RemoveAt(matchIndex);
                    fileLines.RemoveAt(matchIndex - 1);
                }
            }

            string[] lines = fileLines.ToArray();

            // 插入内容
            if (targetLine > lines.Length)
            {
                // 如果目标行号超过文件行数，则追加
                File.AppendAllText(filePath, Environment.NewLine + insertContent + Environment.NewLine);
            }
            else
            {
                // 在指定行插入
                fileLines.Insert(targetLine - 1, insertContent);
                File.WriteAllLines(filePath, fileLines);
            }

            Debug.Log($"已修改文件: {filePath}");
        }
        catch (System.Exception e)
        {
            Debug.LogError($"修改文件失败: {e.Message}");
        }
    }

    public void RemoveTargetContent(string filePath, string target)
    {
        try
        {
            if (!File.Exists(filePath))
            {
                Debug.LogError("文件不存在: " + filePath);
                return;
            }
            // 读取文件内容
            string text = File.ReadAllText(filePath);

            // 删除目标内容
            string newText = text.Replace(target, "");

            // 写回文件
            File.WriteAllText(filePath, newText);
        }
        catch (System.Exception e)
        {
            Debug.LogError($"删除指定内容失败: {e.Message}");
        }
    }

}
