using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace ChillConnect.Editor
{
    /// <summary>
    /// 第三方关卡配置批量转换工具
    /// 输入：文件夹内所有第三方单关JSON
    /// 输出：对应转换后的我方格式单关JSON
    /// </summary>
    public class LevelBatchConverter : EditorWindow
    {
        #region 数据结构定义
        // 第三方单关结构（只声明需要的字段，多余自动忽略）
        [System.Serializable]
        private class ThirdPartyLevel
        {
            public Vector2Int size;
            public string name;
            public List<ThirdPartyArrow> arrows;
        }

        [System.Serializable]
        private class ThirdPartyArrow
        {
            public List<Vector2Int> nodes;
            public int color;
        }

        // 我方单关结构（和运行时对齐）
        [System.Serializable]
        public class ArrowConfig
        {
            public int id;
            public int startPoint;
            public List<string> path = new List<string>();
        }

        [System.Serializable]
        public class LevelConfig
        {
            public int levelId;
            public string levelName;
            public int gridRows;
            public int gridCols;
            public int pointSpacing = 60;
            public List<ArrowConfig> arrows = new List<ArrowConfig>();
        }
        #endregion

        private string _inputFolder = "";
        private string _outputFolder = "";
        private int _pointSpacing = 60;
        private Vector2 _scrollPos;
        private List<string> _logList = new List<string>();

        [MenuItem("Window/Arrow Game/批量关卡转换工具")]
        public static void ShowWindow()
        {
            var window = GetWindow<LevelBatchConverter>("批量关卡转换");
            window.minSize = new Vector2(500, 400);
        }

        private void OnGUI()
        {
            EditorGUILayout.Space(10);

            // 输入文件夹
            EditorGUILayout.LabelField("输入文件夹（第三方单关JSON）", EditorStyles.boldLabel);
            EditorGUILayout.BeginHorizontal();
            _inputFolder = EditorGUILayout.TextField(_inputFolder);
            if (GUILayout.Button("选择", GUILayout.Width(60)))
            {
                string path = EditorUtility.OpenFolderPanel("选择输入文件夹", Application.dataPath, "");
                if (!string.IsNullOrEmpty(path))
                    _inputFolder = path;
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space(8);

            // 输出文件夹
            EditorGUILayout.LabelField("输出文件夹（转换后JSON）", EditorStyles.boldLabel);
            EditorGUILayout.BeginHorizontal();
            _outputFolder = EditorGUILayout.TextField(_outputFolder);
            if (GUILayout.Button("选择", GUILayout.Width(60)))
            {
                string path = EditorUtility.OpenFolderPanel("选择输出文件夹", Application.dataPath, "");
                if (!string.IsNullOrEmpty(path))
                    _outputFolder = path;
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space(8);

            // 基础配置
            _pointSpacing = EditorGUILayout.IntField("默认点间距", _pointSpacing);

            EditorGUILayout.Space(10);

            // 转换按钮
            if (GUILayout.Button("开始批量转换", GUILayout.Height(30)))
            {
                BatchConvert();
            }

            EditorGUILayout.Space(10);

            // 日志区域
            EditorGUILayout.LabelField("转换日志", EditorStyles.boldLabel);
            _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos, GUILayout.ExpandHeight(true));
            foreach (string log in _logList)
            {
                EditorGUILayout.LabelField(log);
            }
            EditorGUILayout.EndScrollView();
        }

        /// <summary>
        /// 批量转换核心逻辑
        /// </summary>
        private void BatchConvert()
        {
            _logList.Clear();

            if (string.IsNullOrEmpty(_inputFolder) || !Directory.Exists(_inputFolder))
            {
                _logList.Add("❌ 输入文件夹不存在");
                return;
            }

            if (string.IsNullOrEmpty(_outputFolder))
            {
                _logList.Add("❌ 请选择输出文件夹");
                return;
            }

            // 创建输出目录
            if (!Directory.Exists(_outputFolder))
            {
                Directory.CreateDirectory(_outputFolder);
            }

            // 获取所有json文件
            string[] files = Directory.GetFiles(_inputFolder, "*.json", SearchOption.TopDirectoryOnly);
            if (files.Length == 0)
            {
                _logList.Add("⚠️ 输入文件夹内未找到JSON文件");
                return;
            }

            _logList.Add($"找到 {files.Length} 个JSON文件，开始转换...");

            int successCount = 0;
            int failCount = 0;

            for (int i = 0; i < files.Length; i++)
            {
                string filePath = files[i];
                string fileName = Path.GetFileNameWithoutExtension(filePath);

                try
                {
                    // 1. 读取并解析第三方配置
                    string json = File.ReadAllText(filePath);
                    ThirdPartyLevel thirdLevel = JsonUtility.FromJson<ThirdPartyLevel>(json);

                    if (thirdLevel == null || thirdLevel.arrows == null)
                    {
                        _logList.Add($"❌ {fileName}：解析失败，格式不匹配");
                        failCount++;
                        continue;
                    }

                    // 2. 转换为我方格式
                    LevelConfig level = ConvertLevel(thirdLevel, fileName, i + 1);

                    // 3. 导出到输出文件夹
                    string outJson = JsonUtility.ToJson(level, true);
                    string outPath = Path.Combine(_outputFolder, $"{fileName}.json");
                    File.WriteAllText(outPath, outJson);

                    _logList.Add($"✅ {fileName}：转换成功 | {level.gridCols}×{level.gridRows} | {level.arrows.Count}个箭头");
                    successCount++;
                }
                catch (System.Exception e)
                {
                    _logList.Add($"❌ {fileName}：转换异常 - {e.Message}");
                    failCount++;
                }
            }

            _logList.Add("");
            _logList.Add($"===== 转换完成 =====");
            _logList.Add($"成功：{successCount} 个");
            _logList.Add($"失败：{failCount} 个");
            _logList.Add($"输出路径：{_outputFolder}");

            EditorUtility.DisplayDialog("批量转换完成", 
                $"成功：{successCount}\n失败：{failCount}\n输出路径：{_outputFolder}", 
                "确定");

            AssetDatabase.Refresh();
        }

        /// <summary>
        /// 单个关卡转换逻辑（和之前编辑器内转换完全一致）
        /// </summary>
        private LevelConfig ConvertLevel(ThirdPartyLevel thirdLevel, string fileName, int index)
        {
            LevelConfig level = new LevelConfig
            {
                levelId = index,
                levelName = string.IsNullOrEmpty(thirdLevel.name) ? fileName : thirdLevel.name,
                gridCols = thirdLevel.size.x,
                gridRows = thirdLevel.size.y,
                pointSpacing = _pointSpacing,
                arrows = new List<ArrowConfig>()
            };

            for (int i = 0; i < thirdLevel.arrows.Count; i++)
            {
                var thirdArrow = thirdLevel.arrows[i];
                if (thirdArrow.nodes == null || thirdArrow.nodes.Count == 0)
                    continue;

                ArrowConfig arrow = new ArrowConfig
                {
                    id = i + 1,
                    path = new List<string>()
                };

                // 起点转换：(x,y) → 点ID = y * 列数 + x
                Vector2Int startNode = thirdArrow.nodes[0];
                arrow.startPoint = startNode.y * level.gridCols + startNode.x;

                // 路径转换：相邻节点计算方向
                for (int j = 1; j < thirdArrow.nodes.Count; j++)
                {
                    Vector2Int prev = thirdArrow.nodes[j - 1];
                    Vector2Int cur = thirdArrow.nodes[j];

                    int dx = cur.x - prev.x;
                    int dy = cur.y - prev.y;

                    if (dx == 1) arrow.path.Add("right");
                    else if (dx == -1) arrow.path.Add("left");
                    else if (dy == 1) arrow.path.Add("down");
                    else if (dy == -1) arrow.path.Add("up");
                }

                level.arrows.Add(arrow);
            }

            return level;
        }
    }
}