using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using OfficeOpenXml;
using ArtResource;
using Debug = UnityEngine.Debug;

namespace DesignTools
{
    /// <summary>
    /// Item配置Editor工具
    /// 读取Docs/config/Item.xlsx，关联所有Art_SO资源
    /// </summary>
    public class ItemConfigEditor : EditorWindow
    {
        private const string ART_SO_PATH = "Assets/Art_SubModule/Art_SO";
        private const string ITEM_EXCEL_NAME = "Item.xlsx";
        private const string LIMITED_TIME_EVENT_EXCEL_NAME = "LimitedTimeEvent.xlsx";
        private const string AVATAR_EXCEL_NAME = "Avatar.xlsx";
        private const string FACE_EXCEL_NAME = "Face.xlsx";
        private const string EMOJI_EXCEL_NAME = "Emoji.xlsx";
        private const string LANGUAGE_EXCEL_NAME = "AllLanguage.xlsx";
        private const string ITEM_SHEET_NAME = "Item";
        private const string EVENT_SHEET_NAME = "Event";
        private const string AVATAR_SHEET_NAME = "Avatar";
        private const string FACE_SHEET_NAME = "Face";
        private const string EMOJI_SHEET_NAME = "Emoji";
        private const string LANGUAGE_SHEET_NAME = "client";
        private const string DOCS_PATH_PREF_KEY = "ItemConfigEditor_DocsPath";
        private const string DESIGN_SUBMODULE_PATH = "Assets/Design_SubModule";
        
        // IType类型定义
        private static readonly Dictionary<int, string> ITEM_TYPES = new Dictionary<int, string>
        {
            { 1, "能量" },
            { 2, "星星" },
            { 3, "钻石" },
            { 97, "Playroom宠物道具" },
            { 98, "卡牌" },
            { 99, "背包道具" },
            { 100, "棋子" },
            { 101, "卡包" },
            { 102, "限时事件" },
            { 103, "小猪存钱罐" },
            { 104, "万能卡" },
            { 105, "头像框" },
            { 106, "活动代币" },
            { 107, "竞赛游戏代币" },
            { 108, "Pet Playroom拜访道具" },
            { 109, "表情" },
            { 110, "头像" },
            { 111, "Playroom装饰" },
            { 112, "Playroom服装" },
            { 113, "Playroom装饰套装" },
            { 114, "Playroom服装套装" },
            { 115, "Playroom道具宝箱" },
            { 116, "活动通行证代币道具" }
        };

        private string docsRootPath = "";
        private List<ItemData> allItemDataList = new List<ItemData>();
        private List<ItemData> filteredItemDataList = new List<ItemData>();
        private Dictionary<int, string> limitedTimeEventDict = new Dictionary<int, string>(); // Id -> Name
        private Dictionary<int, AvatarData> avatarDict = new Dictionary<int, AvatarData>(); // Id -> AvatarData
        private Dictionary<int, FaceData> faceDict = new Dictionary<int, FaceData>(); // Id -> FaceData
        private Dictionary<int, EmojiData> emojiDict = new Dictionary<int, EmojiData>(); // Id -> EmojiData
        private Dictionary<string, Dictionary<string, string>> languageDict = new Dictionary<string, Dictionary<string, string>>();
        private List<ArtTableSO> allArtTables = new List<ArtTableSO>();
        private Dictionary<string, List<ArtTableSO>> artTablesByFolder = new Dictionary<string, List<ArtTableSO>>(); // 按文件夹分组的表格
        
        private ArtTableSO headFrameResourceSO;
        private ArtTableSO headResourceSO;
        private ArtTableSO emojiResourceSO;
        
        // Res选择状态缓存 (ItemData的Id -> 选择的组名)
        private Dictionary<int, string> resSelectedFolderCache = new Dictionary<int, string>();

        private Vector2 scrollPosition;
        private bool isDataLoaded = false;
        
        // 筛选和分页
        private int selectedIType = -1;
        private int currentPage = 0;
        private int itemsPerPage = 20;
        private int totalPages = 0;

        [MenuItem("策划工具/Item配置")]
        public static void ShowWindow()
        {
            var window = GetWindow<ItemConfigEditor>("Item配置");
            window.minSize = new Vector2(1200, 700);
            window.Show();
        }

        private void OnEnable()
        {
            // 读取上次保存的路径
            if (EditorPrefs.HasKey(DOCS_PATH_PREF_KEY))
            {
                docsRootPath = EditorPrefs.GetString(DOCS_PATH_PREF_KEY);
            }
        }

        private void OnGUI()
        {
            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
            EditorGUILayout.LabelField("Item配置工具", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space(5);

            // Docs路径选择
            EditorGUILayout.BeginVertical("box");
            EditorGUILayout.LabelField("Docs项目根目录", EditorStyles.boldLabel);
            
            EditorGUILayout.BeginHorizontal();
            docsRootPath = EditorGUILayout.TextField("路径", docsRootPath);
            if (GUILayout.Button("选择文件夹", GUILayout.Width(100)))
            {
                string selectedPath = EditorUtility.OpenFolderPanel("选择Docs项目根目录", "", "");
                if (!string.IsNullOrEmpty(selectedPath))
                {
                    docsRootPath = selectedPath;
                    EditorPrefs.SetString(DOCS_PATH_PREF_KEY, docsRootPath);
                }
            }
            EditorGUILayout.EndHorizontal();

            if (GUILayout.Button("加载配置数据", GUILayout.Height(30)))
            {
                LoadData();
            }

            EditorGUILayout.EndVertical();

            EditorGUILayout.Space(5);

            // 数据编辑区域
            if (isDataLoaded)
            {
                DrawFilterAndDataEditor();
            }
            else
            {
                EditorGUILayout.HelpBox("请先选择Docs根目录并加载配置数据", MessageType.Info);
            }
        }

        /// <summary>
        /// 加载配置数据
        /// </summary>
        private void LoadData()
        {
            try
            {
                // 校验路径
                if (string.IsNullOrEmpty(docsRootPath) || !Directory.Exists(docsRootPath))
                {
                    EditorUtility.DisplayDialog("错误", "请选择有效的Docs根目录", "确定");
                    return;
                }

                // 1. 检查Docs是否为Git仓库并更新
                if (!CheckAndUpdateDocsRepository())
                {
                    return;
                }

                // 2. 检查Design_SubModule分支
                if (!CheckAndSwitchDesignSubModuleBranch())
                {
                    return;
                }

                // 3. 加载所有Art_SO资源
                LoadAllArtTableSO();

                // 4. 加载语言表
                LoadLanguageData();

                // 5. 加载LimitedTimeEvent表
                LoadLimitedTimeEventData();
                
                // 6. 加载Avatar表
                LoadAvatarData();
                
                // 7. 加载Face表
                LoadFaceData();
                
                // 8. 加载Emoji表
                LoadEmojiData();

                // 9. 加载Item表
                LoadItemExcel();

                isDataLoaded = true;
                EditorUtility.DisplayDialog("成功", "配置数据加载成功！", "确定");
            }
            catch (Exception e)
            {
                EditorUtility.DisplayDialog("错误", $"加载数据失败: {e.Message}\n{e.StackTrace}", "确定");
                isDataLoaded = false;
            }
        }

        /// <summary>
        /// 执行Git命令
        /// </summary>
        private string ExecuteGitCommand(string workingDirectory, string arguments, out bool success)
        {
            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    FileName = "git",
                    Arguments = arguments,
                    WorkingDirectory = workingDirectory,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = true
                };

                using (Process process = Process.Start(startInfo))
                {
                    string output = process.StandardOutput.ReadToEnd();
                    string error = process.StandardError.ReadToEnd();
                    process.WaitForExit();

                    success = process.ExitCode == 0;
                    return success ? output : error;
                }
            }
            catch (Exception e)
            {
                success = false;
                return $"执行Git命令失败: {e.Message}";
            }
        }

        /// <summary>
        /// 检查并更新Docs仓库
        /// </summary>
        private bool CheckAndUpdateDocsRepository()
        {
            string gitPath = Path.Combine(docsRootPath, ".git");
            if (!Directory.Exists(gitPath))
            {
                EditorUtility.DisplayDialog("错误", 
                    $"Docs目录不是Git仓库\n路径: {docsRootPath}\n\n请确保Docs项目已正确克隆", 
                    "确定");
                return false;
            }

            EditorUtility.DisplayProgressBar("检查更新", "正在检查Docs仓库远程更新...", 0.3f);

            string fetchResult = ExecuteGitCommand(docsRootPath, "fetch", out bool fetchSuccess);
            
            if (!fetchSuccess)
            {
                EditorUtility.ClearProgressBar();
                EditorUtility.DisplayDialog("Git Fetch失败", 
                    $"无法检查远程更新:\n{fetchResult}\n\n请在SourceTree或GitHubDesktop中检查网络连接和仓库状态", 
                    "确定");
                return false;
            }

            EditorUtility.DisplayProgressBar("检查更新", "正在检查是否有新提交...", 0.6f);

            string statusResult = ExecuteGitCommand(docsRootPath, "status -uno", out bool statusSuccess);
            
            if (!statusSuccess)
            {
                EditorUtility.ClearProgressBar();
                EditorUtility.DisplayDialog("Git Status失败", 
                    $"无法获取仓库状态:\n{statusResult}\n\n请在SourceTree或GitHubDesktop中检查仓库状态", 
                    "确定");
                return false;
            }

            if (statusResult.Contains("Changes not staged") || statusResult.Contains("Changes to be committed"))
            {
                EditorUtility.ClearProgressBar();
                bool proceed = EditorUtility.DisplayDialog("警告：有未提交的更改", 
                    "Docs仓库中有未提交的更改，这可能导致拉取时产生冲突。\n\n建议先提交或暂存这些更改。\n\n是否继续加载配置？（不推荐）", 
                    "继续（不推荐）", "取消，前往处理");
                
                if (!proceed)
                {
                    Debug.Log("请在SourceTree或GitHubDesktop中处理未提交的更改");
                    return false;
                }
            }

            if (statusResult.Contains("Your branch is behind"))
            {
                EditorUtility.DisplayProgressBar("更新中", "正在从远程拉取最新代码...", 0.8f);
                
                string pullResult = ExecuteGitCommand(docsRootPath, "pull", out bool pullSuccess);
                
                EditorUtility.ClearProgressBar();
                
                if (!pullSuccess)
                {
                    if (pullResult.Contains("CONFLICT") || pullResult.Contains("conflict"))
                    {
                        EditorUtility.DisplayDialog("拉取失败：存在冲突", 
                            $"拉取远程更新时发生冲突:\n{pullResult}\n\n请在SourceTree或GitHubDesktop中解决冲突后再操作", 
                            "确定");
                    }
                    else
                    {
                        EditorUtility.DisplayDialog("拉取失败", 
                            $"无法拉取远程更新:\n{pullResult}\n\n请在SourceTree或GitHubDesktop中检查并解决问题", 
                            "确定");
                    }
                    return false;
                }
                
                Debug.Log($"Docs仓库已更新到最新版本:\n{pullResult}");
                EditorUtility.DisplayDialog("更新成功", "Docs仓库已更新到最新版本", "确定");
            }
            else
            {
                EditorUtility.ClearProgressBar();
                Debug.Log("Docs仓库已是最新版本");
            }

            return true;
        }

        /// <summary>
        /// 检查并切换Design_SubModule到main分支
        /// </summary>
        private bool CheckAndSwitchDesignSubModuleBranch()
        {
            string designSubModulePath = Path.Combine(Application.dataPath, "..", DESIGN_SUBMODULE_PATH);
            designSubModulePath = Path.GetFullPath(designSubModulePath);

            if (!Directory.Exists(designSubModulePath))
            {
                EditorUtility.DisplayDialog("错误", 
                    $"Design_SubModule目录不存在:\n{designSubModulePath}\n\n请确保子模块已正确初始化", 
                    "确定");
                return false;
            }

            EditorUtility.DisplayProgressBar("检查分支", "正在检查Design_SubModule分支...", 0.5f);

            string branchResult = ExecuteGitCommand(designSubModulePath, "branch --show-current", out bool branchSuccess);
            
            if (!branchSuccess)
            {
                EditorUtility.ClearProgressBar();
                EditorUtility.DisplayDialog("Git Branch失败", 
                    $"无法获取当前分支:\n{branchResult}\n\n请在SourceTree或GitHubDesktop中检查Design_SubModule状态", 
                    "确定");
                return false;
            }

            string currentBranch = branchResult.Trim();
            
            if (currentBranch != "main")
            {
                EditorUtility.DisplayProgressBar("切换分支", "正在切换到main分支...", 0.8f);
                
                string checkoutResult = ExecuteGitCommand(designSubModulePath, "checkout main", out bool checkoutSuccess);
                
                EditorUtility.ClearProgressBar();
                
                if (!checkoutSuccess)
                {
                    EditorUtility.DisplayDialog("切换分支失败", 
                        $"无法切换到main分支:\n{checkoutResult}\n\n当前分支: {currentBranch}\n\n请在SourceTree或GitHubDesktop中手动切换到main分支", 
                        "确定");
                    return false;
                }
                
                Debug.Log($"Design_SubModule已从 {currentBranch} 切换到 main 分支");
            }
            else
            {
                EditorUtility.ClearProgressBar();
                Debug.Log("Design_SubModule已在main分支");
            }

            return true;
        }

        /// <summary>
        /// 加载所有Art_SO资源
        /// </summary>
        private void LoadAllArtTableSO()
        {
            allArtTables.Clear();
            artTablesByFolder.Clear();
            
            string[] guids = AssetDatabase.FindAssets("t:ArtTableSO", new[] { ART_SO_PATH });
            foreach (string guid in guids)
            {
                string path = AssetDatabase.GUIDToAssetPath(guid);
                ArtTableSO tableSO = AssetDatabase.LoadAssetAtPath<ArtTableSO>(path);
                if (tableSO != null)
                {
                    allArtTables.Add(tableSO);
                    
                    // 按文件夹分组
                    string folder = GetRelativeFolder(path);
                    if (!artTablesByFolder.ContainsKey(folder))
                    {
                        artTablesByFolder[folder] = new List<ArtTableSO>();
                    }
                    artTablesByFolder[folder].Add(tableSO);
                }
            }
            
            // 加载特定资源
            headFrameResourceSO = allArtTables.FirstOrDefault(x => x.TableName == "HeadFrameResource");
            headResourceSO = allArtTables.FirstOrDefault(x => x.TableName == "HeadResource");
            emojiResourceSO = allArtTables.FirstOrDefault(x => x.TableName == "EmojiResource");
            
            Debug.Log($"加载了 {allArtTables.Count} 个ArtTableSO资源，分为 {artTablesByFolder.Count} 个组");
        }
        
        /// <summary>
        /// 获取相对文件夹路径
        /// </summary>
        private string GetRelativeFolder(string assetPath)
        {
            string relativePath = assetPath.Replace(ART_SO_PATH + "/", "");
            int lastSlash = relativePath.LastIndexOf('/');
            if (lastSlash >= 0)
            {
                return relativePath.Substring(0, lastSlash);
            }
            return "根目录";
        }

        /// <summary>
        /// 加载语言数据
        /// </summary>
        private void LoadLanguageData()
        {
            languageDict.Clear();

            string languageExcelPath = Path.Combine(docsRootPath, "config", LANGUAGE_EXCEL_NAME);
            if (!File.Exists(languageExcelPath))
            {
                Debug.LogWarning($"未找到语言表: {languageExcelPath}");
                return;
            }

            using (var package = new ExcelPackage(new FileInfo(languageExcelPath)))
            {
                var worksheet = package.Workbook.Worksheets[LANGUAGE_SHEET_NAME];
                if (worksheet == null)
                {
                    Debug.LogWarning($"语言表中未找到Sheet: {LANGUAGE_SHEET_NAME}");
                    return;
                }

                // 查找Key列和语言列
                int keyColumnIndex = -1;
                int zhCNColumnIndex = -1;
                int columnCount = worksheet.Dimension.Columns;

                for (int col = 1; col <= columnCount; col++)
                {
                    string header = worksheet.Cells[1, col].Text;
                    if (header == "key")
                    {
                        keyColumnIndex = col;
                    }
                    else if (header == "zh_CN")
                    {
                        zhCNColumnIndex = col;
                    }
                }

                if (keyColumnIndex < 0)
                {
                    Debug.LogWarning("语言表中未找到Key列");
                    return;
                }

                // 读取数据（从第3行开始）
                int rowCount = worksheet.Dimension.Rows;
                for (int row = 3; row <= rowCount; row++)
                {
                    string key = worksheet.Cells[row, keyColumnIndex].Text;
                    if (string.IsNullOrEmpty(key)) continue;

                    if (!languageDict.ContainsKey(key))
                    {
                        languageDict[key] = new Dictionary<string, string>();
                    }

                    if (zhCNColumnIndex > 0)
                    {
                        languageDict[key]["zh_CN"] = worksheet.Cells[row, zhCNColumnIndex].Text;
                    }
                }
            }
        }

        /// <summary>
        /// 加载限时事件数据
        /// </summary>
        private void LoadLimitedTimeEventData()
        {
            limitedTimeEventDict.Clear();

            string eventExcelPath = Path.Combine(docsRootPath, "config", LIMITED_TIME_EVENT_EXCEL_NAME);
            if (!File.Exists(eventExcelPath))
            {
                Debug.LogWarning($"未找到限时事件表: {eventExcelPath}");
                return;
            }

            using (var package = new ExcelPackage(new FileInfo(eventExcelPath)))
            {
                var worksheet = package.Workbook.Worksheets[EVENT_SHEET_NAME];
                if (worksheet == null)
                {
                    Debug.LogWarning($"限时事件表中未找到Sheet: {EVENT_SHEET_NAME}");
                    return;
                }

                // 查找Id和Name列
                int idCol = -1, nameCol = -1;
                int columnCount = worksheet.Dimension.Columns;

                for (int col = 1; col <= columnCount; col++)
                {
                    string header = worksheet.Cells[1, col].Text;
                    if (header == "Id") idCol = col;
                    else if (header == "Name") nameCol = col;
                }

                if (idCol < 0 || nameCol < 0)
                {
                    Debug.LogWarning("限时事件表结构不正确");
                    return;
                }

                // 读取数据（从第3行开始）
                int rowCount = worksheet.Dimension.Rows;
                for (int row = 3; row <= rowCount; row++)
                {
                    string idText = worksheet.Cells[row, idCol].Text;
                    if (string.IsNullOrEmpty(idText)) continue;

                    if (int.TryParse(idText, out int id))
                    {
                        string name = worksheet.Cells[row, nameCol].Text;
                        limitedTimeEventDict[id] = name;
                    }
                }
            }
        }

        /// <summary>
        /// 加载Avatar数据
        /// </summary>
        private void LoadAvatarData()
        {
            avatarDict.Clear();

            string avatarExcelPath = Path.Combine(docsRootPath, "config", AVATAR_EXCEL_NAME);
            if (!File.Exists(avatarExcelPath))
            {
                Debug.LogWarning($"未找到Avatar表: {avatarExcelPath}");
                return;
            }

            using (var package = new ExcelPackage(new FileInfo(avatarExcelPath)))
            {
                var worksheet = package.Workbook.Worksheets[AVATAR_SHEET_NAME];
                if (worksheet == null)
                {
                    Debug.LogWarning($"Avatar表中未找到Sheet: {AVATAR_SHEET_NAME}");
                    return;
                }

                // 查找列
                int idCol = -1, nameKeyCol = -1, iconCol = -1;
                int columnCount = worksheet.Dimension.Columns;

                for (int col = 1; col <= columnCount; col++)
                {
                    string header = worksheet.Cells[1, col].Text;
                    if (header == "Id") idCol = col;
                    else if (header == "NameKey") nameKeyCol = col;
                    else if (header == "Icon") iconCol = col;
                }

                if (idCol < 0 || nameKeyCol < 0 || iconCol < 0)
                {
                    Debug.LogWarning("Avatar表结构不正确");
                    return;
                }

                // 读取数据（从第3行开始）
                int rowCount = worksheet.Dimension.Rows;
                for (int row = 3; row <= rowCount; row++)
                {
                    string idText = worksheet.Cells[row, idCol].Text;
                    if (string.IsNullOrEmpty(idText)) continue;

                    if (int.TryParse(idText, out int id))
                    {
                        string nameKey = worksheet.Cells[row, nameKeyCol].Text;
                        string iconText = worksheet.Cells[row, iconCol].Text;

                        avatarDict[id] = new AvatarData
                        {
                            Id = id,
                            NameKey = nameKey,
                            IconName = iconText ?? ""
                        };
                    }
                }
            }
        }

        /// <summary>
        /// 加载Face数据
        /// </summary>
        private void LoadFaceData()
        {
            faceDict.Clear();

            string faceExcelPath = Path.Combine(docsRootPath, "config", FACE_EXCEL_NAME);
            if (!File.Exists(faceExcelPath))
            {
                Debug.LogWarning($"未找到Face表: {faceExcelPath}");
                return;
            }

            using (var package = new ExcelPackage(new FileInfo(faceExcelPath)))
            {
                var worksheet = package.Workbook.Worksheets[FACE_SHEET_NAME];
                if (worksheet == null)
                {
                    Debug.LogWarning($"Face表中未找到Sheet: {FACE_SHEET_NAME}");
                    return;
                }

                // 查找列
                int idCol = -1, nameKeyCol = -1, iconCol = -1;
                int columnCount = worksheet.Dimension.Columns;

                for (int col = 1; col <= columnCount; col++)
                {
                    string header = worksheet.Cells[1, col].Text;
                    if (header == "Id") idCol = col;
                    else if (header == "NameKey") nameKeyCol = col;
                    else if (header == "Icon") iconCol = col;
                }

                if (idCol < 0 || nameKeyCol < 0 || iconCol < 0)
                {
                    Debug.LogWarning("Face表结构不正确");
                    return;
                }

                // 读取数据（从第3行开始）
                int rowCount = worksheet.Dimension.Rows;
                for (int row = 3; row <= rowCount; row++)
                {
                    string idText = worksheet.Cells[row, idCol].Text;
                    if (string.IsNullOrEmpty(idText)) continue;

                    if (int.TryParse(idText, out int id))
                    {
                        string nameKey = worksheet.Cells[row, nameKeyCol].Text;
                        string iconText = worksheet.Cells[row, iconCol].Text;

                        faceDict[id] = new FaceData
                        {
                            Id = id,
                            NameKey = nameKey,
                            IconName = iconText ?? ""
                        };
                    }
                }
            }
        }

        /// <summary>
        /// 加载Emoji数据
        /// </summary>
        private void LoadEmojiData()
        {
            emojiDict.Clear();

            string emojiExcelPath = Path.Combine(docsRootPath, "config", EMOJI_EXCEL_NAME);
            if (!File.Exists(emojiExcelPath))
            {
                Debug.LogWarning($"未找到Emoji表: {emojiExcelPath}");
                return;
            }

            using (var package = new ExcelPackage(new FileInfo(emojiExcelPath)))
            {
                var worksheet = package.Workbook.Worksheets[EMOJI_SHEET_NAME];
                if (worksheet == null)
                {
                    Debug.LogWarning($"Emoji表中未找到Sheet: {EMOJI_SHEET_NAME}");
                    return;
                }

                // 查找列
                int idCol = -1, nameKeyCol = -1, iconCol = -1;
                int columnCount = worksheet.Dimension.Columns;

                for (int col = 1; col <= columnCount; col++)
                {
                    string header = worksheet.Cells[1, col].Text;
                    if (header == "Id") idCol = col;
                    else if (header == "NameKey") nameKeyCol = col;
                    else if (header == "Icon") iconCol = col;
                }

                if (idCol < 0 || nameKeyCol < 0 || iconCol < 0)
                {
                    Debug.LogWarning("Emoji表结构不正确");
                    return;
                }

                // 读取数据（从第3行开始）
                int rowCount = worksheet.Dimension.Rows;
                for (int row = 3; row <= rowCount; row++)
                {
                    string idText = worksheet.Cells[row, idCol].Text;
                    if (string.IsNullOrEmpty(idText)) continue;

                    if (int.TryParse(idText, out int id))
                    {
                        string nameKey = worksheet.Cells[row, nameKeyCol].Text;
                        string iconText = worksheet.Cells[row, iconCol].Text;

                        emojiDict[id] = new EmojiData
                        {
                            Id = id,
                            NameKey = nameKey,
                            IconName = iconText ?? ""
                        };
                    }
                }
            }
        }

        /// <summary>
        /// 加载Item.xlsx
        /// </summary>
        private void LoadItemExcel()
        {
            allItemDataList.Clear();

            string itemExcelPath = Path.Combine(docsRootPath, "config", ITEM_EXCEL_NAME);
            if (!File.Exists(itemExcelPath))
            {
                throw new Exception($"未找到Item配置文件: {itemExcelPath}");
            }

            using (var package = new ExcelPackage(new FileInfo(itemExcelPath)))
            {
                var worksheet = package.Workbook.Worksheets[ITEM_SHEET_NAME];
                if (worksheet == null)
                {
                    throw new Exception($"Item.xlsx中未找到Sheet: {ITEM_SHEET_NAME}");
                }

                // 读取表头（第1行）
                int idCol = -1, nameCol = -1, iTypeCol = -1, effectCol = -1, resCol = -1;
                int columnCount = worksheet.Dimension.Columns;

                for (int col = 1; col <= columnCount; col++)
                {
                    string header = worksheet.Cells[1, col].Text;
                    if (header == "Id") idCol = col;
                    else if (header == "Name") nameCol = col;
                    else if (header == "IType") iTypeCol = col;
                    else if (header == "Effect") effectCol = col;
                    else if (header == "Res") resCol = col;
                }

                if (idCol < 0 || nameCol < 0 || iTypeCol < 0)
                {
                    throw new Exception("Item.xlsx表结构不正确，缺少必要列（Id/Name/IType）");
                }

                // 读取数据（从第3行开始）
                int rowCount = worksheet.Dimension.Rows;
                for (int row = 3; row <= rowCount; row++)
                {
                    string idText = worksheet.Cells[row, idCol].Text;
                    if (string.IsNullOrEmpty(idText)) continue;

                    if (!int.TryParse(idText, out int id)) continue;

                    string name = worksheet.Cells[row, nameCol].Text;
                    string iTypeText = worksheet.Cells[row, iTypeCol].Text;
                    string effect = effectCol > 0 ? worksheet.Cells[row, effectCol].Text : "";
                    string res = resCol > 0 ? worksheet.Cells[row, resCol].Text : "";

                    if (!int.TryParse(iTypeText, out int iType)) continue;

                    var itemData = new ItemData
                    {
                        Id = id,
                        Name = name,
                        IType = iType,
                        Effect = effect,
                        Res = res
                    };

                    allItemDataList.Add(itemData);
                }
            }
        }

        /// <summary>
        /// 绘制筛选和数据编辑器
        /// </summary>
        private void DrawFilterAndDataEditor()
        {
            EditorGUILayout.BeginVertical("box");
            
            // IType筛选
            EditorGUILayout.LabelField("Item类型筛选", EditorStyles.boldLabel);
            EditorGUILayout.BeginHorizontal();
            
            // 创建下拉列表选项
            var typeOptions = new List<string> { "请选择类型..." };
            var typeValues = new List<int> { -1 };
            
            // 排除103、104、108和97、98、111-115
            foreach (var kvp in ITEM_TYPES.OrderBy(x => x.Key))
            {
                // 跳过不需要显示的类型
                if (kvp.Key == 103 || kvp.Key == 104 || kvp.Key == 108 || 
                    kvp.Key == 97 || kvp.Key == 98 || 
                    (kvp.Key >= 111 && kvp.Key <= 115))
                {
                    continue;
                }
                
                typeOptions.Add(kvp.Value);
                typeValues.Add(kvp.Key);
            }
            
            int currentIndex = typeValues.IndexOf(selectedIType);
            if (currentIndex < 0) currentIndex = 0;
            
            int newIndex = EditorGUILayout.Popup("选择类型", currentIndex, typeOptions.ToArray());
            if (newIndex != currentIndex)
            {
                selectedIType = typeValues[newIndex];
                FilterItemsByType();
                currentPage = 0;
            }
            
            if (selectedIType > 0)
            {
                EditorGUILayout.LabelField($"当前类型ID: {selectedIType}", GUILayout.Width(150));
            }
            
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.EndVertical();
            
            EditorGUILayout.Space(5);
            
            // 如果已选择类型，显示数据列表
            if (selectedIType > 0)
            {
                DrawItemDataList();
            }
            else
            {
                EditorGUILayout.HelpBox("请先选择Item类型进行筛选", MessageType.Info);
            }
        }

        /// <summary>
        /// 根据IType筛选数据
        /// </summary>
        private void FilterItemsByType()
        {
            filteredItemDataList = allItemDataList.Where(x => x.IType == selectedIType).ToList();
            totalPages = Mathf.CeilToInt((float)filteredItemDataList.Count / itemsPerPage);
        }

        /// <summary>
        /// 绘制Item数据列表
        /// </summary>
        private void DrawItemDataList()
        {
            EditorGUILayout.BeginVertical("box");
            
            // 顶部工具栏
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField($"数据列表（共 {filteredItemDataList.Count} 条）", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            
            GUI.backgroundColor = Color.cyan;
            if (GUILayout.Button("+ 添加Item", GUILayout.Height(25), GUILayout.Width(100)))
            {
                AddNewItem();
            }
            GUI.backgroundColor = Color.white;
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.Space(3);
            
            // 分页控制
            DrawPagination();
            
            EditorGUILayout.Space(3);

            scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(400));

            // 表头
            DrawTableHeader();

            // 数据行
            int startIndex = currentPage * itemsPerPage;
            int endIndex = Mathf.Min(startIndex + itemsPerPage, filteredItemDataList.Count);
            
            for (int i = startIndex; i < endIndex; i++)
            {
                DrawItemDataRow(filteredItemDataList[i]);
            }

            EditorGUILayout.EndScrollView();
            
            EditorGUILayout.Space(5);
            
            // 分页控制（底部）
            DrawPagination();
            
            EditorGUILayout.EndVertical();

            EditorGUILayout.Space(10);

            // 保存按钮
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            
            GUI.backgroundColor = Color.green;
            if (GUILayout.Button("保存配置到Excel", GUILayout.Height(30), GUILayout.Width(200)))
            {
                SaveData();
            }
            GUI.backgroundColor = Color.white;
            
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();
        }

        /// <summary>
        /// 绘制分页控制
        /// </summary>
        private void DrawPagination()
        {
            EditorGUILayout.BeginHorizontal();
            
            EditorGUILayout.LabelField("每页显示:", GUILayout.Width(70));
            itemsPerPage = EditorGUILayout.IntField(itemsPerPage, GUILayout.Width(50));
            itemsPerPage = Mathf.Max(1, itemsPerPage);
            
            GUILayout.Space(20);
            
            GUI.enabled = currentPage > 0;
            if (GUILayout.Button("第一页", GUILayout.Width(60)))
            {
                currentPage = 0;
            }
            if (GUILayout.Button("上一页", GUILayout.Width(60)))
            {
                currentPage--;
            }
            GUI.enabled = true;
            
            EditorGUILayout.LabelField($"第 {currentPage + 1} / {Mathf.Max(1, totalPages)} 页", GUILayout.Width(100));
            
            int newPage = EditorGUILayout.IntField(currentPage + 1, GUILayout.Width(50)) - 1;
            if (newPage != currentPage && newPage >= 0 && newPage < totalPages)
            {
                currentPage = newPage;
            }
            
            GUI.enabled = currentPage < totalPages - 1;
            if (GUILayout.Button("下一页", GUILayout.Width(60)))
            {
                currentPage++;
            }
            if (GUILayout.Button("最后一页", GUILayout.Width(70)))
            {
                currentPage = totalPages - 1;
            }
            GUI.enabled = true;
            
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();
        }

        /// <summary>
        /// 绘制表头
        /// </summary>
        private void DrawTableHeader()
        {
            EditorGUILayout.BeginHorizontal("box");
            EditorGUILayout.LabelField("Id", EditorStyles.boldLabel, GUILayout.Width(50));
            EditorGUILayout.LabelField("Name", EditorStyles.boldLabel, GUILayout.Width(120));
            EditorGUILayout.LabelField("IType", EditorStyles.boldLabel, GUILayout.Width(50));
            EditorGUILayout.LabelField("Effect", EditorStyles.boldLabel, GUILayout.Width(200));
            EditorGUILayout.LabelField("Res", EditorStyles.boldLabel, GUILayout.Width(200));
            EditorGUILayout.LabelField("预览", EditorStyles.boldLabel, GUILayout.Width(100));
            EditorGUILayout.LabelField("操作", EditorStyles.boldLabel, GUILayout.Width(60));
            EditorGUILayout.EndHorizontal();
        }

        /// <summary>
        /// 绘制单行数据
        /// </summary>
        private void DrawItemDataRow(ItemData data)
        {
            EditorGUILayout.BeginHorizontal("box");

            // Id（可编辑）
            data.Id = EditorGUILayout.IntField(data.Id, GUILayout.Width(50));

            // Name（可编辑）
            data.Name = EditorGUILayout.TextField(data.Name, GUILayout.Width(120));

            // IType（只读）
            GUI.enabled = false;
            EditorGUILayout.IntField(data.IType, GUILayout.Width(50));
            GUI.enabled = true;

            // Effect（根据IType不同显示不同内容）
            DrawEffectField(data);

            // Res（资源选择）
            DrawResField(data);

            // 预览
            DrawResPreview(data);

            // 删除按钮
            GUI.backgroundColor = Color.red;
            if (GUILayout.Button("删除", GUILayout.Width(60)))
            {
                if (EditorUtility.DisplayDialog("确认删除", $"确定要删除ID为{data.Id}的Item吗？", "删除", "取消"))
                {
                    filteredItemDataList.Remove(data);
                    allItemDataList.Remove(data);
                    FilterItemsByType(); // 重新计算分页
                }
            }
            GUI.backgroundColor = Color.white;

            EditorGUILayout.EndHorizontal();
        }

        /// <summary>
        /// 绘制Effect字段（统一文本编辑）
        /// </summary>
        private void DrawEffectField(ItemData data)
        {
            EditorGUILayout.BeginVertical(GUILayout.Width(200));
            
            // 当前使用统一的文本编辑框处理所有类型
            EditorGUI.BeginChangeCheck();
            string newEffect = EditorGUILayout.TextField(data.Effect ?? "", GUILayout.Width(200));
            if (EditorGUI.EndChangeCheck())
            {
                data.Effect = newEffect;
            }
            
            /* 
            // 以下是之前按类型特殊处理的代码，已注释保留，方便之后还原特殊处理
            switch (data.IType)
            {
                case 100: // 棋子 - 不显示
                case 1:   // 能量
                case 2:   // 星星
                case 3:   // 钻石
                    EditorGUILayout.LabelField("-", GUILayout.Width(200));
                    break;
                    
                case 101: // 卡包 - 只读
                case 106: // 活动代币 - 没有Effect
                case 107: // 竞赛游戏代币 - 没有Effect
                case 99:  // 背包道具 - 没有Effect
                    EditorGUILayout.LabelField(string.IsNullOrEmpty(data.Effect) ? "-" : data.Effect, GUILayout.Width(200));
                    break;
                    
                case 102: // 限时事件
                    DrawLimitedTimeEventEffect(data);
                    break;
                    
                case 105: // 头像框 - 已改用Res字段
                    EditorGUILayout.LabelField("请使用Res字段配置", GUILayout.Width(200));
                    break;
                    
                case 110: // 头像 - 已改用Res字段
                    EditorGUILayout.LabelField("请使用Res字段配置", GUILayout.Width(200));
                    break;
                    
                case 109: // 表情 - 已改用Res字段
                    EditorGUILayout.LabelField("请使用Res字段配置", GUILayout.Width(200));
                    break;
                    
                default:
                    data.Effect = EditorGUILayout.TextField(data.Effect, GUILayout.Width(200));
                    break;
            }
            */
            
            EditorGUILayout.EndVertical();
        }

        /// <summary>
        /// 绘制限时事件Effect
        /// </summary>
        private void DrawLimitedTimeEventEffect(ItemData data)
        {
            // Effect格式: "eventId,seconds"
            string[] parts = data.Effect.Split(',');
            int eventId = 0;
            int seconds = 0;
            
            if (parts.Length >= 1) int.TryParse(parts[0], out eventId);
            if (parts.Length >= 2) int.TryParse(parts[1], out seconds);
            
            EditorGUILayout.BeginHorizontal();
            
            // 事件选择下拉框
            var eventOptions = new List<string> { "请选择..." };
            var eventIds = new List<int> { 0 };
            
            foreach (var kvp in limitedTimeEventDict.OrderBy(x => x.Key))
            {
                eventOptions.Add(kvp.Value);
                eventIds.Add(kvp.Key);
            }
            
            int currentIndex = eventIds.IndexOf(eventId);
            if (currentIndex < 0) currentIndex = 0;
            
            int newIndex = EditorGUILayout.Popup(currentIndex, eventOptions.ToArray(), GUILayout.Width(120));
            int newEventId = eventIds[newIndex];
            
            // 秒数输入
            int newSeconds = EditorGUILayout.IntField(seconds, GUILayout.Width(60));
            
            // 显示时间格式
            int minutes = newSeconds / 60;
            int secs = newSeconds % 60;
            GUI.enabled = false;
            EditorGUILayout.TextField($"{minutes:D2}:{secs:D2}", GUILayout.Width(50));
            GUI.enabled = true;
            
            EditorGUILayout.EndHorizontal();
            
            // 验证提示
            if (newEventId > 0 && !limitedTimeEventDict.ContainsKey(newEventId))
            {
                EditorGUILayout.HelpBox("没有这个限时事件", MessageType.Error);
            }
            
            // 更新数据
            data.Effect = $"{newEventId},{newSeconds}";
        }

        /// <summary>
        /// 绘制头像框Effect
        /// </summary>
        private void DrawHeadFrameEffect(ItemData data)
        {
            // Effect格式: "avatarId,0"
            string[] parts = string.IsNullOrEmpty(data.Effect) ? new string[0] : data.Effect.Split(',');
            int avatarId = -1;
            
            if (parts.Length >= 1) int.TryParse(parts[0], out avatarId);
            
            // 创建下拉选项
            var options = new List<string> { "请选择..." };
            var ids = new List<int> { -1 };
            
            foreach (var kvp in avatarDict.OrderBy(x => x.Key))
            {
                string name = kvp.Value.NameKey;
                if (languageDict.ContainsKey(kvp.Value.NameKey) && languageDict[kvp.Value.NameKey].ContainsKey("zh_CN"))
                {
                    name = languageDict[kvp.Value.NameKey]["zh_CN"];
                }
                options.Add($"{name} (ID:{kvp.Key})");
                ids.Add(kvp.Key);
            }
            
            int currentIndex = ids.IndexOf(avatarId);
            if (currentIndex < 0) currentIndex = 0;
            
            EditorGUI.BeginChangeCheck();
            int newIndex = EditorGUILayout.Popup(currentIndex, options.ToArray(), GUILayout.Width(200));
            if (EditorGUI.EndChangeCheck())
            {
                int newAvatarId = ids[newIndex];
                data.Effect = $"{newAvatarId},0";
            }
        }

        /// <summary>
        /// 绘制头像Effect
        /// </summary>
        private void DrawFaceEffect(ItemData data)
        {
            // Effect格式: "faceId,0"
            string[] parts = string.IsNullOrEmpty(data.Effect) ? new string[0] : data.Effect.Split(',');
            int faceId = -1;
            
            if (parts.Length >= 1) int.TryParse(parts[0], out faceId);
            
            // 创建下拉选项
            var options = new List<string> { "请选择..." };
            var ids = new List<int> { -1 };
            
            foreach (var kvp in faceDict.OrderBy(x => x.Key))
            {
                string name = kvp.Value.NameKey;
                if (languageDict.ContainsKey(kvp.Value.NameKey) && languageDict[kvp.Value.NameKey].ContainsKey("zh_CN"))
                {
                    name = languageDict[kvp.Value.NameKey]["zh_CN"];
                }
                options.Add($"{name} (ID:{kvp.Key})");
                ids.Add(kvp.Key);
            }
            
            int currentIndex = ids.IndexOf(faceId);
            if (currentIndex < 0) currentIndex = 0;
            
            EditorGUI.BeginChangeCheck();
            int newIndex = EditorGUILayout.Popup(currentIndex, options.ToArray(), GUILayout.Width(200));
            if (EditorGUI.EndChangeCheck())
            {
                int newFaceId = ids[newIndex];
                data.Effect = $"{newFaceId},0";
            }
        }

        /// <summary>
        /// 绘制表情Effect
        /// </summary>
        private void DrawEmojiEffect(ItemData data)
        {
            // Effect格式: "emojiId,0"
            string[] parts = string.IsNullOrEmpty(data.Effect) ? new string[0] : data.Effect.Split(',');
            int emojiId = -1;
            
            if (parts.Length >= 1) int.TryParse(parts[0], out emojiId);
            
            // 创建下拉选项
            var options = new List<string> { "请选择..." };
            var ids = new List<int> { -1 };
            
            foreach (var kvp in emojiDict.OrderBy(x => x.Key))
            {
                string name = kvp.Value.NameKey;
                if (languageDict.ContainsKey(kvp.Value.NameKey) && languageDict[kvp.Value.NameKey].ContainsKey("zh_CN"))
                {
                    name = languageDict[kvp.Value.NameKey]["zh_CN"];
                }
                options.Add($"{name} (ID:{kvp.Key})");
                ids.Add(kvp.Key);
            }
            
            int currentIndex = ids.IndexOf(emojiId);
            if (currentIndex < 0) currentIndex = 0;
            
            EditorGUI.BeginChangeCheck();
            int newIndex = EditorGUILayout.Popup(currentIndex, options.ToArray(), GUILayout.Width(200));
            if (EditorGUI.EndChangeCheck())
            {
                int newEmojiId = ids[newIndex];
                data.Effect = $"{newEmojiId},0";
            }
        }

        /// <summary>
        /// 绘制Res字段（三级选择：组->表->Item）
        /// </summary>
        private void DrawResField(ItemData data)
        {
            EditorGUILayout.BeginVertical(GUILayout.Width(200));
            
            // Res格式: "TableName,ItemName"
            string[] parts = string.IsNullOrEmpty(data.Res) ? new string[0] : data.Res.Split(',');
            string tableName = parts.Length > 0 ? parts[0] : "";
            string itemName = parts.Length > 1 ? parts[1] : "";
            
            // 查找当前表格和所属文件夹
            ArtTableSO currentTable = null;
            string currentFolder = "";
            
            // 优先使用缓存的组选择
            if (resSelectedFolderCache.ContainsKey(data.Id))
            {
                currentFolder = resSelectedFolderCache[data.Id];
            }
            
            // 如果有Res数据，从Res推导组和表
            if (!string.IsNullOrEmpty(tableName))
            {
                currentTable = allArtTables.FirstOrDefault(x => x.TableName == tableName);
                if (currentTable != null)
                {
                    string tablePath = AssetDatabase.GetAssetPath(currentTable);
                    string folderFromRes = GetRelativeFolder(tablePath);
                    // 如果没有缓存或缓存不一致，更新缓存
                    if (string.IsNullOrEmpty(currentFolder) || currentFolder != folderFromRes)
                    {
                        currentFolder = folderFromRes;
                        resSelectedFolderCache[data.Id] = currentFolder;
                    }
                }
            }
            
            // 第一级：选择组
            var folderOptions = new List<string> { "未选择" };
            folderOptions.AddRange(artTablesByFolder.Keys.OrderBy(k => k));
            
            int currentFolderIndex = 0;
            if (!string.IsNullOrEmpty(currentFolder))
            {
                currentFolderIndex = folderOptions.IndexOf(currentFolder);
                if (currentFolderIndex < 0) currentFolderIndex = 0;
            }
            
            EditorGUI.BeginChangeCheck();
            int newFolderIndex = EditorGUILayout.Popup(currentFolderIndex, folderOptions.ToArray(), GUILayout.Width(200));
            bool folderChanged = EditorGUI.EndChangeCheck();
            
            if (folderChanged)
            {
                if (newFolderIndex > 0 && newFolderIndex < folderOptions.Count)
                {
                    currentFolder = folderOptions[newFolderIndex];
                    // 保存到缓存
                    resSelectedFolderCache[data.Id] = currentFolder;
                    // 组改变时，清空表和Item选择，并清空Res数据
                    currentTable = null;
                    tableName = "";
                    itemName = "";
                    data.Res = ""; // 清空Res，避免旧数据干扰
                }
                else if (newFolderIndex == 0)
                {
                    // 选择"未选择"，清空所有
                    currentFolder = "";
                    if (resSelectedFolderCache.ContainsKey(data.Id))
                    {
                        resSelectedFolderCache.Remove(data.Id);
                    }
                    currentTable = null;
                    data.Res = "";
                    EditorGUILayout.EndVertical();
                    return;
                }
            }
            else if (newFolderIndex > 0 && newFolderIndex < folderOptions.Count)
            {
                currentFolder = folderOptions[newFolderIndex];
            }
            else if (newFolderIndex == 0)
            {
                // 当前是"未选择"状态
                EditorGUILayout.EndVertical();
                return;
            }
            
            // 第二级：选择表
            List<ArtTableSO> tablesInFolder = artTablesByFolder.ContainsKey(currentFolder) 
                ? artTablesByFolder[currentFolder] 
                : new List<ArtTableSO>();
            
            var tableOptions = new List<string> { "未选择" };
            tableOptions.AddRange(tablesInFolder.Select(t => $"{t.TableName}(ID:{t.TableId})"));
            
            int currentTableIndex = 0;
            if (currentTable != null && !folderChanged)
            {
                int foundIndex = tablesInFolder.FindIndex(t => t.TableName == currentTable.TableName);
                if (foundIndex >= 0)
                {
                    currentTableIndex = foundIndex + 1; // +1 因为有"未选择"选项
                }
            }
            
            EditorGUI.BeginChangeCheck();
            int newTableIndex = EditorGUILayout.Popup(currentTableIndex, tableOptions.ToArray(), GUILayout.Width(200));
            bool tableSelectionChanged = EditorGUI.EndChangeCheck();
            
            if (tableSelectionChanged)
            {
                if (newTableIndex > 0 && newTableIndex <= tablesInFolder.Count)
                {
                    currentTable = tablesInFolder[newTableIndex - 1]; // -1 因为有"未选择"选项
                    // 表格改变时，清空Item选择
                    data.Res = $"{currentTable.TableName},";
                    itemName = "";
                }
                else if (newTableIndex == 0)
                {
                    // 选择"未选择"
                    currentTable = null;
                    data.Res = "";
                    EditorGUILayout.EndVertical();
                    return;
                }
            }
            else if (newTableIndex > 0 && newTableIndex <= tablesInFolder.Count)
            {
                currentTable = tablesInFolder[newTableIndex - 1];
            }
            else
            {
                // 当前表是"未选择"状态
                EditorGUILayout.EndVertical();
                return;
            }
            
            // 第三级：选择Item
            if (currentTable != null && currentTable.Items != null && currentTable.Items.Count > 0)
            {
                var itemOptions = new List<string> { "未选择" };
                itemOptions.AddRange(currentTable.Items.Select(item => $"{item.Name}(ID:{item.Id})"));
                
                int currentItemIndex = 0;
                if (!string.IsNullOrEmpty(itemName) && !tableSelectionChanged)
                {
                    int foundIndex = currentTable.Items.FindIndex(item => item.Name == itemName);
                    if (foundIndex >= 0)
                    {
                        currentItemIndex = foundIndex + 1; // +1 因为有"未选择"选项
                    }
                }
                
                EditorGUI.BeginChangeCheck();
                int newItemIndex = EditorGUILayout.Popup(currentItemIndex, itemOptions.ToArray(), GUILayout.Width(200));
                if (EditorGUI.EndChangeCheck())
                {
                    if (newItemIndex > 0 && newItemIndex <= currentTable.Items.Count)
                    {
                        data.Res = $"{currentTable.TableName},{currentTable.Items[newItemIndex - 1].Name}";
                    }
                    else if (newItemIndex == 0)
                    {
                        // 选择"未选择"
                        data.Res = $"{currentTable.TableName},";
                    }
                }
            }
            
            EditorGUILayout.EndVertical();
        }

        /// <summary>
        /// 绘制资源预览（统一使用Res字段）
        /// </summary>
        private void DrawResPreview(ItemData data)
        {
            Sprite previewSprite = null;
            string tipMessage = "";
            
            // 统一从Res字段获取预览
            previewSprite = GetResPreview(data);
            
            if (previewSprite != null)
            {
                Rect rect = GUILayoutUtility.GetRect(80, 80, GUILayout.Width(100));
                GUI.DrawTexture(rect, previewSprite.texture, ScaleMode.ScaleToFit);
            }
            else
            {
                if (!string.IsNullOrEmpty(tipMessage))
                {
                    GUILayout.Box(tipMessage, GUILayout.Width(100), GUILayout.Height(80));
                }
                else
                {
                    GUILayout.Box("无预览", GUILayout.Width(100), GUILayout.Height(80));
                }
            }
        }

        /// <summary>
        /// 获取头像框预览
        /// </summary>
        private Sprite GetHeadFramePreview(ItemData data)
        {
            if (headFrameResourceSO == null) return null;
            if (string.IsNullOrEmpty(data.Effect)) return null;
            
            string[] parts = data.Effect.Split(',');
            if (parts.Length < 1 || !int.TryParse(parts[0], out int avatarId)) return null;
            if (avatarId < 0) return null;
            
            if (!avatarDict.ContainsKey(avatarId)) return null;
            
            string iconName = avatarDict[avatarId].IconName;
            if (string.IsNullOrEmpty(iconName)) return null;
            var item = headFrameResourceSO.Items.FirstOrDefault(x => x.Name == iconName);
            
            return item?.Sprite;
        }

        /// <summary>
        /// 获取头像预览
        /// </summary>
        private Sprite GetFacePreview(ItemData data)
        {
            if (headResourceSO == null) return null;
            if (string.IsNullOrEmpty(data.Effect)) return null;
            
            string[] parts = data.Effect.Split(',');
            if (parts.Length < 1 || !int.TryParse(parts[0], out int faceId)) return null;
            if (faceId < 0) return null;
            
            if (!faceDict.ContainsKey(faceId)) return null;
            
            string iconName = faceDict[faceId].IconName;
            if (string.IsNullOrEmpty(iconName)) return null;
            var item = headResourceSO.Items.FirstOrDefault(x => x.Name == iconName);
            
            return item?.Sprite;
        }

        /// <summary>
        /// 获取表情预览
        /// </summary>
        private Sprite GetEmojiPreview(ItemData data)
        {
            if (emojiResourceSO == null) return null;
            if (string.IsNullOrEmpty(data.Effect)) return null;
            
            string[] parts = data.Effect.Split(',');
            if (parts.Length < 1 || !int.TryParse(parts[0], out int emojiId)) return null;
            if (emojiId < 0) return null;
            
            if (!emojiDict.ContainsKey(emojiId)) return null;
            
            string iconName = emojiDict[emojiId].IconName;
            if (string.IsNullOrEmpty(iconName)) return null;
            var item = emojiResourceSO.Items.FirstOrDefault(x => x.Name == iconName);
            
            return item?.Sprite;
        }

        /// <summary>
        /// 获取Res资源预览
        /// </summary>
        private Sprite GetResPreview(ItemData data)
        {
            if (string.IsNullOrEmpty(data.Res)) return null;
            
            string[] parts = data.Res.Split(',');
            if (parts.Length < 2) return null;
            
            string tableName = parts[0];
            string artItemName = parts[1];
            
            if (string.IsNullOrEmpty(tableName) || string.IsNullOrEmpty(artItemName)) return null;
            
            var table = allArtTables.FirstOrDefault(x => x.TableName == tableName);
            if (table == null) return null;
            
            var item = table.Items.FirstOrDefault(x => x.Name == artItemName);
            return item?.Sprite;
        }

        /// <summary>
        /// 添加新Item
        /// </summary>
        private void AddNewItem()
        {
            // 找到当前IType的最大ID
            int maxId = 0;
            foreach (var item in allItemDataList.Where(x => x.IType == selectedIType))
            {
                if (item.Id > maxId) maxId = item.Id;
            }
            
            // 自增ID并检查重复
            int newId = maxId + 1;
            while (allItemDataList.Any(x => x.Id == newId))
            {
                newId++;
            }
            
            var newItem = new ItemData
            {
                Id = newId,
                Name = $"新Item_{newId}",
                IType = selectedIType,
                Effect = "",
                Res = ""
            };
            
            allItemDataList.Add(newItem);
            FilterItemsByType();
            
            // 跳转到最后一页
            currentPage = totalPages - 1;
        }

        /// <summary>
        /// 根据Res字段获取完整资源路径
        /// </summary>
        private string GetFullResourcePath(string res)
        {
            if (string.IsNullOrEmpty(res)) return "";
            
            string[] parts = res.Split(',');
            if (parts.Length < 2) return "";
            
            string tableName = parts[0];
            string artItemName = parts[1];
            
            if (string.IsNullOrEmpty(tableName) || string.IsNullOrEmpty(artItemName)) return "";
            
            var table = allArtTables.FirstOrDefault(x => x.TableName == tableName);
            if (table == null) return "";
            
            var item = table.Items.FirstOrDefault(x => x.Name == artItemName);
            if (item == null) return "";
            if (item.Sprite == null) return "";
            
            return AssetDatabase.GetAssetPath(item.Sprite);
        }

        /// <summary>
        /// 保存数据到Excel
        /// </summary>
        private void SaveData()
        {
            try
            {
                // ID重复检查
                var duplicateIds = allItemDataList.GroupBy(x => x.Id)
                    .Where(g => g.Count() > 1)
                    .Select(g => g.Key)
                    .ToList();
                    
                if (duplicateIds.Count > 0)
                {
                    EditorUtility.DisplayDialog("错误", 
                        $"存在重复的ID: {string.Join(", ", duplicateIds)}\n请修正后再保存", 
                        "确定");
                    return;
                }
                
                // 验证限时事件
                foreach (var item in allItemDataList.Where(x => x.IType == 102))
                {
                    if (!string.IsNullOrEmpty(item.Effect))
                    {
                        string[] parts = item.Effect.Split(',');
                        if (parts.Length >= 1 && int.TryParse(parts[0], out int eventId))
                        {
                            if (eventId > 0 && !limitedTimeEventDict.ContainsKey(eventId))
                            {
                                EditorUtility.DisplayDialog("错误", 
                                    $"ID {item.Id} 的限时事件ID {eventId} 不存在\n请修正后再保存", 
                                    "确定");
                                return;
                            }
                        }
                    }
                }
                
                string itemExcelPath = Path.Combine(docsRootPath, "config", ITEM_EXCEL_NAME);
                
                using (var package = new ExcelPackage(new FileInfo(itemExcelPath)))
                {
                    var worksheet = package.Workbook.Worksheets[ITEM_SHEET_NAME];
                    
                    // 找到列索引
                    int idCol = -1, nameCol = -1, iTypeCol = -1, effectCol = -1, resCol = -1, fullResourcePathCol = -1;
                    int columnCount = worksheet.Dimension.Columns;
                    
                    for (int col = 1; col <= columnCount; col++)
                    {
                        string header = worksheet.Cells[1, col].Text;
                        if (header == "Id") idCol = col;
                        else if (header == "Name") nameCol = col;
                        else if (header == "IType") iTypeCol = col;
                        else if (header == "Effect") effectCol = col;
                        else if (header == "Res") resCol = col;
                        else if (header == "FullResourcePath") fullResourcePathCol = col;
                    }
                    
                    // 创建Id到行号的映射（读取现有数据）
                    var existingRowMap = new Dictionary<int, int>();
                    int existingRowCount = worksheet.Dimension.Rows;
                    
                    for (int row = 3; row <= existingRowCount; row++)
                    {
                        string idText = worksheet.Cells[row, idCol].Text;
                        if (!string.IsNullOrEmpty(idText) && int.TryParse(idText, out int id))
                        {
                            existingRowMap[id] = row;
                        }
                    }
                    
                    // 更新或新增数据
                    int nextNewRow = existingRowCount + 1;
                    
                    foreach (var item in allItemDataList.OrderBy(x => x.Id))
                    {
                        int targetRow;
                        
                        // 如果该ID已存在，更新对应行；否则添加新行
                        if (existingRowMap.ContainsKey(item.Id))
                        {
                            targetRow = existingRowMap[item.Id];
                        }
                        else
                        {
                            targetRow = nextNewRow;
                            nextNewRow++;
                        }
                        
                        // 只更新我们管理的列
                        worksheet.Cells[targetRow, idCol].Value = item.Id;
                        worksheet.Cells[targetRow, nameCol].Value = item.Name;
                        worksheet.Cells[targetRow, iTypeCol].Value = item.IType;
                        
                        if (effectCol > 0)
                        {
                            worksheet.Cells[targetRow, effectCol].Value = item.Effect;
                        }
                        
                        if (resCol > 0)
                        {
                            worksheet.Cells[targetRow, resCol].Value = item.Res;
                        }
                        
                        // 写入完整资源路径
                        if (fullResourcePathCol > 0)
                        {
                            string fullPath = GetFullResourcePath(item.Res);
                            worksheet.Cells[targetRow, fullResourcePathCol].Value = fullPath;
                        }
                    }
                    
                    // 删除已不存在的数据行（只清空我们管理的列）
                    var currentIds = allItemDataList.Select(x => x.Id).ToHashSet();
                    for (int row = 3; row <= existingRowCount; row++)
                    {
                        string idText = worksheet.Cells[row, idCol].Text;
                        if (!string.IsNullOrEmpty(idText) && int.TryParse(idText, out int id))
                        {
                            if (!currentIds.Contains(id))
                            {
                                // 只清空我们管理的列，保留其他列
                                worksheet.Cells[row, idCol].Value = null;
                                worksheet.Cells[row, nameCol].Value = null;
                                worksheet.Cells[row, iTypeCol].Value = null;
                                if (effectCol > 0) worksheet.Cells[row, effectCol].Value = null;
                                if (resCol > 0) worksheet.Cells[row, resCol].Value = null;
                                if (fullResourcePathCol > 0) worksheet.Cells[row, fullResourcePathCol].Value = null;
                            }
                        }
                    }
                    
                    package.Save();
                }
                
                EditorUtility.DisplayDialog("成功", "配置已保存到Excel文件", "确定");
            }
            catch (Exception e)
            {
                EditorUtility.DisplayDialog("错误", $"保存失败: {e.Message}\n{e.StackTrace}", "确定");
            }
        }

        /// <summary>
        /// Item数据类
        /// </summary>
        private class ItemData
        {
            public int Id;
            public string Name;
            public int IType;
            public string Effect;
            public string Res;
        }

        /// <summary>
        /// Avatar数据类
        /// </summary>
        private class AvatarData
        {
            public int Id;
            public string NameKey;
            public string IconName = "";
        }

        /// <summary>
        /// Face数据类
        /// </summary>
        private class FaceData
        {
            public int Id;
            public string NameKey;
            public string IconName = "";
        }

        /// <summary>
        /// Emoji数据类
        /// </summary>
        private class EmojiData
        {
            public int Id;
            public string NameKey;
            public string IconName = "";
        }
    }
}
