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

namespace DesignTools.LimitedTimeEvent
{
    /// <summary>
    /// 限时事件投放配置工具
    /// 读取 Docs/config/LimitedTimeEvent.xlsx 的 Series Sheet
    /// Items字段通过读取 Item.xlsx 中 IType=102 的条目进行选择
    /// </summary>
    public class LimitedEventSeriesEditor : BaseDesignToolEditor
    {
        private const string LIMITED_TIME_EVENT_EXCEL_NAME = "LimitedTimeEvent.xlsx";
        private const string ITEM_EXCEL_NAME = "Item.xlsx";
        private const string SERIES_SHEET_NAME = "Jackpot";
        private const string ITEM_SHEET_NAME = "Item";
        private const string ART_SO_PATH = "Assets/Art_SubModule/Art_SO";
        private const int HEADER_ROW = 1;
        private const int DATA_START_ROW = 3;

        // 列索引
        private int colId = -1;
        private int colBonusLv = -1;
        private int colItems = -1;
        private int colType = -1;
        private int colProb = -1;
        private int colNote = -1;

        private readonly List<SeriesRowData> seriesDataList = new List<SeriesRowData>();

        private readonly List<LimitedEventItemInfo> limitedEventItems = new List<LimitedEventItemInfo>();
        private readonly Dictionary<int, LimitedEventItemInfo> limitedEventItemById = new Dictionary<int, LimitedEventItemInfo>();
        private readonly Dictionary<string, ArtTableSO> artTableByName = new Dictionary<string, ArtTableSO>(StringComparer.OrdinalIgnoreCase);

        [MenuItem("策划工具/限时事件/限时事件投放")]
        public static void ShowWindow()
        {
            var window = GetWindow<LimitedEventSeriesEditor>("限时事件投放");
            window.minSize = window.GetMinWindowSize();
            window.Show();
        }

        protected override string GetDocsPathPrefKey()
        {
            return "LimitedEventSeriesEditor_DocsPath";
        }

        protected override string GetWindowTitle()
        {
            return "限时事件投放配置工具";
        }

        protected override Vector2 GetMinWindowSize()
        {
            return new Vector2(1100, 600);
        }

        protected override void LoadConfigData()
        {
            LoadAllArtTableSO();
            LoadLimitedEventItems();
            LoadSeriesSheet();
        }

        protected override void DrawDataEditor()
        {
            DrawTableHeader();
            scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
            for (int i = 0; i < seriesDataList.Count; i++)
            {
                DrawSeriesRow(seriesDataList[i]);
            }
            EditorGUILayout.EndScrollView();

            EditorGUILayout.Space(4);
            DrawAddRemoveButtons();
        }

        protected override void SaveDataToExcel()
        {
            SaveSeriesSheet();
        }

        #region 数据加载

        /// <summary>
        /// 加载所有ArtTableSO资源
        /// </summary>
        private void LoadAllArtTableSO()
        {
            artTableByName.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 || string.IsNullOrEmpty(tableSO.TableName))
                {
                    continue;
                }

                artTableByName[tableSO.TableName] = tableSO;
            }

            Debug.Log($"加载了 {artTableByName.Count} 个 ArtTableSO 资源表");
        }

        /// <summary>
        /// 从Item.xlsx加载IType=102的道具
        /// </summary>
        private void LoadLimitedEventItems()
        {
            limitedEventItems.Clear();
            limitedEventItemById.Clear();

            string excelPath = GetDocsConfigFilePath(ITEM_EXCEL_NAME);
            if (!File.Exists(excelPath))
            {
                Debug.LogWarning($"未找到 {ITEM_EXCEL_NAME}: {excelPath}");
                return;
            }

            using (var package = new ExcelPackage(new FileInfo(excelPath)))
            {
                var worksheet = package.Workbook.Worksheets[ITEM_SHEET_NAME];
                if (worksheet == null || worksheet.Dimension == null)
                {
                    Debug.LogWarning($"{ITEM_EXCEL_NAME} 中未找到 Sheet: {ITEM_SHEET_NAME}");
                    return;
                }

                int idCol = -1, nameCol = -1, iTypeCol = -1, resCol = -1;
                int columnCount = worksheet.Dimension.End.Column;

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

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

                int rowCount = worksheet.Dimension.End.Row;
                for (int row = DATA_START_ROW; row <= rowCount; row++)
                {
                    string idText = worksheet.Cells[row, idCol].Text.Trim();
                    if (string.IsNullOrEmpty(idText)) continue;
                    if (!int.TryParse(idText, out int id)) continue;

                    string iTypeText = worksheet.Cells[row, iTypeCol].Text.Trim();
                    if (!int.TryParse(iTypeText, out int iType)) continue;

                    if (iType == 102)
                    {
                        string name = worksheet.Cells[row, nameCol].Text.Trim();
                        string res = resCol > 0 ? worksheet.Cells[row, resCol].Text.Trim() : "";
                        LimitedEventItemInfo itemInfo = new LimitedEventItemInfo
                        {
                            Id = id,
                            Name = name,
                            Res = res,
                            PreviewSprite = GetPreviewSpriteByRes(res)
                        };

                        limitedEventItems.Add(itemInfo);
                        limitedEventItemById[id] = itemInfo;
                    }
                }
            }

            limitedEventItems.Sort((left, right) => left.Id.CompareTo(right.Id));

            Debug.Log($"从Item.xlsx加载了 {limitedEventItems.Count} 个限时事件道具(IType=102)");
        }

        /// <summary>
        /// 加载Series Sheet数据
        /// </summary>
        private void LoadSeriesSheet()
        {
            seriesDataList.Clear();

            string excelPath = GetDocsConfigFilePath(LIMITED_TIME_EVENT_EXCEL_NAME);
            if (!File.Exists(excelPath))
            {
                throw new FileNotFoundException($"未找到 {LIMITED_TIME_EVENT_EXCEL_NAME}", excelPath);
            }

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

                if (worksheet.Dimension == null)
                {
                    throw new Exception($"{LIMITED_TIME_EVENT_EXCEL_NAME}/{SERIES_SHEET_NAME} 没有可读取的数据");
                }

                colId = FindColumnIndex(worksheet, "Id");
                colBonusLv = FindColumnIndex(worksheet, "BonusLv");
                colItems = FindColumnIndex(worksheet, "Items");
                colType = FindColumnIndex(worksheet, "Type");
                colProb = FindColumnIndex(worksheet, "Prob");
                colNote = FindColumnIndex(worksheet, "备注");

                if (colId < 0 || colBonusLv < 0 || colItems < 0 || colType < 0 || colProb < 0)
                {
                    throw new Exception($"{SERIES_SHEET_NAME} 表结构不正确，缺少必要列（Id/BonusLv/Items/Type/Prob）");
                }

                int rowCount = worksheet.Dimension.End.Row;
                for (int row = DATA_START_ROW; row <= rowCount; row++)
                {
                    string idText = worksheet.Cells[row, colId].Text.Trim();
                    if (string.IsNullOrEmpty(idText)) continue;
                    if (!int.TryParse(idText, out int id)) continue;

                    var data = new SeriesRowData
                    {
                        RowIndex = row,
                        Id = id,
                        BonusLv = ParseInt(worksheet.Cells[row, colBonusLv].Text),
                        ItemsJson = worksheet.Cells[row, colItems].Text.Trim(),
                        Type = ParseInt(worksheet.Cells[row, colType].Text),
                        Prob = ParseInt(worksheet.Cells[row, colProb].Text),
                        Note = colNote > 0 ? worksheet.Cells[row, colNote].Text.Trim() : ""
                    };

                    // 解析Items JSON中的第一个Id
                    data.ParsedItemId = ParseItemIdFromJson(data.ItemsJson);

                    seriesDataList.Add(data);
                }
            }

            Debug.Log($"限时事件投放配置读取完成，共加载 {seriesDataList.Count} 条数据");
        }

        #endregion

        #region UI绘制

        private void DrawTableHeader()
        {
            EditorGUILayout.BeginVertical("box");
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Id", EditorStyles.boldLabel, GUILayout.Width(50));
            EditorGUILayout.LabelField("BonusLv", EditorStyles.boldLabel, GUILayout.Width(70));
            EditorGUILayout.LabelField("Items (限时事件道具)", EditorStyles.boldLabel, GUILayout.Width(350));
            EditorGUILayout.LabelField("Type", EditorStyles.boldLabel, GUILayout.Width(60));
            EditorGUILayout.LabelField("Prob", EditorStyles.boldLabel, GUILayout.Width(60));
            EditorGUILayout.LabelField("备注", EditorStyles.boldLabel, GUILayout.MinWidth(120));
            EditorGUILayout.LabelField("", GUILayout.Width(20)); // 删除按钮占位
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();
        }

        private void DrawSeriesRow(SeriesRowData data)
        {
            EditorGUILayout.BeginHorizontal("box");

            // Id
            data.Id = EditorGUILayout.IntField(data.Id, GUILayout.Width(50));

            // BonusLv
            data.BonusLv = EditorGUILayout.IntField(data.BonusLv, GUILayout.Width(70));

            // Items - 使用下拉选择IType=102的道具
            DrawItemsField(data);

            // Type
            data.Type = EditorGUILayout.IntField(data.Type, GUILayout.Width(60));

            // Prob
            data.Prob = EditorGUILayout.IntField(data.Prob, GUILayout.Width(60));

            // 备注
            data.Note = EditorGUILayout.TextField(data.Note, GUILayout.MinWidth(120));

            // 删除按钮
            if (GUILayout.Button("×", GUILayout.Width(20)))
            {
                if (EditorUtility.DisplayDialog("确认删除", $"确定删除 Id={data.Id} 的行吗？", "确定", "取消"))
                {
                    seriesDataList.Remove(data);
                    GUIUtility.ExitGUI();
                }
            }

            EditorGUILayout.EndHorizontal();
        }

        private void DrawItemsField(SeriesRowData data)
        {
            LimitedEventItemInfo itemInfo = GetLimitedEventItemInfo(data.ParsedItemId);
            bool hasPreview = itemInfo?.PreviewSprite != null && itemInfo.PreviewSprite.texture != null;

            EditorGUILayout.BeginHorizontal(
                "box",
                GUILayout.Width(350),
                GUILayout.MinHeight(hasPreview ? 68f : 42f));

            if (hasPreview)
            {
                DrawSpritePreview(itemInfo.PreviewSprite, 48f, string.Empty);
            }

            EditorGUILayout.BeginVertical();

            if (limitedEventItems.Count > 0)
            {
                string buttonText = itemInfo != null
                    ? $"{itemInfo.Id} - {itemInfo.Name}"
                    : data.ParsedItemId > 0
                        ? $"未找到道具 {data.ParsedItemId}"
                        : "选择限时事件道具";

                if (GUILayout.Button(buttonText, GUILayout.Height(22)))
                {
                    SeriesRowData capturedData = data;
                    LimitedEventItemPickerWindow.Show(limitedEventItems, position, data.ParsedItemId, selectedItem =>
                    {
                        capturedData.ParsedItemId = selectedItem.Id;
                        capturedData.ItemsJson = BuildItemsJson(selectedItem.Id);
                        Repaint();
                    });
                }

                if (itemInfo != null && !string.IsNullOrEmpty(itemInfo.Res))
                {
                    EditorGUILayout.LabelField(itemInfo.Res, EditorStyles.miniLabel);
                }
            }
            else
            {
                EditorGUILayout.LabelField("未加载到IType=102的道具", EditorStyles.miniLabel);
                data.ItemsJson = EditorGUILayout.TextField(data.ItemsJson);
            }

            EditorGUILayout.LabelField(data.ItemsJson, EditorStyles.miniLabel);

            EditorGUILayout.EndVertical();
            EditorGUILayout.EndHorizontal();
        }

        private void DrawAddRemoveButtons()
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            if (GUILayout.Button("+ 添加行", GUILayout.Width(100), GUILayout.Height(25)))
            {
                int newId = seriesDataList.Count > 0 ? seriesDataList.Max(x => x.Id) + 1 : 1;
                int defaultItemId = limitedEventItems.Count > 0 ? limitedEventItems[0].Id : 0;

                seriesDataList.Add(new SeriesRowData
                {
                    RowIndex = -1,
                    Id = newId,
                    BonusLv = 1,
                    ItemsJson = defaultItemId > 0 ? $"[{{\"Id\":{defaultItemId},\"Num\":1}}]" : "[]",
                    Type = 0,
                    Prob = 0,
                    Note = "",
                    ParsedItemId = defaultItemId
                });
            }

            EditorGUILayout.EndHorizontal();
        }

        #endregion

        #region 数据保存

        private void SaveSeriesSheet()
        {
            if (seriesDataList.Count == 0)
            {
                EditorUtility.DisplayDialog("提示", "当前没有可保存的数据，请先加载配置。", "确定");
                return;
            }

            string excelPath = GetDocsConfigFilePath(LIMITED_TIME_EVENT_EXCEL_NAME);
            if (!File.Exists(excelPath))
            {
                EditorUtility.DisplayDialog("错误", $"未找到文件：{excelPath}", "确定");
                return;
            }

            try
            {
                using (var package = new ExcelPackage(new FileInfo(excelPath)))
                {
                    var worksheet = package.Workbook.Worksheets[SERIES_SHEET_NAME];
                    if (worksheet == null)
                    {
                        EditorUtility.DisplayDialog("错误", $"未找到 Sheet: {SERIES_SHEET_NAME}", "确定");
                        return;
                    }

                    // 清除旧数据行（从DATA_START_ROW开始）
                    int oldRowCount = worksheet.Dimension?.End.Row ?? 0;
                    for (int row = DATA_START_ROW; row <= oldRowCount; row++)
                    {
                        for (int col = 1; col <= worksheet.Dimension.End.Column; col++)
                        {
                            worksheet.Cells[row, col].Value = null;
                        }
                    }

                    // 写入新数据
                    for (int i = 0; i < seriesDataList.Count; i++)
                    {
                        int row = DATA_START_ROW + i;
                        var data = seriesDataList[i];

                        worksheet.Cells[row, colId].Value = data.Id;
                        worksheet.Cells[row, colBonusLv].Value = data.BonusLv;
                        worksheet.Cells[row, colItems].Value = data.ItemsJson;
                        worksheet.Cells[row, colType].Value = data.Type;
                        worksheet.Cells[row, colProb].Value = data.Prob;

                        if (colNote > 0)
                        {
                            worksheet.Cells[row, colNote].Value = data.Note;
                        }
                    }

                    package.Save();
                }

                EditorUtility.DisplayDialog("成功", "限时事件投放配置已保存到 Excel！", "确定");
                Debug.Log("限时事件投放配置保存成功");
            }
            catch (Exception e)
            {
                EditorUtility.DisplayDialog("错误", $"保存失败: {e.Message}", "确定");
                Debug.LogError($"保存限时事件投放配置失败: {e}");
            }
        }

        #endregion

        #region 工具方法

        private LimitedEventItemInfo GetLimitedEventItemInfo(int itemId)
        {
            if (itemId <= 0)
            {
                return null;
            }

            limitedEventItemById.TryGetValue(itemId, out LimitedEventItemInfo itemInfo);
            return itemInfo;
        }

        private string BuildItemsJson(int itemId)
        {
            return itemId > 0 ? $"[{{\"Id\":{itemId},\"Num\":1}}]" : "[]";
        }

        private Sprite GetPreviewSpriteByRes(string res)
        {
            if (!TryParseRes(res, out string tableName, out string artItemName))
            {
                return null;
            }

            if (!artTableByName.TryGetValue(tableName, out ArtTableSO table) || table == null)
            {
                return null;
            }

            ArtItemData item = table.Items.FirstOrDefault(x => x.Name == artItemName);
            return item?.Sprite;
        }

        private static bool TryParseRes(string res, out string tableName, out string artItemName)
        {
            tableName = string.Empty;
            artItemName = string.Empty;

            if (string.IsNullOrWhiteSpace(res))
            {
                return false;
            }

            string[] parts = res.Split(new[] { ',' }, 2, StringSplitOptions.None);
            if (parts.Length < 2)
            {
                return false;
            }

            tableName = parts[0].Trim();
            artItemName = parts[1].Trim();
            return !string.IsNullOrEmpty(tableName) && !string.IsNullOrEmpty(artItemName);
        }

        private static void DrawSpritePreview(Sprite sprite, float size, string emptyText)
        {
            Rect previewRect = GUILayoutUtility.GetRect(size, size, GUILayout.Width(size), GUILayout.Height(size));
            DrawSpritePreview(previewRect, sprite, emptyText);
        }

        private static void DrawSpritePreview(Rect previewRect, Sprite sprite, string emptyText)
        {
            if (sprite != null && sprite.texture != null)
            {
                Rect texCoords = sprite.textureRect;
                Texture2D tex = sprite.texture;
                Rect normalizedCoords = new Rect(
                    texCoords.x / tex.width,
                    texCoords.y / tex.height,
                    texCoords.width / tex.width,
                    texCoords.height / tex.height
                );

                EditorGUI.DrawRect(previewRect, new Color(0.4f, 0.4f, 0.4f, 1f));

                float aspect = texCoords.height <= 0f ? 1f : texCoords.width / texCoords.height;
                Rect drawRect = previewRect;
                if (aspect > 1f)
                {
                    float newHeight = previewRect.height / aspect;
                    drawRect.y += (previewRect.height - newHeight) * 0.5f;
                    drawRect.height = newHeight;
                }
                else
                {
                    float newWidth = previewRect.width * aspect;
                    drawRect.x += (previewRect.width - newWidth) * 0.5f;
                    drawRect.width = newWidth;
                }

                GUI.DrawTextureWithTexCoords(drawRect, tex, normalizedCoords);
                return;
            }

            EditorGUI.DrawRect(previewRect, new Color(0.3f, 0.3f, 0.3f, 1f));
            GUIStyle emptyStyle = new GUIStyle(EditorStyles.centeredGreyMiniLabel)
            {
                wordWrap = true,
                alignment = TextAnchor.MiddleCenter
            };
            GUI.Label(previewRect, emptyText, emptyStyle);
        }

        private int FindColumnIndex(ExcelWorksheet worksheet, string columnName)
        {
            int columnCount = worksheet.Dimension?.End.Column ?? 0;
            for (int col = 1; col <= columnCount; col++)
            {
                if (string.Equals(worksheet.Cells[HEADER_ROW, col].Text.Trim(), columnName, StringComparison.OrdinalIgnoreCase))
                {
                    return col;
                }
            }
            return -1;
        }

        private static int ParseInt(string text)
        {
            if (int.TryParse(text?.Trim(), out int value))
                return value;
            return 0;
        }

        /// <summary>
        /// 从Items的JSON中解析出第一个Id
        /// 输入格式: [{"Id":100011,"Num":1}]
        /// </summary>
        private static int ParseItemIdFromJson(string json)
        {
            if (string.IsNullOrEmpty(json)) return 0;

            int idIndex = json.IndexOf("\"Id\"", StringComparison.OrdinalIgnoreCase);
            if (idIndex < 0) return 0;

            int colonIndex = json.IndexOf(':', idIndex);
            if (colonIndex < 0) return 0;

            int start = colonIndex + 1;
            while (start < json.Length && char.IsWhiteSpace(json[start]))
            {
                start++;
            }

            int end = start;
            while (end < json.Length && (char.IsDigit(json[end]) || json[end] == '-'))
            {
                end++;
            }

            if (end > start && int.TryParse(json.Substring(start, end - start), out int id))
                return id;

            return 0;
        }

        #endregion

        [Serializable]
        private class LimitedEventItemInfo
        {
            public int Id;
            public string Name;
            public string Res;
            public Sprite PreviewSprite;
        }

        private class LimitedEventItemPickerWindow : EditorWindow
        {
            private readonly List<LimitedEventItemInfo> allItems = new List<LimitedEventItemInfo>();
            private Action<LimitedEventItemInfo> onSelect;
            private string searchText = string.Empty;
            private Vector2 scrollPosition;
            private int currentItemId;

            private const float IMAGE_SIZE = 84f;
            private const float ROW_HEIGHT_WITH_PREVIEW = 108f;
            private const float ROW_HEIGHT_NO_PREVIEW = 54f;

            public static void Show(List<LimitedEventItemInfo> items, Rect ownerWindowRect, int currentItemId, Action<LimitedEventItemInfo> onSelect)
            {
                if (items == null || items.Count == 0)
                {
                    EditorUtility.DisplayDialog("提示", "未加载到 IType=102 的道具", "确定");
                    return;
                }

                LimitedEventItemPickerWindow window = CreateInstance<LimitedEventItemPickerWindow>();
                window.titleContent = new GUIContent("选择限时事件道具");
                window.minSize = new Vector2(620, 520);
                window.allItems.Clear();
                window.allItems.AddRange(items.OrderBy(x => x.Id));
                window.currentItemId = currentItemId;
                window.onSelect = onSelect;
                window.position = GetCenteredRect(ownerWindowRect, window.minSize);
                window.ShowUtility();
            }

            private static Rect GetCenteredRect(Rect ownerWindowRect, Vector2 windowSize)
            {
                float x = ownerWindowRect.x + (ownerWindowRect.width - windowSize.x) * 0.5f;
                float y = ownerWindowRect.y + (ownerWindowRect.height - windowSize.y) * 0.5f;
                return new Rect(x, y, windowSize.x, windowSize.y);
            }

            private void OnGUI()
            {
                DrawToolbar();
                EditorGUILayout.Space(4f);
                DrawItemList();
            }

            private void DrawToolbar()
            {
                EditorGUILayout.BeginVertical("box");
                EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
                EditorGUILayout.LabelField("搜索", GUILayout.Width(40));
                searchText = EditorGUILayout.TextField(searchText, EditorStyles.toolbarSearchField);
                if (GUILayout.Button("×", EditorStyles.miniButton, GUILayout.Width(20)))
                {
                    searchText = string.Empty;
                    GUI.FocusControl(null);
                }
                EditorGUILayout.EndHorizontal();

                int filteredCount = allItems.Count(MatchSearch);
                EditorGUILayout.LabelField($"共 {filteredCount} 个限时事件道具，点击即可选择", EditorStyles.miniLabel);
                EditorGUILayout.EndVertical();
            }

            private void DrawItemList()
            {
                List<LimitedEventItemInfo> filteredItems = allItems.Where(MatchSearch).ToList();
                scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);

                foreach (LimitedEventItemInfo item in filteredItems)
                {
                    DrawItemRow(item);
                }

                EditorGUILayout.EndScrollView();
            }

            private void DrawItemRow(LimitedEventItemInfo item)
            {
                bool isCurrent = item.Id == currentItemId;
                bool hasPreview = item.PreviewSprite != null && item.PreviewSprite.texture != null;
                float rowHeight = hasPreview ? ROW_HEIGHT_WITH_PREVIEW : ROW_HEIGHT_NO_PREVIEW;
                GUI.backgroundColor = isCurrent ? new Color(0.8f, 1f, 0.8f) : Color.white;

                EditorGUILayout.BeginHorizontal("box", GUILayout.ExpandWidth(true), GUILayout.MinHeight(rowHeight));

                if (hasPreview)
                {
                    Rect imageRect = GUILayoutUtility.GetRect(IMAGE_SIZE, IMAGE_SIZE, GUILayout.Width(IMAGE_SIZE), GUILayout.Height(IMAGE_SIZE));
                    DrawSpritePreview(imageRect, item.PreviewSprite, string.Empty);
                }

                EditorGUILayout.BeginVertical();

                GUIStyle nameStyle = new GUIStyle(EditorStyles.boldLabel)
                {
                    wordWrap = true,
                    alignment = TextAnchor.UpperLeft
                };
                GUILayout.Label($"{item.Id} - {item.Name}", nameStyle);

                if (!string.IsNullOrEmpty(item.Res))
                {
                    GUIStyle resStyle = new GUIStyle(EditorStyles.centeredGreyMiniLabel)
                    {
                        wordWrap = true,
                        alignment = TextAnchor.UpperLeft
                    };
                    GUILayout.Label(item.Res, resStyle);
                }

                EditorGUILayout.EndVertical();

                GUILayout.FlexibleSpace();

                if (GUILayout.Button("选择", EditorStyles.miniButton))
                {
                    onSelect?.Invoke(item);
                    Close();
                }

                EditorGUILayout.EndHorizontal();
                GUI.backgroundColor = Color.white;
            }

            private bool MatchSearch(LimitedEventItemInfo item)
            {
                if (string.IsNullOrWhiteSpace(searchText))
                {
                    return true;
                }

                return item.Id.ToString().Contains(searchText, StringComparison.OrdinalIgnoreCase)
                    || (!string.IsNullOrEmpty(item.Name) && item.Name.Contains(searchText, StringComparison.OrdinalIgnoreCase))
                    || (!string.IsNullOrEmpty(item.Res) && item.Res.Contains(searchText, StringComparison.OrdinalIgnoreCase));
            }
        }

        [Serializable]
        private class SeriesRowData
        {
            public int RowIndex;
            public int Id;
            public int BonusLv;
            public string ItemsJson;
            public int Type;
            public int Prob;
            public string Note;

            /// <summary>
            /// 从ItemsJson解析出的道具Id，用于下拉选择
            /// </summary>
            public int ParsedItemId;
        }
    }
}
