using Assets.Native.tools.excel.Model;
using Assets.Native.tools.excel.Util;
using ClosedXML.Excel;
using CommonUtil;
using EditorUtils;
using iHuman.UnitySz.Framework;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
using static iHuman.UnitySz.Framework.ResLinkAsset;

public class PracticeCreator
{
    const string artPathRoot = "Assets/art/game/practice/";
    const string scriptPathRoot = "Assets/gamesrc/practice/";
    const string templatePath = "Assets/gamesrc/practice/template/practiceTemplate.lua";

    [MenuItem("Assets/自定义创建/练环节/创建文件")]
    public static void createNewPractice()
    {
        string[] strs = Selection.assetGUIDs;

        if (strs != null)
        {
            foreach (string str in strs)
            {
                string id = GetID(str);
                if (!String.IsNullOrEmpty(id))
                {
                    CreateSoundAsset(id);

                    var gamesrcFolder = Path.Combine(scriptPathRoot, @$"practice{id}");
                    if (!Directory.Exists(gamesrcFolder))
                    {
                        Debug.Log("[创建目录]" + gamesrcFolder);
                        Directory.CreateDirectory(gamesrcFolder);
                    }

                    //创建practiceConfig文件
                    var practiceConfigName = $"Practice{id}Config.lua";
                    var practiceConfigPath = Path.Combine(gamesrcFolder, practiceConfigName);
                    if (!File.Exists(practiceConfigPath) && File.Exists(templatePath))
                    {
                        Debug.Log("[创建practiceConfig文件]" + practiceConfigPath);
                        using (StreamReader reader = new StreamReader(templatePath, Encoding.Default))
                        {
                            string a = reader.ReadToEnd();
                            //todo 一些修改逻辑。。。

                            using (StreamWriter writer = new StreamWriter(practiceConfigPath, false, Encoding.Default))
                            {
                                writer.Write(a);
                                writer.Flush();
                            }
                        }
                    }


                    //创建reslink文件
                    var practiceResLinkName = $"Practice{id}resLink.asset";
                    string practiceResFolder = Path.Combine(artPathRoot, @$"practice{id}");
                    string practiceResLinkPath = Path.Combine(gamesrcFolder, practiceResLinkName);
                    string practiceResLinkLuaPath = Path.Combine(gamesrcFolder, $"Practice{id}resLink.lua");
                    if (File.Exists(practiceResLinkPath))
                    {
                        File.Delete(practiceResLinkPath);
                        File.Delete(practiceResLinkPath);
                    }
                    if (!File.Exists(practiceResLinkPath))
                    {
                        Debug.Log("[创建reslink文件]" + practiceResLinkPath);
                        ResLinkAsset asset = ScriptableObject.CreateInstance<ResLinkAsset>();
                        AddAssets(asset, practiceResFolder);
                        // 保存ScriptableObject资源
                        AssetDatabase.CreateAsset(asset, practiceResLinkPath);
                        ResLinkEditor.Save(asset);
                    }
                    else
                    {
                        ResLinkAsset asset = AssetDatabase.LoadAssetAtPath<ResLinkAsset>(practiceResLinkPath);
                        AddAssets(asset, practiceResFolder);
                        ResLinkEditor.Save(asset);
                        EditorUtility.SetDirty(asset);
                        AssetDatabase.SaveAssets();
                    }
                    AssetDatabase.Refresh();
                    CreateBaseConfig(id);
                }
                else
                {
                    var assetPath = AssetDatabase.GUIDToAssetPath(str);
                    Debug.LogWarning(@$"所选{assetPath}不合法");
                }
            }
        }

    }

    public static void AddAssets(ResLinkAsset asset, string path)
    {
        //加载game prefab
        var prefabsDir = Path.Combine(path, "prefab/game");
        Debug.Log($"prefabPath:{prefabsDir}");
        AddAsset(asset, prefabsDir, "*.prefab");

        //加载analysis 图片
        var analysisDir = Path.Combine(path, "analysis");
        Debug.Log($"analysisDir:{analysisDir}");
        AddAsset(asset, analysisDir, "*.png");

        //加载sound
        var soundDir = Path.Combine(path, "sound");
        Debug.Log($"soundDir:{soundDir}");
        AddAsset(asset, soundDir, "*.ogg");

        //加载config
        var configDir = Path.Combine(path, "config");
        Debug.Log($"configDir:{configDir}");
        AddAsset(asset, configDir, "*.json");

        // 加载node替换模板界面的资源
        SearchFilesRecursively(asset, Path.Combine(path, "node"));
    }


    public static void AddAsset(ResLinkAsset asset, string dirPath, string extension = null)
    {
        if (Directory.Exists(dirPath))
        {
            string[] paths = null;
            if(string.IsNullOrEmpty(extension))
            {
                paths = Directory.GetFiles(dirPath);
            }
            else
            {
                paths = Directory.GetFiles(dirPath, extension);
            }
            foreach (string path in paths)
            {
                string key = Path.GetFileNameWithoutExtension(path);
                if (!path.EndsWith(".meta") && !asset.Contains(key))
                {
                    var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path);
                    if(obj == null)
                    {
                        // 强制Unity重新导入资源
                        AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);

                        // 刷新编辑器，确保更改被识别
                        AssetDatabase.Refresh();
                        obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path);
                    }
                    if (obj is Texture2D)
                    {
                        obj = AssetDatabase.LoadAssetAtPath<Sprite>(path);
                    }

                    var item = new Item { Key = key, Val = obj };
                    asset.assets.Add(item);
                }

            }
        }
    }

    static void SearchFilesRecursively(ResLinkAsset asset, string path)
    {
        string[] entries = Directory.GetFileSystemEntries(path);
        foreach (string entry in entries)
        {
            if (File.Exists(entry))
            {
                // 处理文件逻辑
                var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(entry);
                if(obj == null)
                {
                    continue;
                } else if (obj is Texture2D)
                {
                    obj = AssetDatabase.LoadAssetAtPath<Sprite>(entry);
                }
                Match match = Regex.Match(obj.name, @"^node_\d+_\d+");
                if (match.Success)
                {
                    string key = match.Value;
                    if (!asset.Contains(key))
                    {
                        var item = new Item { Key = key, Val = obj };
                        asset.assets.Add(item);
                    }
                }
            }
            else if (Directory.Exists(entry))
            {
                SearchFilesRecursively(asset, entry);
            }
        }
    }

    [MenuItem("Assets/自定义创建/练环节/根据文档生成baseConfig")]
    public static void CreateNewPracticeConfig()
    {
        string[] strs = Selection.assetGUIDs;

        if (strs != null)
        {
            foreach (string str in strs)
            {
                string id = GetID(str);
                if (!String.IsNullOrEmpty(id))
                {
                    CreateBaseConfig(id);
                }
                else
                {
                    var assetPath = AssetDatabase.GUIDToAssetPath(str);
                    Debug.LogWarning(@$"所选{assetPath}不合法");
                }
            }
        }
    }

    public static void CreateBaseConfig(string id)
    {
        string gamesrcFolder = Path.Combine(scriptPathRoot, @$"practice{id}");
        string gameResFolder = Path.Combine(artPathRoot, @$"practice{id}");
        string configFolder = Path.Combine(gameResFolder, "config");
        if (!Directory.Exists(gamesrcFolder))
        {
            Debug.Log("[创建目录]" + gamesrcFolder);
            Directory.CreateDirectory(gamesrcFolder);
        }
        if (!Directory.Exists(configFolder))
        {
            Debug.Log("[创建目录]" + configFolder);
            Directory.CreateDirectory(configFolder);
        }

        //创建practiceConfig文件
        string practiceConfigLuaName = $"Practice{id}BaseConfig.lua";
        string practiceConfigJsonName = $"BaseConfig.json";
        string luaOutPutPath = Path.Combine(gamesrcFolder, practiceConfigLuaName);
        string jsonOutPutPath = Path.Combine(configFolder, practiceConfigJsonName);
        string svnPath = "https://10.3.254.33/repos/hongen_read/product/脑力练习脚本";
        string excelFile = SvnUtil.getFileByPattern(svnPath, id);
        //获取版本号
        XLWorkbook xlWorkBook = new XLWorkbook(excelFile);
        string sheetName = xlWorkBook.Worksheets.Worksheet(2).Name;
        Match match = Regex.Match(sheetName, @"\d+");
        string version = match.Success ? match.Value : "0";
        List<PracticeExcelPageRow> practiceExcelContentList = ExcelUtil.ReadExcelWithReflection<PracticeExcelPageRow>(excelFile, sheetName);
        PracticeBaseConfigOutPutModel practiceBaseConfigOutPutModel = new PracticeBaseConfigOutPutModel(practiceExcelContentList, version);
        string result = JsonConvert.SerializeObject(practiceBaseConfigOutPutModel, Formatting.Indented);
        File.WriteAllText(jsonOutPutPath, result);
        if (File.Exists(luaOutPutPath))
        {
            File.Delete(luaOutPutPath);
        }

        //新增音效sheet
        if(xlWorkBook.Worksheets.Count > 2)
        {
            //xlWorkBook.Worksheets.Delete(3);
            return;
        }

        IXLWorksheet sheet = xlWorkBook.AddWorksheet("旁白音效表", 3);
        int rowId = 1;
        int round = 1;
        sheet.Cell(rowId, 1).Value = "音效文本";
        sheet.Cell(rowId++, 2).Value = "音效文件名";
        foreach (PracticeBaseConfigModel model in practiceBaseConfigOutPutModel.PracticeBaseConfigModels) {
            //题目音效
            if (!String.IsNullOrEmpty(model.QuestionText) && model.GameType != "Sort")
            {
                sheet.Cell(rowId, 1).Value = model.QuestionText;
                sheet.Cell(rowId++, 2).Value = @$"question{round}";
            }

            //解析音效
            if (!String.IsNullOrEmpty(model.AnalysisText))
            {
                sheet.Cell(rowId, 1).Value = model.AnalysisText;
                sheet.Cell(rowId++, 2).Value = @$"analyse{round}";
            }

            //选项音效
            if(model.GameType == "Select3")
            {
                for(int i = 1; i <= 2; i++)
                {
                    sheet.Cell(rowId, 1).Value = model.AnswerText == null ? "" : model.AnswerText[i - 1];
                    sheet.Cell(rowId++, 2).Value = @$"answer_{round}_{i}";
                }
            }
            else if(model.AnswerText != null && model.AnswerText.Count > 0)
            {
                for (int i = 1; i <= model.AnswerText.Count; i++)
                {
                    sheet.Cell(rowId, 1).Value = model.AnswerText[i - 1];
                    sheet.Cell(rowId++, 2).Value = @$"answer_{round}_{i}";
                }
            }
            round++;
        }
        xlWorkBook.Save();
        SvnUtil.commit(excelFile, @$"{id}新增音效配置表");
    }

    [MenuItem("Assets/自定义创建/练环节/加载音频文件(覆盖)")]
    public static void CreateSoundAsset()
    {
        string[] strs = Selection.assetGUIDs;

        if (strs != null)
        {
            foreach (string str in strs)
            {
                string id = GetID(str);
                if (!String.IsNullOrEmpty(id))
                {
                    CreateSoundAsset(id, true);
                }
                else
                {
                    var assetPath = AssetDatabase.GUIDToAssetPath(str);
                    Debug.LogWarning(@$"所选{assetPath}不合法");
                }
            }
        }
    }

    /// <summary>
    /// 拉取音频资源
    /// </summary>
    /// <param name="id"> ID </param>
    /// <param name="isNeedCover"> 是否需要覆盖 </param>
    public static void CreateSoundAsset(string id, bool isNeedCover = false)
    {
        var destinationFolder = Path.Combine(artPathRoot, @$"practice{id}/sound");
        string svnPath = @$"https://10.3.254.33/repos/hongen_read/product/sound/练/{id}";
        CheckoutFolder(svnPath, destinationFolder, isNeedCover);
    }

    public static void CheckoutFolder(string svnPath, string destFolder, bool isNeedCover = false)
    {

        if (isNeedCover && Directory.Exists(destFolder))
        {
            Directory.Delete(destFolder, true);
        }

        if (!Directory.Exists(destFolder))
        {
            Directory.CreateDirectory(destFolder);
        }

        string sourceFolder = SvnUtil.getDir(svnPath, "files");
        if (String.IsNullOrEmpty(sourceFolder))
        {
            Debug.Log(@$"{svnPath}不存在。");
        }
        else
        {
            string[] files = Directory.GetFiles(sourceFolder);
            foreach (string file in files)
            {
                string fileName = Path.GetFileName(file);
                string destinationPath = Path.Combine(destFolder, fileName);
                if (!File.Exists(destinationPath))
                {
                    File.Move(Path.Combine(sourceFolder, fileName), destinationPath);
                }
            }
            AssetDatabase.Refresh();
            Debug.Log("资源克隆完成。");
        }

    }

    [MenuItem("Assets/自定义创建/练环节/定位Res")]
    public static void PingResFolder()
    {
        string assetGUID = Selection.assetGUIDs[0];
        string id = GetID(assetGUID);
        if (!String.IsNullOrEmpty(id))
        {
            DirUtil.skipToDir(Path.Combine(artPathRoot, @$"practice{id}"));
        }
        else
        {
            DirUtil.skipToDir(artPathRoot);
        }
    }

    [MenuItem("Assets/自定义创建/练环节/定位Src")]
    public static void PingSrcFolder()
    {

        string assetGUID = Selection.assetGUIDs[0];
        string id = GetID(assetGUID);
        if (!String.IsNullOrEmpty(id))
        {
            DirUtil.skipToDir(Path.Combine(scriptPathRoot, @$"practice{id}"));
        }
        else
        {
            DirUtil.skipToDir(scriptPathRoot);
        }

    }

    public static string GetID(string assetGUID)
    {
        var folderName = AssetDatabase.GUIDToAssetPath(assetGUID);
        if (!AssetDatabase.IsValidFolder(folderName))
        {
            folderName = Path.GetDirectoryName(folderName);
        }
        Match match = Regex.Match(folderName, @"\d+"); // 匹配一个或多个数字
        string id = match.Success ? match.Value : "";
        return id;
    }

    [MenuItem("工具/(ctrl + F2)打开unity存储目录 %F2")]
    public static void openFolder()
    {
        System.Diagnostics.Process.Start(UnityEngine.Application.persistentDataPath);
    }
}

