using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using CycleGUI;
using Newtonsoft.Json;
using StandardScene.InterLock;
using StandardScene.Utils;

namespace LoopViewerApp
{
    /// <summary>
    /// 交通联锁区域管理界面（CycleGUI 版，替代原 WinForms <c>TrafficInterlockViewer</c> 窗体）。
    /// <list type="bullet">
    /// <item>维护 <see cref="TrafficInterlockMission.TrafficAreaList"/> 的增 / 改 / 删，并写入 <c>Config/traffic.json</c>。</item>
    /// <item>单实例：再次打开则把已有面板置前。</item>
    /// <item>勾选多行后「删除选中」可批量删除；每行「编辑」按钮加载下方编辑区。</item>
    /// <item>文件写入放后台线程，绝不阻塞渲染线程。</item>
    /// </list>
    /// 沿用 <c>LoopViewer</c> / <c>DeliveryViewer</c> 同套模式（单实例面板、<c>pb.Table</c>、<c>CycleUiHelper.ConfirmThen</c>）。
    /// 保留可实例化 + <see cref="Show"/> 以兼容既有调用 <c>new TrafficInterlockViewer().Show()</c>。
    /// </summary>
    public class TrafficInterlockViewer
    {
        private const string TableId = "traffic-area-list";

        private static string JsonPath =>
            Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", "traffic.json");

        private static readonly object SaveLock = new object();

        private static Panel _panel;
        private static string _editingAreaId = "";
        private static readonly HashSet<string> _selected = new HashSet<string>(StringComparer.Ordinal);

        private static string _areaName = "";
        private static string _stationIds = "";
        private static string _controlRight = "";
        private static bool _isOccupied;
        private static bool _isEnabled = true;
        private static string _editingHint = "新增区域";
        private static string _editErr = "";
        private static volatile string _status = "";

        /// <summary>打开（或置前）区域管理面板。兼容原 <c>new TrafficInterlockViewer().Show()</c> 调用方式。</summary>
        public void Show() => Open();

        /// <summary>打开（或置前）区域管理面板。</summary>
        public static void Open()
        {
            if (_panel != null)
            {
                try
                {
                    _panel.BringToFront();
                    return;
                }
                catch
                {
                    _panel = null;
                }
            }

            ClearPanelInputs();

            var panel = GUI.DeclarePanel()
                .ShowTitle("交通联锁区域管理")
                .SetDefaultDocking(Panel.Docking.None)
                .InitSize(800, 680)
                .InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
            _panel = panel;
            panel.IfTerminalQuit(() => { if (_panel == panel) _panel = null; });

            panel.Define(pb =>
            {
                if (pb.Closing())
                {
                    panel.Exit();
                    _panel = null;
                    return;
                }

                List<TrafficArea> areas;
                lock (TrafficInterlockMission.TrafficAreaList)
                {
                    EnsureAreaIdsLocked();
                    areas = TrafficInterlockMission.TrafficAreaList.ToList();
                }
                _selected.RemoveWhere(id => areas.All(a => a.Id != id));
                if (!string.IsNullOrEmpty(_editingAreaId) && areas.All(a => a.Id != _editingAreaId))
                    ClearPanelInputs();

                if (pb.Button("删除选中", distinct: "traffic-del-selected"))
                    ConfirmDeleteSelected();
                pb.SameLine(12);
                if (pb.Button("刷新", distinct: "traffic-refresh"))
                {
                    _status = "";
                    _editErr = "";
                }
                pb.SameLine(12);
                pb.Label($"共 {areas.Count} 个区域，已选 {_selected.Count} 个");

                pb.Table(TableId,
                    new[] { "选择", "区域名称", "区域站点集合", "控制权", "是否被占用", "是否启用", "操作" },
                    areas.Count, (row, i) =>
                    {
                        var a = areas[i];
                        var areaId = EnsureAreaId(a);

                        var sel = _selected.Contains(areaId);
                        if (row.Checkbox(ref sel, "勾选以批量删除"))
                        {
                            if (sel) _selected.Add(areaId);
                            else _selected.Remove(areaId);
                        }

                        row.Label(a.AreaName ?? "");
                        row.Label(a.SiteList != null && a.SiteList.Count > 0
                            ? string.Join(", ", a.SiteList)
                            : "");
                        row.Label(a.ControllerName ?? "");
                        row.Label(a.IsOccupy ? "是" : "否");
                        row.Label(a.IsEnable ? "是" : "否");

                        if (row.ButtonGroup(new[] { "编辑" }, new[] { "编辑该区域" }) == 0)
                        {
                            _editingAreaId = areaId;
                            LoadAreaToFields(a);
                        }
                    }, height: 14, enableSearch: true);

                pb.Separator();
                pb.Label("数据新增/编辑（点击表格行「编辑」可在此查看并修改该行数据）");
                pb.Label(_editingHint);

                var (name, _) = pb.TextInput("1. 区域名称", _areaName, alwaysReturnString: true);
                _areaName = name;
                var (sites, _) = pb.TextInput("2. 站点集合 (逗号/分号/空格分隔)", _stationIds, alwaysReturnString: true);
                _stationIds = sites;
                var (ctrl, _) = pb.TextInput("3. 控制权", _controlRight, alwaysReturnString: true);
                _controlRight = ctrl;
                pb.CheckBox("4. 是否被占用", ref _isOccupied);
                pb.SameLine(16);
                pb.CheckBox("5. 是否启用", ref _isEnabled);

                if (!string.IsNullOrEmpty(_editErr))
                {
                    pb.Separator();
                    pb.Label(_editErr);
                }

                pb.Separator();
                if (pb.Button("保存", distinct: "traffic-save"))
                    SaveArea();
                pb.SameLine(12);
                if (pb.Button("新增", distinct: "traffic-new"))
                {
                    _selected.Clear();
                    ClearPanelInputs();
                }

                if (!string.IsNullOrEmpty(_status))
                {
                    pb.Separator();
                    pb.Label(_status);
                }

                pb.Panel.Repaint(repaintTimeMs: 500);
            });
        }

        private static void ConfirmDeleteSelected()
        {
            if (_selected.Count == 0)
            {
                _status = "请先在上方列表中选择要删除的区域。";
                _panel?.Repaint();
                return;
            }

            string prompt = _selected.Count == 1
                ? "确定要删除选中的区域吗？"
                : $"确定要删除所选 {_selected.Count} 个区域吗？";

            CycleUiHelper.ConfirmThen(prompt, DeleteSelected);
        }

        private static void DeleteSelected()
        {
            var selectedIds = _selected.ToHashSet(StringComparer.Ordinal);
            var removed = 0;
            lock (TrafficInterlockMission.TrafficAreaList)
            {
                removed = TrafficInterlockMission.TrafficAreaList.RemoveAll(a => selectedIds.Contains(a.Id));
            }

            _selected.Clear();
            SaveToConfig();
            ClearPanelInputs();
            _status = $"已删除 {removed} 个区域";
            _panel?.Repaint();
        }

        private static void SaveArea()
        {
            try
            {
                string areaName = (_areaName ?? "").Trim();
                if (string.IsNullOrEmpty(areaName))
                {
                    _editErr = "请输入区域名称。";
                    _panel?.Repaint();
                    return;
                }

                var stationIds = ParseStationIds(_stationIds ?? "");
                string controlRight = (_controlRight ?? "").Trim();
                bool isOccupied = _isOccupied;
                bool isEnabled = _isEnabled;

                if (!string.IsNullOrEmpty(_editingAreaId))
                {
                    lock (TrafficInterlockMission.TrafficAreaList)
                    {
                        var existing = TrafficInterlockMission.TrafficAreaList
                            .FirstOrDefault(a => string.Equals(a.Id, _editingAreaId, StringComparison.Ordinal));
                        if (existing == null)
                        {
                            _editErr = "正在编辑的区域已不存在，请刷新后重试。";
                            _panel?.Repaint();
                            return;
                        }

                        existing.AreaName = areaName;
                        existing.SiteList = stationIds;
                        existing.ControllerName = controlRight;
                        existing.IsOccupy = isOccupied;
                        existing.IsEnable = isEnabled;
                    }
                    _status = $"已保存区域：{areaName}";
                }
                else
                {
                    lock (TrafficInterlockMission.TrafficAreaList)
                    {
                        TrafficInterlockMission.TrafficAreaList.Add(new TrafficArea
                        {
                            Id = NewAreaId(),
                            AreaName = areaName,
                            SiteList = stationIds,
                            ControllerName = controlRight,
                            IsOccupy = isOccupied,
                            IsEnable = isEnabled
                        });
                    }
                    _status = "已新增区域";
                }

                SaveToConfig();
                ClearPanelInputs();
                _editErr = "";
                _panel?.Repaint();
            }
            catch (Exception ex)
            {
                _editErr = "操作失败：" + ex.Message;
                _panel?.Repaint();
            }
        }

        private static void LoadAreaToFields(TrafficArea a)
        {
            if (a == null) return;
            _editingHint = $"编辑：{a.AreaName}";
            _areaName = a.AreaName ?? "";
            _stationIds = a.SiteList != null && a.SiteList.Count > 0
                ? string.Join(", ", a.SiteList)
                : "";
            _controlRight = a.ControllerName ?? "";
            _isOccupied = a.IsOccupy;
            _isEnabled = a.IsEnable;
            _editErr = "";
        }

        private static void ClearPanelInputs()
        {
            _editingAreaId = "";
            _editingHint = "新增区域";
            _areaName = "";
            _stationIds = "";
            _controlRight = "";
            _isOccupied = false;
            _isEnabled = true;
            _editErr = "";
        }

        private static void SaveToConfig()
        {
            string json;
            try
            {
                lock (TrafficInterlockMission.TrafficAreaList)
                    json = JsonConvert.SerializeObject(TrafficInterlockMission.TrafficAreaList, Formatting.Indented);
            }
            catch (Exception ex)
            {
                _status = "保存失败：" + ex.Message;
                _panel?.Repaint();
                return;
            }

            var path = JsonPath;
            var dir = Path.GetDirectoryName(path);
            Task.Run(() =>
            {
                try
                {
                    if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
                        Directory.CreateDirectory(dir);
                    lock (SaveLock)
                        File.WriteAllText(path, json);
                }
                catch (Exception ex)
                {
                    _status = "保存失败：" + ex.Message;
                    _panel?.Repaint();
                }
            });
        }

        /// <summary>解析站点集合字符串，如 "1,2,3" → <see cref="List{T}"/> of int。</summary>
        private static List<int> ParseStationIds(string text)
        {
            var list = new List<int>();
            if (string.IsNullOrWhiteSpace(text)) return list;
            foreach (var part in text.Split(new[] { ',', ';', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (int.TryParse(part.Trim(), out int id))
                    list.Add(id);
            }
            return list;
        }

        private static void EnsureAreaIdsLocked()
        {
            foreach (var area in TrafficInterlockMission.TrafficAreaList)
                EnsureAreaId(area);
        }

        private static string EnsureAreaId(TrafficArea area)
        {
            if (string.IsNullOrWhiteSpace(area.Id))
                area.Id = NewAreaId();
            return area.Id;
        }

        private static string NewAreaId() => Guid.NewGuid().ToString("N");
    }
}
