using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using CycleGUI;
using SimpleLite;
using StandardScene.Utils;

namespace StandardScene.ExtendDevice.Door
{
    /// <summary>
    /// 门控监控界面（CycleGUI 版，替代原 WinForms <c>DoorMonitor</c> 窗体）。
    /// <list type="bullet">
    /// <item>单实例：再次打开则把已有面板置前。</item>
    /// <item><c>pb.Table</c> 展示门列表，单击行选中以进行手动控制。</item>
    /// <item>约每 500ms 重绘刷新门状态快照（替代 WinForms 定时器）。</item>
    /// </list>
    /// </summary>
    public class DoorMonitor
    {
        private const string TableId = "door-monitor-list";

        private static readonly Color SelectedRowColor = Color.FromArgb(230, 240, 255);

        private static Panel _panel;
        private static (int ControllerIndex, int DoorIndex)? _selectedDoor;

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

            var panel = GUI.DeclarePanel()
                .ShowTitle("门控监控")
                .SetDefaultDocking(Panel.Docking.None)
                .InitSize(1200, 620)
                .InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
            _panel = panel;
            panel.IfTerminalQuit(() => _panel = null);

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

                var mission = GetMission();
                var snapshot = mission?.GetDoorMonitorSnapshot() ?? Array.Empty<DoorMission.DoorMonitorSnapshotItem>();

                pb.Label($"共 {snapshot.Count} 扇门");
                pb.Label(GetDoorInfoText(snapshot));

                pb.Table(TableId,
                    new[]
                    {
                        "控制器编码", "门编码", "状态", "控制目标", "控制来源",
                        "手动剩余(s)", "车辆占用", "控制地址", "开到位地址"
                    },
                    snapshot.Count, (row, i) =>
                    {
                        var door = snapshot[i];
                        if (IsRowSelected(door))
                            row.SetColor(SelectedRowColor);

                        LabelCell(row, door, door.ControllerIndex.ToString());
                        LabelCell(row, door, door.DoorIndex.ToString());
                        LabelCell(row, door, FormatState(door.State));
                        LabelCell(row, door, door.Target ? "开" : "关");
                        LabelCell(row, door, door.Source == DoorMission.ControlSource.Manual ? "手动" : "自动");
                        LabelCell(row, door, FormatManualRemain(door));
                        LabelCell(row, door, FormatCars(door));
                        LabelCell(row, door, door.ControlAddress.ToString());
                        LabelCell(row, door, door.OpenStatusAddress.ToString());
                    }, height: 18, enableSearch: true);

                pb.Separator();
                pb.Label("手动控制");

                var canClose = CanCloseSelected(mission);
                if (pb.Button("打开", distinct: "door-monitor-open"))
                    OpenSelectedDoor();
                pb.SameLine(12);
                if (pb.Button("关闭", distinct: "door-monitor-close", disabled: !canClose))
                    CloseSelectedDoor();
                pb.SameLine(12);
                if (pb.Button("清空占用", distinct: "door-monitor-clear-cars"))
                    ClearSelectedCars();

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

        private static void LabelCell(PanelBuilder.Row row, DoorMission.DoorMonitorSnapshotItem door, string text)
        {
            if (row.Label(text))
                _selectedDoor = (door.ControllerIndex, door.DoorIndex);
        }

        private static DoorMission GetMission() =>
            SimpleProject.proj?.Missions?.OfType<DoorMission>().FirstOrDefault();

        private static bool IsRowSelected(DoorMission.DoorMonitorSnapshotItem door) =>
            _selectedDoor.HasValue
            && _selectedDoor.Value.ControllerIndex == door.ControllerIndex
            && _selectedDoor.Value.DoorIndex == door.DoorIndex;

        private static string GetDoorInfoText(IReadOnlyList<DoorMission.DoorMonitorSnapshotItem> snapshot)
        {
            if (!_selectedDoor.HasValue)
                return "请选择要控制的门";

            var door = snapshot.FirstOrDefault(d =>
                d.ControllerIndex == _selectedDoor.Value.ControllerIndex
                && d.DoorIndex == _selectedDoor.Value.DoorIndex);
            if (door == null)
                return $"控制器编码: {_selectedDoor.Value.ControllerIndex}, 门编码: {_selectedDoor.Value.DoorIndex}";

            return $"控制器编码: {door.ControllerIndex}, 门编码: {door.DoorIndex}";
        }

        private static bool CanCloseSelected(DoorMission mission)
        {
            if (!_selectedDoor.HasValue || mission == null)
                return true;

            var cars = mission.GetCarsInArea(_selectedDoor.Value.ControllerIndex, _selectedDoor.Value.DoorIndex);
            return cars.Count == 0;
        }

        private static string FormatState(DoorState state) =>
            state == DoorState.Open ? "打开" : state == DoorState.Closed ? "关闭" : "未知";

        private static string FormatManualRemain(DoorMission.DoorMonitorSnapshotItem door) =>
            door.Source == DoorMission.ControlSource.Manual && door.ManualRemainingSeconds.HasValue
                ? Math.Ceiling(door.ManualRemainingSeconds.Value).ToString()
                : "-";

        private static string FormatCars(DoorMission.DoorMonitorSnapshotItem door) =>
            door.CarsInArea.Count > 0 ? string.Join(", ", door.CarsInArea) : "无";

        private static void OpenSelectedDoor()
        {
            if (!_selectedDoor.HasValue)
            {
                CycleUiHelper.Alert("提示", "请先选择要控制的门");
                return;
            }

            try
            {
                var mission = GetMission();
                if (mission == null)
                {
                    CycleUiHelper.Alert("错误", "未找到门控进程");
                    return;
                }

                var (controllerIndex, doorIndex) = _selectedDoor.Value;
                mission.SetManualDoorControl(controllerIndex, doorIndex, true);
                CycleUiHelper.Alert("提示", $"控制器 {controllerIndex} 门 {doorIndex} 已设置手动打开（10秒）");
            }
            catch (Exception ex)
            {
                CycleUiHelper.Alert("错误", $"设置门打开目标失败: {ex.Message}");
            }
        }

        private static void CloseSelectedDoor()
        {
            if (!_selectedDoor.HasValue)
            {
                CycleUiHelper.Alert("提示", "请先选择要控制的门");
                return;
            }

            try
            {
                var mission = GetMission();
                if (mission == null)
                {
                    CycleUiHelper.Alert("错误", "未找到门控进程");
                    return;
                }

                var (controllerIndex, doorIndex) = _selectedDoor.Value;
                var success = mission.SetManualDoorControl(controllerIndex, doorIndex, false);
                if (!success)
                {
                    CycleUiHelper.Alert("提示", "门存在车辆占用，禁止手动关闭。");
                    return;
                }

                CycleUiHelper.Alert("提示", $"控制器 {controllerIndex} 门 {doorIndex} 已设置手动关闭（10秒）");
            }
            catch (Exception ex)
            {
                CycleUiHelper.Alert("错误", $"设置门关闭目标失败: {ex.Message}");
            }
        }

        private static void ClearSelectedCars()
        {
            if (!_selectedDoor.HasValue)
            {
                CycleUiHelper.Alert("提示", "请先选择要清空占用的门");
                return;
            }

            try
            {
                var mission = GetMission();
                if (mission == null)
                {
                    CycleUiHelper.Alert("错误", "未找到门控进程");
                    return;
                }

                var (controllerIndex, doorIndex) = _selectedDoor.Value;
                mission.ClearCarsInArea(controllerIndex, doorIndex);
                CycleUiHelper.Alert("提示", $"控制器 {controllerIndex} 门 {doorIndex} 已清空占用");
            }
            catch (Exception ex)
            {
                CycleUiHelper.Alert("错误", $"清空占用失败: {ex.Message}");
            }
        }
    }
}
