using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using LessokajiWeaverUtilities.MagicAttributes;
using LessokajiWeaverUtilities.Utilities;
using Newtonsoft.Json;
using SimpleLite.RCS;
using SimpleLite.RCS.CarTypes;
using SimpleCore;
using SimpleCore.Library;
using SimpleCore.PropType;
using SimpleCore.Traffic;
using StandardScene.Utils;

namespace StandardScene.ExtendDevice.Door
{
    //todo:2026.1.21 1,门控制器的通信参数配置移动到具体门控制器类中管理，实现对不同通信类型的支持
    [MissionType(Name = "门控进程")]
    [I18N.DocumentTranslation(Name = "DoorMission", locale = "en")]
    public class DoorMission : Mission
    {
        private const string DataFileName = "DoorConfig.json";
        private string _dataFilePath;

        /// <summary>
        /// 当前所有门控制器实例列表
        /// </summary>
        private List<BasicDoorController> _doorControllers = new List<BasicDoorController>();

        /// <summary>
        /// 用于管理异步循环的取消令牌源
        /// </summary>
        private CancellationTokenSource _cancellationTokenSource;

        /// <summary>
        /// 保存监控配置与状态的后台任务
        /// </summary>
        private Task _configTask;
        private Task _stateTask;

        /// <summary>
        /// 同步锁，用于保护门控制器列表的并发访问
        /// </summary>
        private readonly object _syncLock = new object();

        /// <summary>
        /// 门区域内的小车记录：(ControllerIndex, DoorIndex) -> List<CarId>
        /// </summary>
        [JsonIgnore] private readonly Dictionary<(int ControllerIndex, int DoorIndex), List<int>> carsInAreas = new Dictionary<(int ControllerIndex, int DoorIndex), List<int>>();

        /// <summary>
        /// 需要打开的门：(ControllerIndex, DoorIndex) -> bool
        /// </summary>
        [JsonIgnore] private readonly Dictionary<(int ControllerIndex, int DoorIndex), bool> _needOpen = new Dictionary<(int ControllerIndex, int DoorIndex), bool>();

        /// <summary>
        /// 手动控制请求：(ControllerIndex, DoorIndex) -> ManualControlRequest
        /// </summary>
        [JsonIgnore] private readonly Dictionary<(int ControllerIndex, int DoorIndex), ManualControlRequest> _manualRequests = new Dictionary<(int ControllerIndex, int DoorIndex), ManualControlRequest>();

        private const int DefaultManualHoldSeconds = 10;

        public enum ControlSource
        {
            Auto = 0,
            Manual = 1
        }

        private class ManualControlRequest
        {
            public bool Target { get; set; }
            public DateTime ExpireAt { get; set; }
        }

        public class DoorControlStatus
        {
            public bool Target { get; set; }
            public ControlSource Source { get; set; }
            public double? ManualRemainingSeconds { get; set; }
            public IReadOnlyList<int> CarsInArea { get; set; } = Array.Empty<int>();
        }

        /// <summary>
        /// 监控界面快照项（线程安全快照，避免UI直接枚举可变字典）
        /// </summary>
        public class DoorMonitorSnapshotItem
        {
            public int ControllerIndex { get; set; }
            public int DoorIndex { get; set; }
            public DoorState State { get; set; }
            public bool Target { get; set; }
            public ControlSource Source { get; set; }
            public double? ManualRemainingSeconds { get; set; }
            public IReadOnlyList<int> CarsInArea { get; set; } = Array.Empty<int>();
            public ushort ControlAddress { get; set; }
            public ushort OpenStatusAddress { get; set; }
        }

        [MethodMember(Name = "启动进程")]
        [I18N.DocumentTranslation(Name = "Start Mission", locale = "en")]
        public override void Execute()
        {
            // 设置数据文件路径
            _dataFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DataFileName);

            // 如果已经启动，先停止之前的循环
            StopInternalAsync().GetAwaiter().GetResult();

            TrafficControl.BeforeLock += BeforeLockEvent;
            TrafficControl.AfterLeave += AfterLeaveEvent;
            TrafficControl.OnLockAcquired += OnLockAcquiredEvent;

            // 启动时立即加载一次配置，避免监控界面在第一次轮询前无数据
            try
            {
                var configControllers = LoadDoorControllerConfig();
                SyncDoorControllers(configControllers);
            }
            catch (Exception ex)
            {
                Diagnosis.Log($"启动时加载门控制器配置失败: {ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
            }

            // 创建新的取消令牌源
            _cancellationTokenSource = new CancellationTokenSource();

            // 启动异步循环
            var token = _cancellationTokenSource.Token;
            _configTask = Task.Run(async () => await MonitorDoorConfigAsync(token), token);
            _stateTask = Task.Run(async () => await MonitorDoorLogicAsync(token), token);
            status.status = "Running";
        }

        /// <summary>
        /// 停止监控任务
        /// </summary>
        [MethodMember(Name = "停止进程")]
        [I18N.DocumentTranslation(Name = "Stop Mission", locale = "en")]
        public void Stop()
        {
            StopInternalAsync().GetAwaiter().GetResult();
            status.status = "/";
        }

        /// <summary>
        /// 取消并释放当前的取消令牌源
        /// </summary>
        private async Task StopInternalAsync()
        {
            // 取消事件订阅
            TrafficControl.BeforeLock -= BeforeLockEvent;
            TrafficControl.AfterLeave -= AfterLeaveEvent;
            TrafficControl.OnLockAcquired -= OnLockAcquiredEvent;

            var cts = Interlocked.Exchange(ref _cancellationTokenSource, null);
            var configTask = Interlocked.Exchange(ref _configTask, null);
            var stateTask = Interlocked.Exchange(ref _stateTask, null);

            if (cts == null && configTask == null && stateTask == null)
            {
                return;
            }

            try
            {
                cts?.Cancel();
            }
            catch (ObjectDisposedException)
            {
                // 已释放，忽略
            }

            var runningTasks = new[] { configTask, stateTask }
                .Where(t => t != null)
                .ToArray();

            if (runningTasks.Length > 0)
            {
                var aggregateTask = Task.WhenAll(runningTasks);
                var timeoutTask = Task.Delay(TimeSpan.FromSeconds(5));
                var completedTask = await Task.WhenAny(aggregateTask, timeoutTask).ConfigureAwait(false);

                if (completedTask == timeoutTask)
                {
                    Diagnosis.Log("停止门控任务超时", "DoorMission", true);
                }
                else
                {
                    try
                    {
                        await aggregateTask.ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        Diagnosis.Log($"停止门控任务时发生异常: {ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
                    }
                }
            }

            cts?.Dispose();

            DisconnectAllDoorControllers();
        }

        /// <summary>
        /// 断开所有门控制器连接
        /// </summary>
        private void DisconnectAllDoorControllers()
        {
            List<BasicDoorController> snapshot;
            lock (_syncLock)
            {
                snapshot = _doorControllers.ToList();
            }

            foreach (var controller in snapshot)
            {
                try
                {
                    controller.Disconnect();
                }
                catch (Exception ex)
                {
                    Diagnosis.Log($"停止门控制器失败: Index={controller.Index}, Error={ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
                }
            }
        }

        /// <summary>
        /// 异步监控门控制器配置文件
        /// </summary>
        private async Task MonitorDoorConfigAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    // 读取配置文件
                    var configControllers = LoadDoorControllerConfig();

                    // 同步门控制器列表
                    SyncDoorControllers(configControllers);

                    // 等待10秒
                    await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken);
                }
                catch (OperationCanceledException)
                {
                    // 正常取消，退出循环
                    break;
                }
                catch (Exception ex)
                {
                    Diagnosis.Log($"门控制器配置监控错误: {ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
                    // 发生错误时等待5秒后重试
                    try
                    {
                        await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
                    }
                    catch (OperationCanceledException)
                    {
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 监控门控逻辑
        /// </summary>
        private async Task MonitorDoorLogicAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    lock (_syncLock)
                    {
                        foreach (var controller in _doorControllers)
                        {
                            foreach (var doorConfig in controller.DoorConfigs.Values)
                            {
                                var doorIndex = doorConfig.Index;
                                var key = (controller.Index, doorIndex);
                                var needOpen = _needOpen.TryGetValue(key, out var open) && open;

                                // 自动目标：有车或需要打开
                                var hasCarsInArea = carsInAreas.TryGetValue(key, out var cars) && cars.Count > 0;
                                var autoTarget = needOpen || hasCarsInArea;

                                // 手动请求仲裁：优先级 Manual > Auto，手动过期后自动恢复
                                bool finalTarget = autoTarget;
                                if (_manualRequests.TryGetValue(key, out var manual))
                                {
                                    if (manual.ExpireAt <= DateTime.Now)
                                    {
                                        _manualRequests.Remove(key);
                                    }
                                    else
                                    {
                                        finalTarget = manual.Target;
                                    }
                                }

                                // 仅更新门控制器中的目标控制字段，不直接进行通信
                                controller.SetDoorControlTarget(doorIndex, finalTarget);
                            }
                        }
                    }

                    await Task.Delay(TimeSpan.FromMilliseconds(500), cancellationToken);
                }
                catch (OperationCanceledException)
                {
                    // 正常取消，退出循环
                    break;
                }
                catch (Exception ex)
                {
                    Diagnosis.Log($"门控逻辑监控错误: {ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
                    // 发生错误时等待5秒后重试
                    try
                    {
                        await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
                    }
                    catch (OperationCanceledException)
                    {
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 加载门控制器配置文件
        /// </summary>
        private List<DoorControllerModel> LoadDoorControllerConfig()
        {
            try
            {
                if (File.Exists(_dataFilePath))
                {
                    var jsonContent = File.ReadAllText(_dataFilePath, Encoding.UTF8);
                    if (!string.IsNullOrWhiteSpace(jsonContent))
                    {
                        var controllers = jsonContent.JsonTo<List<DoorControllerModel>>();
                        return controllers ?? new List<DoorControllerModel>();
                    }
                }
            }
            catch (Exception ex)
            {
                Diagnosis.Log($"加载门控制器配置文件失败: {ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
            }

            return new List<DoorControllerModel>();
        }

        /// <summary>
        /// 同步门控制器列表，根据配置文件进行增删改
        /// </summary>
        private void SyncDoorControllers(List<DoorControllerModel> configControllers)
        {
            var controllersToAdd = new List<DoorControllerModel>();

            lock (_syncLock)
            {
                // 创建配置中的门控制器索引字典
                var configDict = configControllers.ToDictionary(c => c.Index);

                // 创建当前门控制器索引字典
                var currentDict = _doorControllers.ToDictionary(c => c.Index);

                // 1. 删除：在配置中不存在的门控制器
                var toRemove = _doorControllers.Where(c => !configDict.ContainsKey(c.Index)).ToList();
                foreach (var controller in toRemove)
                {
                    try
                    {
                        controller.Disconnect();
                        _doorControllers.Remove(controller);
                        Diagnosis.Post($"删除门控制器: Index={controller.Index}, IP={controller.Ip}", "DoorMission", true);
                    }
                    catch (Exception ex)
                    {
                        Diagnosis.Log($"删除门控制器失败: {ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
                    }
                }

                // 2. 添加和修改：遍历配置中的门控制器
                foreach (var configController in configControllers)
                {
                    if (currentDict.TryGetValue(configController.Index, out var existingController))
                    {
                        // 修改：检查是否需要更新
                        if (ShouldUpdateDoorController(existingController, configController))
                        {
                            try
                            {
                                UpdateDoorController(existingController, configController);
                                Diagnosis.Post($"更新门控制器: Index={configController.Index}, IP={configController.Ip}, Type={configController.Type}", "DoorMission", true);
                            }
                            catch (Exception ex)
                            {
                                Diagnosis.Log($"更新门控制器失败: {ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
                            }
                        }
                    }
                    else
                    {
                        controllersToAdd.Add(configController);
                    }
                }
            }

            foreach (var configController in controllersToAdd)
            {
                try
                {
                    var newController = CreateDoorControllerInstance(configController);
                    if (newController != null)
                    {
                        lock (_syncLock)
                        {
                            _doorControllers.Add(newController);
                        }
                        Diagnosis.Post($"添加门控制器: Index={configController.Index}, IP={configController.Ip}, Type={configController.Type}", "DoorMission", true);
                    }
                    else
                    {
                        Diagnosis.Log($"无法创建门控制器实例: Index={configController.Index}, Type={configController.Type}", "DoorMission", true);
                    }
                }
                catch (Exception ex)
                {
                    Diagnosis.Log($"添加门控制器失败: {ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
                }
            }
        }

        /// <summary>
        /// 获取门控制器类型的 DoorTypeAttribute.Name
        /// </summary>
        private string GetDoorTypeName(Type controllerType)
        {
            if (controllerType == null)
            {
                return string.Empty;
            }

            var attr = controllerType.GetCustomAttribute<DoorTypeAttribute>();
            return attr?.Name ?? controllerType.Name;
        }

        /// <summary>
        /// 判断是否需要更新门控制器
        /// </summary>
        private bool ShouldUpdateDoorController(BasicDoorController existingController, DoorControllerModel configController)
        {
            // 检查基本属性是否变更
            var existingTypeName = GetDoorTypeName(existingController.GetType());
            if (existingController.Ip != configController.Ip
                || existingController.Port != configController.Port
                || existingTypeName != configController.Type)
            {
                return true;
            }

            // 检查门配置信息是否变更
            return HasDoorConfigsChanged(existingController, configController);
        }

        /// <summary>
        /// 检查门配置信息是否变更
        /// </summary>
        private bool HasDoorConfigsChanged(BasicDoorController existingController, DoorControllerModel configController)
        {
            var configDoors = configController.Doors ?? new List<DoorModel>();
            var configDict = configDoors.ToDictionary(d => d.Index);
            var existingDict = existingController.DoorConfigs;

            // 检查门数量是否变化
            if (existingDict.Count != configDict.Count)
            {
                return true;
            }

            // 检查每个门的配置是否变化
            foreach (var configDoor in configDoors)
            {
                if (!existingDict.TryGetValue(configDoor.Index, out var existingDoor))
                {
                    // 新增了门
                    return true;
                }

                // 检查门配置是否变化
                if (existingDoor.ControlAddress != configDoor.ControlAddress
                    || existingDoor.OpenStatusAddress != configDoor.OpenStatusAddress)
                {
                    return true;
                }
            }

            // 检查是否有门被删除
            foreach (var existingKey in existingDict.Keys)
            {
                if (!configDict.ContainsKey(existingKey))
                {
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// 更新门控制器属性
        /// </summary>
        private void UpdateDoorController(BasicDoorController controller, DoorControllerModel configController)
        {
            // 如果类型改变，需要重新创建实例
            var existingTypeName = GetDoorTypeName(controller.GetType());
            if (existingTypeName != configController.Type)
            {
                // 断开旧连接
                controller.Disconnect();

                // 从列表中移除
                _doorControllers.Remove(controller);

                // 创建新实例
                var newController = CreateDoorControllerInstance(configController);
                if (newController != null)
                {
                    _doorControllers.Add(newController);
                }
            }
            else
            {
                // 只更新属性
                bool needReconnect = controller.Ip != configController.Ip || controller.Port != configController.Port;
                controller.Ip = configController.Ip;
                controller.Port = configController.Port;

                // 更新门配置信息
                controller.UpdateDoorConfigs(configController.Doors);

                // 初始化门状态（基于配置中的门索引）
                var doorIndices = configController.Doors?.Select(d => d.Index).ToList() ?? new List<int>();
                controller.InitializeDoors(doorIndices);

                // 如果IP或端口改变，需要重新连接
                if (needReconnect)
                {
                    controller.Disconnect();
                    controller.Connect();
                }
            }
        }

        /// <summary>
        /// 根据 DoorTypeAttribute.Name 获取类型
        /// </summary>
        private Type GetControllerTypeByDoorTypeName(string doorTypeName)
        {
            if (string.IsNullOrWhiteSpace(doorTypeName))
            {
                return null;
            }

            try
            {
                // 在插件/宿主环境下 GetExecutingAssembly 可能不是 StandardScene.dll
                // 这里固定从门控制器基类所在程序集查找
                // 跨程序集发现：门控制器具体类型可能位于卫星插件 dll（StandardScene.Devices.Door），
                // 用内核同款全域类型发现替代仅扫基类所在程序集。
                var allControllerTypes = SimpleLite.Utils.UiTypeDiscovery.AllTypes()
                    .Where(t => t.IsClass
                        && !t.IsAbstract
                        && t.Namespace == typeof(BasicDoorController).Namespace
                        && t.IsSubclassOf(typeof(BasicDoorController))
                        && t.IsDefined(typeof(DoorTypeAttribute), false));

                foreach (var type in allControllerTypes)
                {
                    var attr = type.GetCustomAttribute<DoorTypeAttribute>();
                    if (attr != null && attr.Name == doorTypeName)
                    {
                        return type;
                    }
                }

                return null;
            }
            catch (Exception ex)
            {
                Diagnosis.Log($"获取门控制器类型失败: DoorTypeName={doorTypeName}, Error={ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
                return null;
            }
        }

        /// <summary>
        /// 通过 DoorTypeAttribute.Name 创建门控制器实例
        /// </summary>
        private BasicDoorController CreateDoorControllerInstance(DoorControllerModel configController)
        {
            if (string.IsNullOrWhiteSpace(configController.Type))
            {
                return null;
            }

            try
            {
                // 通过 DoorTypeAttribute.Name 查找类型
                var controllerType = GetControllerTypeByDoorTypeName(configController.Type);

                if (controllerType == null)
                {
                    Diagnosis.Log($"未找到门控制器类型: {configController.Type}", "DoorMission", true);
                    return null;
                }

                // 使用反射创建实例
                var instance = (BasicDoorController)Activator.CreateInstance(controllerType);

                // 设置属性
                instance.Index = configController.Index;
                instance.Ip = configController.Ip;
                instance.Port = configController.Port;

                // 初始化门配置信息
                instance.InitializeDoorConfigs(configController.Doors);

                // 初始化门状态（基于配置中的门索引）
                var doorIndices = configController.Doors?.Select(d => d.Index).ToList() ?? new List<int>();
                instance.InitializeDoors(doorIndices);

                // 自动连接
                instance.Connect();

                return instance;
            }
            catch (Exception ex)
            {
                Diagnosis.Log($"创建门控制器实例失败: Type={configController.Type}, Error={ExceptionFormatter.FormatEx(ex)}", "DoorMission", true);
                return null;
            }
        }

        /// <summary>
        /// 获取当前所有门控制器实例（只读）
        /// </summary>
        public IReadOnlyList<BasicDoorController> GetDoorControllers()
        {
            lock (_syncLock)
            {
                return _doorControllers.ToList().AsReadOnly();
            }
        }

        /// <summary>
        /// 获取用于监控界面的门状态快照
        /// </summary>
        public IReadOnlyList<DoorMonitorSnapshotItem> GetDoorMonitorSnapshot()
        {
            lock (_syncLock)
            {
                var snapshot = new List<DoorMonitorSnapshotItem>();
                var now = DateTime.Now;

                foreach (var controller in _doorControllers)
                {
                    var doorConfigs = controller.DoorConfigs?.Values?.ToList() ?? new List<DoorModel>();
                    foreach (var doorConfig in doorConfigs)
                    {
                        var key = (controller.Index, doorConfig.Index);
                        var cars = carsInAreas.TryGetValue(key, out var list) && list != null
                            ? list.ToList().AsReadOnly()
                            : new List<int>().AsReadOnly();

                        var source = ControlSource.Auto;
                        double? manualRemaining = null;
                        bool target = false;

                        if (_manualRequests.TryGetValue(key, out var manual))
                        {
                            if (manual.ExpireAt > now)
                            {
                                source = ControlSource.Manual;
                                target = manual.Target;
                                manualRemaining = (manual.ExpireAt - now).TotalSeconds;
                            }
                            else
                            {
                                _manualRequests.Remove(key);
                            }
                        }

                        if (source == ControlSource.Auto)
                        {
                            var needOpen = _needOpen.TryGetValue(key, out var open) && open;
                            target = needOpen || cars.Count > 0;
                        }

                        snapshot.Add(new DoorMonitorSnapshotItem
                        {
                            ControllerIndex = controller.Index,
                            DoorIndex = doorConfig.Index,
                            State = controller.GetDoorState(doorConfig.Index),
                            Target = target,
                            Source = source,
                            ManualRemainingSeconds = manualRemaining,
                            CarsInArea = cars,
                            ControlAddress = doorConfig.ControlAddress,
                            OpenStatusAddress = doorConfig.OpenStatusAddress
                        });
                    }
                }

                return snapshot.AsReadOnly();
            }
        }

        /// <summary>
        /// 解析门标识符字符串（格式：控制器索引.门索引）
        /// </summary>
        /// <param name="doorIdentifier">门标识符字符串，格式：控制器索引.门索引</param>
        /// <returns>如果解析成功返回(控制器索引, 门索引)，否则返回null</returns>
        private (int ControllerIndex, int DoorIndex)? ParseDoorIdentifier(string doorIdentifier)
        {
            if (string.IsNullOrWhiteSpace(doorIdentifier))
            {
                return null;
            }

            var parts = doorIdentifier.Split('.');
            if (parts.Length != 2)
            {
                return null;
            }

            if (int.TryParse(parts[0].Trim(), out int controllerIndex) &&
                int.TryParse(parts[1].Trim(), out int doorIndex))
            {
                return (controllerIndex, doorIndex);
            }

            return null;
        }

        /// <summary>
        /// 读取门状态
        /// </summary>
        /// <param name="controllerIndex">门控制器索引</param>
        /// <param name="doorIndex">门索引</param>
        /// <returns>true=打开，false=关闭</returns>
        public bool GetDoorState(int controllerIndex, int doorIndex)
        {
            lock (_syncLock)
            {
                var controller = _doorControllers.FirstOrDefault(c => c.Index == controllerIndex);
                if (controller != null && controller.DoorConfigs.ContainsKey(doorIndex))
                {
                    // 只访问控制器中的门状态字段，不直接进行通信
                    var state = controller.GetDoorState(doorIndex);
                    return state == DoorState.Open;
                }
            }
            return false;
        }

        /// <summary>
        /// 写入门控制状态
        /// </summary>
        /// <param name="controllerIndex">门控制器索引</param>
        /// <param name="doorIndex">门索引</param>
        /// <param name="open">true=打开，false=关闭</param>
        public void SetDoorControlTarget(int controllerIndex, int doorIndex, bool open)
        {
            lock (_syncLock)
            {
                var controller = _doorControllers.FirstOrDefault(c => c.Index == controllerIndex);
                if (controller != null && controller.DoorConfigs.ContainsKey(doorIndex))
                {
                    // 仅设置门的目标控制状态，由门控制器内部线程负责实际通信
                    controller.SetDoorControlTarget(doorIndex, open);
                }
            }
        }

        /// <summary>
        /// 设置手动控制目标，支持保持时间，车辆占用时禁止手动关闭
        /// </summary>
        /// <param name="controllerIndex">控制器索引</param>
        /// <param name="doorIndex">门索引</param>
        /// <param name="open">目标开关</param>
        /// <param name="holdSeconds">手动保持秒数，默认10秒</param>
        /// <returns>成功返回true；当占用且尝试关闭时返回false</returns>
        public bool SetManualDoorControl(int controllerIndex, int doorIndex, bool open, int? holdSeconds = null)
        {
            lock (_syncLock)
            {
                // 车辆占用时禁止手动关闭
                var key = (controllerIndex, doorIndex);
                if (!open && carsInAreas.TryGetValue(key, out var cars) && cars.Count > 0)
                {
                    return false;
                }

                var seconds = holdSeconds.GetValueOrDefault(DefaultManualHoldSeconds);
                _manualRequests[key] = new ManualControlRequest
                {
                    Target = open,
                    ExpireAt = DateTime.Now.AddSeconds(seconds)
                };
                return true;
            }
        }

        /// <summary>
        /// 清除手动控制，恢复自动
        /// </summary>
        public void ClearManualDoorControl(int controllerIndex, int doorIndex)
        {
            lock (_syncLock)
            {
                var key = (controllerIndex, doorIndex);
                _manualRequests.Remove(key);
            }
        }

        /// <summary>
        /// 清空车辆占用记录
        /// </summary>
        public void ClearCarsInArea(int controllerIndex, int doorIndex)
        {
            lock (_syncLock)
            {
                var key = (controllerIndex, doorIndex);
                if (carsInAreas.ContainsKey(key))
                {
                    carsInAreas[key].Clear();
                }
            }
        }

        /// <summary>
        /// 获取门的控制状态（目标、来源、手动剩余时间、占用车辆）
        /// </summary>
        public DoorControlStatus GetDoorControlStatus(int controllerIndex, int doorIndex)
        {
            lock (_syncLock)
            {
                var key = (controllerIndex, doorIndex);

                // 车辆占用
                IReadOnlyList<int> cars;
                if (carsInAreas.TryGetValue(key, out var list) && list != null)
                {
                    cars = list.ToList().AsReadOnly();
                }
                else
                {
                    cars = new List<int>().AsReadOnly();
                }

                // 当前目标来源与剩余
                var source = ControlSource.Auto;
                double? remaining = null;
                bool target = false;

                if (_manualRequests.TryGetValue(key, out var manual))
                {
                    if (manual.ExpireAt > DateTime.Now)
                    {
                        source = ControlSource.Manual;
                        target = manual.Target;
                        remaining = (manual.ExpireAt - DateTime.Now).TotalSeconds;
                    }
                    else
                    {
                        _manualRequests.Remove(key);
                    }
                }

                if (source == ControlSource.Auto)
                {
                    var needOpen = _needOpen.TryGetValue(key, out var open) && open;
                    var hasCars = cars.Count > 0;
                    target = needOpen || hasCars;
                }

                return new DoorControlStatus
                {
                    Target = target,
                    Source = source,
                    ManualRemainingSeconds = remaining,
                    CarsInArea = cars
                };
            }
        }

        /// <summary>
        /// 获取门的车辆占用情况
        /// </summary>
        /// <param name="controllerIndex">门控制器索引</param>
        /// <param name="doorIndex">门索引</param>
        /// <returns>车辆ID列表，如果没有车辆则返回空列表</returns>
        public IReadOnlyList<int> GetCarsInArea(int controllerIndex, int doorIndex)
        {
            lock (_syncLock)
            {
                var key = (controllerIndex, doorIndex);
                if (carsInAreas.TryGetValue(key, out var cars) && cars != null)
                {
                    return cars.ToList().AsReadOnly();
                }
                return new List<int>().AsReadOnly();
            }
        }

        private bool BeforeLockEvent(AbstractCar car, int siteId)
        {
            var site = SimpleLib.GetSite(siteId);

            if (!site.fields.TryGetValue("EnterDoor", out string fieldStr)) return true;
            var lastSiteId = car.status.holdingLocks.LastOrDefault();
            var lastSite = SimpleLib.GetSite(lastSiteId);
            if (lastSite == null || !lastSite.fields.TryGetValue("PreEnterDoor",out var value)) return true;
            if (value != fieldStr) return true;
            var doorInfo = ParseDoorIdentifier(fieldStr);
            if (!doorInfo.HasValue) return true;
            var (controllerIndex, doorIndex) = doorInfo.Value;
            lock (_syncLock)
            {
                _needOpen[(controllerIndex, doorIndex)] = true;
                return GetDoorState(controllerIndex, doorIndex);
            }
        }

        private void AfterLeaveEvent(AbstractCar car, int siteId)
        {
            var site = SimpleLib.GetSite(siteId);

            if (!site.fields.TryGetValue("LeaveDoor", out string fieldStr)) return;
            var carSiteId = car.status.holdingLocks.FirstOrDefault();
            var carSite = SimpleLib.GetSite(carSiteId);
            if (carSite == null || !carSite.fields.TryGetValue("RearLeaveDoor",out var value)) return;
            if (value != fieldStr) return;
            var doorInfo = ParseDoorIdentifier(fieldStr);
            if (!doorInfo.HasValue) return;
            var (controllerIndex, doorIndex) = doorInfo.Value;
            var key = (controllerIndex, doorIndex);
            lock (_syncLock)
            {
                if (carsInAreas.TryGetValue(key, out var list))
                {
                    list.Remove(car.id);
                }
            }
        }

        private void OnLockAcquiredEvent(AbstractCar car, int siteId)
        {
            var site = SimpleLib.GetSite(siteId);
            if (!site.fields.TryGetValue("EnterDoor", out string fieldStr)) return;
            if(car.status.holdingLocks.Length<2) return;
            var preSiteId = car.status.holdingLocks[car.status.holdingLocks.Length-2];
            var preSite = SimpleLib.GetSite(preSiteId);
            if (preSite == null || !preSite.fields.TryGetValue("PreEnterDoor", out var value)) return ;
            if (value != fieldStr) return ;
            var doorInfo = ParseDoorIdentifier(fieldStr);
            if (!doorInfo.HasValue) return;
            var (controllerIndex, doorIndex) = doorInfo.Value;
            var key = (controllerIndex, doorIndex);
            lock (_syncLock)
            {
                if (!carsInAreas.TryGetValue(key, out var list))
                {
                    list = new List<int>();
                    carsInAreas[key] = list;
                }
                if (!list.Contains(car.id))
                {
                    list.Add(car.id);
                }
                _needOpen[key] = false;
            }
        }

        /// <summary>
        /// 打开门控制器管理界面
        /// </summary>
        [MethodMember(Name = "打开管理界面")]
        [I18N.DocumentTranslation(Name = "Open Manager", locale = "en")]
        public static void OpenViewer()
        {
            DoorManager.OpenViewer();
        }

        /// <summary>
        /// 打开门控监控界面
        /// </summary>
        [MethodMember(Name = "打开监控界面")]
        [I18N.DocumentTranslation(Name = "Open Monitor", locale = "en")]
        public static void OpenMonitor()
        {
            try
            {
                DoorMonitor.Open();
            }
            catch (Exception ex)
            {
                CycleUiHelper.Alert("错误", $"打开门控监控界面失败: {ex.Message}");
            }
        }
    }
}
