using Assets.app.Editor.tools.assetCopyer;
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;

 class WeeklyClassTools
{
    static string configSvnPath = "https://10.3.254.33/repos/hongen_read/product/周课/配置表/周课-路-带拼音.xlsx";
    const string weeklyArtPathRoot = "Assets/art/game/weekly/";
    const string weeklySrcPathRoot = "Assets/gamesrc/weekly/";

    const string practiceArtPathRoot = "Assets/art/game/practice/";

    [MenuItem("Assets/自定义创建/周课/创建周课")]
    public static void CreateAllWeekly()
    {
        Dictionary<string, List<WeeklyPracticeModel>> dict = GenBookExcel();
        Dictionary<string, WeelkyModel> weelkyModels = CreateWeeklyModelDicts();

        string[] strs = Selection.assetGUIDs;
        List<string> ids = new List<string>();
        if (strs != null)
        {
            foreach (string str in strs)
            {
                string id = PracticeCreator.GetID(str);
                if (!String.IsNullOrEmpty(id))
                {
                    ids.Add(id);
                }
            }
        }
        //ids = new List<string>{ "0216" };
        int index = 0;
        foreach (string id in dict.Keys)
        {
            index++;
            //if (index <= 12)
            //{
            //    continue;
            //}
            string artFolder = Path.Combine(weeklyArtPathRoot, @$"weekly{id}");
            //if (Directory.Exists(artFolder))
            //{
            //    continue;
            //}
            if (ids.Count == 0 || !ids.Contains(id))
            {
                continue;
            }
            //复制练环节资源
            CopyPracticeRes(id, dict[id]);

            //创建baseconfig
            WeelkyModel weelkyModel = weelkyModels[id];
            CreateConfig(weelkyModel);

            // 克隆音效资源
            CreateSoundAsset(id);

            //克隆音效资源
            CreateVideoAsset(id);

            //创建reslink
            var resLinkName = $"Weekly{id}resLink.asset";
            string resFolder = Path.Combine(weeklyArtPathRoot, @$"weekly{id}");
            var practiceResLinkPath = Path.Combine(weeklySrcPathRoot, @$"weekly{id}/{resLinkName}");
            if (File.Exists(practiceResLinkPath))
            {
                File.Delete(practiceResLinkPath);
                File.Delete(practiceResLinkPath);
            }
            Debug.Log("[创建reslink文件]" + practiceResLinkPath);
            ResLinkAsset asset = ScriptableObject.CreateInstance<ResLinkAsset>();
            PracticeCreator.AddAssets(asset, resFolder);
            //加载video
            PracticeCreator.AddAsset(asset, Path.Combine(resFolder, "video"));
            //加载bg
            string bgPath = Path.Combine(resFolder, "spine", "bg");
            if (Directory.Exists(bgPath))
            {
                string[] bgPaths = Directory.GetFiles(bgPath, "*.asset");
                foreach (string path in bgPaths)
                {
                    string key = "bg";
                    if (path.Contains("SkeletonData") && !asset.Contains(key))
                    {
                        var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path);

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

            }
            // 保存ScriptableObject资源
            AssetDatabase.CreateAsset(asset, practiceResLinkPath);
            ResLinkEditor.Save(asset);

            AssetDatabase.Refresh();
        }
        AssetDatabase.Refresh();
        AssetDatabase.SaveAssets();

    }


    public static void CopyPracticeRes(string id, List<WeeklyPracticeModel> weeklyPracticeModels)
    {
        string weeklySvnSoundPath = @$"https://10.3.254.33/repos/hongen_read/product/sound/周课/{id}";
        string weeklySoundFolder = SvnUtil.getDir(weeklySvnSoundPath, "files");
        string artFolder = Path.Combine(weeklyArtPathRoot, @$"weekly{id}");
        bool needCommit = false;
        List<string> resPaths = new List<string>();
        if (Directory.Exists(artFolder))
        {

            //Directory.Delete(Path.Combine(artFolder, "analysis"), true);
            //Directory.Delete(Path.Combine(artFolder, "node"), true);
            //Directory.Delete(Path.Combine(artFolder, "res"), true);
            return;
        }
        for (int i = 1; i <= weeklyPracticeModels.Count; ++i)
        {
            WeeklyPracticeModel weeklyPracticeModel = weeklyPracticeModels[i - 1];
            string bookId = weeklyPracticeModel.BookID;
            int BookIndex = int.Parse(weeklyPracticeModel.BookIndex);
            string srcResPath = Path.Combine(practiceArtPathRoot, @$"practice{bookId}");
            string practiceSvnSoundPath = @$"https://10.3.254.33/repos/hongen_read/product/sound/练/{bookId}";

            //copy node
            string[] nodeFolders = Directory.GetDirectories(Path.Combine(srcResPath, "node"));
            //string srcNode = Path.Combine(srcResPath, @$"node/game{BookIndex}");
            string srcNode = nodeFolders[BookIndex - 1];
            if (Directory.Exists(srcNode))
            {
                string[] files = Directory.GetFiles(srcNode);
                string destNode = Path.Combine(artFolder, @$"node/game{i}");
                string destResFolder = Path.Combine(artFolder, @$"res/game{i}");
                if (!Directory.Exists(destNode))
                {
                    Directory.CreateDirectory(destNode);
                }
                if (!Directory.Exists(destResFolder))
                {
                    Directory.CreateDirectory(destResFolder);
                }
                foreach (string file in files)
                {
                    string fileName = Path.GetFileName(file);
                    string destNodeName = fileName.Replace(@$"node_{BookIndex}", @$"node_{i}");
                    string destNodePath = Path.Combine(destNode, destNodeName);
                    File.Copy(file, destNodePath);
                    if (BookIndex != i && fileName.EndsWith(".asset"))
                    {
                        string name1 = Path.GetFileNameWithoutExtension(file);
                        string name2 = Path.GetFileNameWithoutExtension(destNodePath);
                        string contents = File.ReadAllText(destNodePath);
                        contents = contents.Replace(@$"m_Name: {name1}", @$"m_Name: {name2}");
                        File.WriteAllText(destNodePath, contents);
                    }
                    string extentision = Path.GetExtension(file);
                    // 复制依赖资源
                    if (extentision != ".png")
                    {
                        string[] dependencies = AssetDatabase.GetDependencies(file);
                        foreach (string dependency in dependencies)
                        {
                            if (dependency.Replace("/", "\\") == file.Replace("/", "\\"))
                            {
                                continue;
                            }
                            //依赖资源在本目录下的 spine资源 粒子资源等
                            if (!resPaths.Contains(dependency) && Path.GetDirectoryName(dependency).Contains(srcResPath.Replace("/", "\\")))
                            {
                                resPaths.Add(dependency);
                                File.Copy(dependency, Path.Combine(destResFolder, Path.GetFileName(dependency)), true);
                                string metaFileName = dependency + ".meta";
                                File.Copy(metaFileName, Path.Combine(destResFolder, Path.GetFileName(metaFileName)), true);
                            }
                        }
                    }

                }

            }

            //copy analysis
            string srcAnalysis = Path.Combine(srcResPath, "analysis");
            if (Directory.Exists(srcAnalysis))
            {
                string[] fileNames = Directory.GetFiles(srcAnalysis);
                string destAnalysis = Path.Combine(artFolder, "analysis");
                if (!Directory.Exists(destAnalysis))
                {
                    Directory.CreateDirectory(destAnalysis);
                }
                foreach (string filePath in fileNames)
                {
                    string fileName = Path.GetFileName(filePath);
                    if (fileName.Contains(@$"analysis_{BookIndex}"))
                    {
                        string destAnalysisPath = Path.Combine(destAnalysis, fileName.Replace(@$"analysis_{BookIndex}", @$"analysis_{i}"));
                        File.Copy(filePath, destAnalysisPath);
                    }
                }
            }

            // sound
            string rightPracticeSoundFile = SvnUtil.getFile(@$"{practiceSvnSoundPath}/s_right_{BookIndex}.ogg");
            string wrongPracticeSoundFile = SvnUtil.getFile(@$"{practiceSvnSoundPath}/s_wrong_{BookIndex}.ogg");
            string rightWeeklySound = Path.Combine(weeklySoundFolder, @$"s_right_{i}.ogg");
            string wrongWeeklySound = Path.Combine(weeklySoundFolder, @$"s_wrong_{i}.ogg");
            if (rightPracticeSoundFile != null && !File.Exists(rightWeeklySound))
            {
                needCommit = true;
                File.Move(rightPracticeSoundFile, rightWeeklySound);
            }
            if (wrongPracticeSoundFile != null && !File.Exists(wrongWeeklySound))
            {
                needCommit = true;
                File.Move(wrongPracticeSoundFile, wrongWeeklySound);
            }
        }
        if(needCommit)
        {
            SvnUtil.commitFolder(weeklySoundFolder, "提交音效");
        }
        //重新生成guids
        UtilGuids.RegenerateGuids(Path.GetFullPath(artFolder));
    }

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

        if (strs != null)
        {
            Dictionary<string, WeelkyModel> weelkyModels = CreateWeeklyModelDicts();
            foreach (string str in strs)
            {
                string id = PracticeCreator.GetID(str);
                if (!String.IsNullOrEmpty(id))
                {
                    CreateConfig(weelkyModels[id]);
                }
                else
                {
                    var assetPath = AssetDatabase.GUIDToAssetPath(str);
                    Debug.LogWarning(@$"所选{assetPath}不合法");
                }
            }
        }
    }

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

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

    public static void CreateSoundAsset(string id, bool isNeedCover = false)
    {
        var destinationFolder = Path.Combine(weeklyArtPathRoot, @$"weekly{id}/sound");
        string svnPath = @$"https://10.3.254.33/repos/hongen_read/product/sound/周课/{id}";
        PracticeCreator.CheckoutFolder(svnPath, destinationFolder, isNeedCover);
    }

    [MenuItem("Assets/自定义创建/周课/加载视频文件(覆盖)")]
    public static void CreateVideoAsset()
    {
        string[] strs = Selection.assetGUIDs;

        if (strs != null)
        {
            foreach (string str in strs)
            {
                string id = PracticeCreator.GetID(str);
                if (!String.IsNullOrEmpty(id))
                {
                    CreateVideoAsset(id);
                }
                else
                {
                    var assetPath = AssetDatabase.GUIDToAssetPath(str);
                    Debug.LogWarning(@$"所选{assetPath}不合法");
                }
            }
        }
    }
    public static void CreateVideoAsset(string id)
    {
        string destinationFolder = Path.Combine(weeklyArtPathRoot, @$"weekly{id}/video");
        if (!Directory.Exists(destinationFolder))
        {
            Directory.CreateDirectory(destinationFolder);
        }
        for(int index = 1; index <= 5; ++index)
        {
            string videoFilePath = SvnUtil.getFile(@$"https://10.3.254.33/repos/hongen_read/product/视频/720p/video_week_{id}_{index}.mp4");
            string srtFilePath = SvnUtil.getFile(@$"https://10.3.254.33/repos/hongen_read/product/视频/周课/{id}/video_week_{id}_{index}_srt.txt");
            string videoPath = Path.Combine(destinationFolder, @$"video_{index}.mp4");
            string strPath = Path.Combine(destinationFolder, @$"video_srt_{index}.txt");
            if (string.IsNullOrEmpty(videoFilePath))
            {
                videoFilePath = Path.Combine(weeklyArtPathRoot, "common", "video", @$"video_{index}.mp4");
            }
            if (string.IsNullOrEmpty(srtFilePath))
            {
                srtFilePath = Path.Combine(weeklyArtPathRoot, "common", "video", @$"video_srt_{index}.txt");
            }
            if (File.Exists(videoPath))
            {
                File.Delete(videoPath);
            }
            File.Copy(videoFilePath, videoPath, true);
            if (File.Exists(strPath))
            {
                File.Delete(strPath);
            }
            File.Copy(srtFilePath, strPath, true);
        }
        AssetDatabase.Refresh();

        var resLinkName = $"Weekly{id}resLink.asset";
        var practiceResLinkPath = Path.Combine(weeklySrcPathRoot, @$"weekly{id}/{resLinkName}");
        if (File.Exists(practiceResLinkPath))
        {
            ResLinkAsset asset = AssetDatabase.LoadAssetAtPath<ResLinkAsset>(practiceResLinkPath);
            PracticeCreator.AddAsset(asset, destinationFolder);
        }
    }

    public static void CreateConfig(WeelkyModel weelkyModel)
    {
        string id = weelkyModel.ID;
        string gamesrcFolder = Path.Combine(weeklySrcPathRoot, @$"weekly{id}");
        string gameResFolder = Path.Combine(weeklyArtPathRoot, @$"weekly{id}");
        string configFolder = Path.Combine(gameResFolder, "config");

        string configLuaName = $"Weekly{id}BaseConfig.lua";
        string configJsonName = $"BaseConfig.json";
        string luaOutPutPath = Path.Combine(gamesrcFolder, configLuaName);
        string jsonOutPutPath = Path.Combine(configFolder, configJsonName);
        if (!Directory.Exists(gamesrcFolder))
        {
            Debug.Log("[创建目录]" + gamesrcFolder);
            Directory.CreateDirectory(gamesrcFolder);
        }
        if (!Directory.Exists(configFolder))
        {
            Debug.Log("[创建目录]" + configFolder);
            Directory.CreateDirectory(configFolder);
        }

        string result = JsonConvert.SerializeObject(weelkyModel, Formatting.Indented);
        File.WriteAllText(jsonOutPutPath, result);
        if (File.Exists(luaOutPutPath))
        {
            File.Delete(luaOutPutPath);
        }

        //var resLinkName = $"Weekly{id}resLink.asset";
        //var practiceResLinkPath = Path.Combine(weeklySrcPathRoot, @$"weekly{id}/{resLinkName}");
        //ResLinkAsset asset = AssetDatabase.LoadAssetAtPath<ResLinkAsset>(practiceResLinkPath);
        //PracticeCreator.AddAsset(asset, configFolder, "*.json");
    }

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

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

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

    }

    [MenuItem("Assets/自定义创建/周课/生成音效配置表")]
    public static void CreateSoundConfig()
    {
        List<WeelkyModel> weelkyModels = CreateWeeklyModels();

        string excelFile = SvnUtil.getFile(configSvnPath);
        //新增音效sheet
        XLWorkbook xlWorkBook = new XLWorkbook(excelFile);
        for(int i = xlWorkBook.Worksheets.Count; i >= 3; i--)
        {
            xlWorkBook.Worksheets.Delete(i);
        }

        IXLWorksheet sheet = xlWorkBook.AddWorksheet("绘本音效表", 3);
        IXLWorksheet sheet2 = xlWorkBook.AddWorksheet("古诗音效表", 4);

        int round = 0;

        List<List<string>> list = new List<List<string>>();
        List<List<string>> list2 = new List<List<string>>();
        foreach (WeelkyModel model in weelkyModels)
        {
            list.Add(new List<string> {
                model.ID
            });
            round = 0;
            model.PracticeBaseConfigOutPutModel.PracticeBaseConfigModels.ForEach(practiceModel =>
            {
                round++;
                //题目音效
                if (!String.IsNullOrEmpty(practiceModel.QuestionText) && practiceModel.GameType != "Sort")
                {
                    list.Add(new List<string> {
                        practiceModel.QuestionText,
                        @$"question{round}"
                    });
                }

                //解析音效
                if (!String.IsNullOrEmpty(practiceModel.AnalysisText))
                {
                    list.Add(new List<string> {
                        practiceModel.AnalysisText,
                        @$"analyse{round}"
                    });
                   
                }

                //选项音效
                if (practiceModel.GameType == "Select3")
                {
                    for (int i = 1; i <= 2; i++)
                    {
                        list.Add(new List<string> {
                            practiceModel.AnswerText == null ? "" : practiceModel.AnswerText[i - 1],
                            @$"answer_{round}_{i}"
                        });
                    }
                }
                else if (practiceModel.AnswerText != null && practiceModel.AnswerText.Count > 0)
                {
                    for (int i = 1; i <= practiceModel.AnswerText.Count; i++)
                    {
                        list.Add(new List<string> {
                            practiceModel.AnswerText[i - 1],
                            @$"answer_{round}_{i}"
                        });
                    }
                }
            });

            list2.Add(new List<string> {
                model.ID
            });
            list2.Add(new List<string> {
                model.SayModel.Title,
                "poetryTitle"
            });
            list2.Add(new List<string> {
                @$"({model.SayModel.Dynasty}){model.SayModel.Author}",
                "poetryAuthor"
            });

            for (int i = 1; i <= model.SayModel.Content.Length; i++)
            {
                list2.Add(new List<string> {
                   model.SayModel.Content[i - 1],
                   @$"poetry{i}"
                });
            }

            list.Add(new List<string> {
                ""
            });
            list2.Add(new List<string> {
                ""
            });
        }
        ExcelUtil.SheetAddCell(sheet, list);
        ExcelUtil.SheetAddCell(sheet2, list2);
        xlWorkBook.Save();
        SvnUtil.commit(excelFile, @$"周课音效表");
    }

    [MenuItem("Assets/自定义创建/周课/生成古诗音效配置表")]
    public static void CreatePoetrySoundConfig()
    {
        List<WeeklySayModel> sayList = GenPoetryExcel();

        string excelFile = SvnUtil.getFile(configSvnPath);
        //新增音效sheet
        XLWorkbook xlWorkBook = new XLWorkbook(excelFile);
        for (int i = xlWorkBook.Worksheets.Count; i >= 4; i--)
        {
            xlWorkBook.Worksheets.Delete(i);
        }

        IXLWorksheet sheet2 = xlWorkBook.AddWorksheet("古诗音效表", 4);

        List<List<string>> list = new List<List<string>>();
        foreach (WeeklySayModel model in sayList)
        {
            list.Add(new List<string> {
                model.ID
            });
            list.Add(new List<string> {
                model.Title,
                "poetryTitle"
            });
            list.Add(new List<string> {
                @$"({model.Dynasty}){model.Author}",
                "poetryAuthor"
            });

            // 使用正则表达式分割古诗，并保留标点符号
            string pattern = @"(?<=[，。！？,])\s*";
            string[] lines = Regex.Split(model.Content, pattern);
            if (lines.Length > 0 && string.IsNullOrWhiteSpace(lines[^1]))
            {
                Array.Resize(ref lines, lines.Length - 1);
            }
            for (int i = 1; i <= lines.Length; i++)
            {
                list.Add(new List<string> {
                   lines[i - 1],
                   @$"poetry{i}"
                });
            }

            list.Add(new List<string> {
                ""
            });
        }
        ExcelUtil.SheetAddCell(sheet2, list);
        xlWorkBook.Save();
        SvnUtil.commit(excelFile, @$"周课音效表");
    }

    public static List<WeelkyModel> CreateWeeklyModels()
    {
        Dictionary<string, List<WeeklyPracticeModel>> dict = GenBookExcel();
        List<WeeklySayModel> sayList = GenPoetryExcel();

        List<WeelkyModel> weelkyModels = new List<WeelkyModel>();
        int count = Math.Min(dict.Count, sayList.Count);
        for (int i = 0; i < count; ++i)
        {
            weelkyModels.Add(new WeelkyModel(dict[sayList[i].ID], sayList[i]));
        }

        return weelkyModels;
    }

    public static Dictionary<string, WeelkyModel> CreateWeeklyModelDicts()
    {
        Dictionary<string, List<WeeklyPracticeModel>> dict = GenBookExcel();
        List<WeeklySayModel> sayList = GenPoetryExcel();

        Dictionary<string, WeelkyModel> weelkyModels = new Dictionary<string, WeelkyModel>();
        int count = Math.Min(dict.Count, sayList.Count);
        for (int i = 0; i < count; ++i)
        {
            string id = sayList[i].ID;
            weelkyModels.Add(id, new WeelkyModel(dict[id], sayList[i]));
        }

        return weelkyModels;
    }

    public static Dictionary<string, List<WeeklyPracticeModel>> GenBookExcel()
    {
        string excelFile = SvnUtil.getFile(configSvnPath);
        List<WeeklyPracticeModel> practiceList = ExcelUtil.ReadExcelWithReflection<WeeklyPracticeModel>(excelFile, "绘本");

        string lastId = "";
        string lastVersion = "";
        string lastBookId = "";
        Dictionary<string, List<WeeklyPracticeModel>> dict = new Dictionary<string, List<WeeklyPracticeModel>>();
        for (int i = 0; i < practiceList.Count; ++i)
        {
            WeeklyPracticeModel practiceModel = practiceList[i];
            if (string.IsNullOrEmpty(practiceModel.GameType))
            {
                break;
            }
            string id = practiceModel.ID;
            if (!string.IsNullOrEmpty(id))
            {
                lastId = id;
            }
            string version = practiceModel.Version;
            if (!string.IsNullOrEmpty(version))
            {
                lastVersion = version;
            } else
            {
                practiceModel.Version = lastVersion;
            }
            string bookId = practiceModel.BookID;
            if (!string.IsNullOrEmpty(bookId))
            {
                lastBookId = bookId;
            } else
            {
                practiceModel.BookID = lastBookId;
            }
            if (!dict.ContainsKey(lastId))
            {
                dict.Add(lastId, new List<WeeklyPracticeModel>());
            }
            dict[lastId].Add(practiceModel);
        }
        return dict;
    }

    public static List<WeeklySayModel> GenPoetryExcel()
    {
        string excelFile = SvnUtil.getFile(configSvnPath);
        List<WeeklySayModel> sayList = ExcelUtil.ReadExcelWithReflection<WeeklySayModel>(excelFile, "古诗");
        return sayList;
    }
}

