using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Input;
using DeviceCommand.Devices;
using Logger;
using Prism.Ioc;
using TestingModule.ViewModels;
using UIShare;
using UIShare.GlobalVariable;
using UIShare.PubEvent;
using UIShare.UIViewModel;
using UIShare.ViewModelBase;
using static System.Formats.Asn1.AsnWriter;

namespace MainModule.ViewModels
{
    public class AutomatedTestingViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable
    {
        #region 私有字段
        private string _testStatus;
        private readonly IScopedProvider _scope;
        private bool IsInitialized =false;
        private bool _isRunningErrorSteps = false;
        private SubscriptionToken? _alarmToken;
        #endregion

        #region 属性
        public bool KeepAlive => true; // 保持存活

        public string TestStatus
        {
            get => _testStatus;
            set => SetProperty(ref _testStatus, value);
        }

        // 该 AutomatedTestingView 实例独占的 ScopedContext，5 个子面板共享
        public ScopedContext _scopedContext { get; }
        public StepRunning _stepRunning { get; }
        public GlobalInfo _globalInfo { get; }
        public SystemConfig _systemConfig { get; set; }
        public DeviceManager _deviceManager { get; set; }

        // 5 个子 ViewModel 全部从同一个 scope 解析，自动注入同一个 ScopedContext
        public CommandTreeViewModel       CommandTreeVM       { get; }
        public StepsManagerViewModel      StepsManagerVM      { get; }
        public SingleStepEditViewModel    SingleStepEditVM    { get; }
        public LogAreaViewModel           LogAreaVM           { get; }
        public ParametersManagerViewModel ParametersManagerVM { get; }
        #endregion

        public ICommand RefreshCommand { get; set; }
        public ICommand BackToProtocolCommand { get; set; }
        public ICommand LoadedCommand { get; set; }

        public AutomatedTestingViewModel(IContainerExtension container) : base(container)
        {
            // 每个 AutomatedTestingViewModel 实例创建独立的容器作用域
            _scope = container.CreateScope();
            _globalInfo =container.Resolve<GlobalInfo>();
            _systemConfig = _scope.Resolve<SystemConfig>();
            //加载Json数据
            if (ConfigService.IsExit(_globalInfo.CurrentOpeningScope))
            {
                string filePath = System.IO.Path.Combine(_systemConfig.SystemPath, $"{_globalInfo.CurrentOpeningScope}.json");
                if (System.IO.File.Exists(filePath))
                {
                    string json = System.IO.File.ReadAllText(filePath);
                    Newtonsoft.Json.JsonConvert.PopulateObject(json, _systemConfig);
                }
            }
            //容器解析顺序不要改变！！！
            _scopedContext = _scope.Resolve<ScopedContext>();
            _deviceManager = _scope.Resolve<DeviceManager>();
            _stepRunning = _scope.Resolve<StepRunning>();
            // 从同一个 _scope 解析 5 个子 VM，DI 会把同一个 ScopedContext 注入它们
            CommandTreeVM       = _scope.Resolve<CommandTreeViewModel>();
            StepsManagerVM      = _scope.Resolve<StepsManagerViewModel>();
            SingleStepEditVM    = _scope.Resolve<SingleStepEditViewModel>();
            LogAreaVM           = _scope.Resolve<LogAreaViewModel>();
            ParametersManagerVM = _scope.Resolve<ParametersManagerViewModel>();
            RefreshCommand = new DelegateCommand(OnRefresh);
            BackToProtocolCommand = new DelegateCommand(OnBackToProtocol);
            LoadedCommand = new AsyncDelegateCommand(OnLoad);
            _eventAggregator.GetEvent<SilenceBuzzerEvent>().Subscribe(async (scope) => await SilenceBuzzer(scope));
            _alarmToken = _eventAggregator.GetEvent<AlarmEvent>().Subscribe(OnAlarmTriggered);
        }

        private async Task SilenceBuzzer(string scope)
        {
            if (_deviceManager.IOGroup == null) return;

            if (scope == "default")
            {
                for(int i = 1; i <= 8; i++)
                {
                    await _deviceManager.IOGroup.执行台架动作Async(i, 功能动作.蜂鸣器报警, false);
                }
            }
            else if (scope == TestStatus)
            {
                int 台架号 = _systemConfig.SharedParameterList
                    .FirstOrDefault(x => x.ParameterName == "台架序号")?.Value ?? 0;
                if (台架号 >= 1 && 台架号 <= 8)
                {
                    await _deviceManager.IOGroup.执行台架动作Async(台架号, 功能动作.蜂鸣器报警, false);
                }
            }
        }

        /// <summary>
        /// AlarmEvent 回调：
        ///   上下限 → 蜂鸣器报警 true
        ///   上下极限 → 蜂鸣器报警 true + 执行对应 scope 的异常流程
        /// </summary>
        private async void OnAlarmTriggered((string Scope, string Fingerprint, string Status) args)
        {
            if (args.Scope != TestStatus) return;
            if (_deviceManager?.IOGroup == null) return;

            int 台架号 = _systemConfig.SharedParameterList
                .FirstOrDefault(x => x.ParameterName == "台架序号")?.Value ?? 0;
            if (台架号 < 1 || 台架号 > 8) return;

            // 上下限 / 上下极限 均触发蜂鸣器报警
            await _deviceManager.IOGroup.执行台架动作Async(台架号, 功能动作.蜂鸣器报警, true);
            LoggerHelper.WarnWithNotify(args.Scope, $"[{args.Scope}] 报警触发: {args.Status} ({args.Fingerprint})，蜂鸣器已开启。");

            // 上下极限额外触发异常流程
            if (args.Status == "超上极限" || args.Status == "超下极限")
            {
                _ = TriggerErrorStepsAsync();
            }
        }

        /// <summary>
        /// 执行异常流程（带并发保护，同一时间仅允许一次）。
        /// 如果正常流程正在运行，先取消并等待其停止，再执行异常流程。
        /// </summary>
        private async Task TriggerErrorStepsAsync()
        {
            if (_isRunningErrorSteps) return;
            _isRunningErrorSteps = true;
            try
            {
                // 1. 如果正常流程正在运行，先停止它
                //    IsStop == false 表示正在运行；IsStop == null 表示未启动或已结束
                if (_scopedContext.IsStop == false)
                {
                    LoggerHelper.WarnWithNotify(TestStatus, $"[{TestStatus}] 报警触发，正在停止正常流程...");
                    _stepRunning.stepCTS.Cancel();

                    // 等待 ShellViewModel 清理完毕（IsStop 变回 null、stepCTS 被重置）
                    // ExecuteMethodStep 内部硬编码使用 stepCTS.Token，必须等它重置后才能跑异常流程
                    var deadline = DateTime.Now.AddSeconds(5);
                    while ((_scopedContext.IsStop != null || _stepRunning.stepCTS.IsCancellationRequested)
                           && DateTime.Now < deadline)
                    {
                        await Task.Delay(50);
                    }

                    // 超时后仍未重置则强制重置，确保异常流程的设备命令能拿到有效 Token
                    if (_stepRunning.stepCTS.IsCancellationRequested)
                    {
                        _stepRunning.stepCTS = new CancellationTokenSource();
                        _scopedContext.IsStop = null;
                        _scopedContext.RunState = "运行";
                    }

                    LoggerHelper.WarnWithNotify(TestStatus, $"[{TestStatus}] 正常流程已停止，开始执行异常流程");
                }

                // 2. 执行异常流程
                await _stepRunning.ExecuteErrorSteps(
                    _scopedContext.Program,
                    cancellationToken: _stepRunning.errorStepCTS.Token);
            }
            catch (Exception ex)
            {
                LoggerHelper.ErrorWithNotify(TestStatus, $"[{TestStatus}] 报警触发异常流程失败: {ex.Message}");
            }
            finally
            {
                _isRunningErrorSteps = false;
                if (_stepRunning.errorStepCTS.IsCancellationRequested)
                    _stepRunning.errorStepCTS = new CancellationTokenSource();
            }
        }

        public void Dispose()
        {
            // 1. 如果 TestStatus 为空，说明还没走到 OnNavigatedTo 赋值，直接释放 scope 即可
            if (string.IsNullOrEmpty(TestStatus))
            {
                _scope?.Dispose();
                return;
            }

            try
            {
                if (_alarmToken != null)
                    _eventAggregator.GetEvent<AlarmEvent>().Unsubscribe(_alarmToken);
                _eventAggregator.GetEvent<SilenceBuzzerEvent>().Unsubscribe(async (scope) => await SilenceBuzzer(scope));
                // 2. 显式释放硬件资源（防止端口占用/死锁）
                if (_deviceManager is IDisposable disposableDevice)
                {
                    disposableDevice.Dispose();
                }
                (CommandTreeVM as IDisposable)?.Dispose();
                (StepsManagerVM as IDisposable)?.Dispose();
                (SingleStepEditVM as IDisposable)?.Dispose();
                (LogAreaVM as IDisposable)?.Dispose();
                (ParametersManagerVM as IDisposable)?.Dispose();

                _globalInfo.ContextDic?.Remove(TestStatus);
                _globalInfo.StepRunningDic?.Remove(TestStatus);
                _globalInfo.ConfigDic?.Remove(TestStatus);
                _globalInfo.ScopeDic?.Remove(TestStatus); 
            }
            catch (Exception ex)
            {
                Logger.LoggerHelper.ErrorWithNotify(TestStatus, $"卸载机台 [{TestStatus}] 全局引用或资源失败: {ex.Message}");
            }
            finally
            {
                _scope?.Dispose();
            }
        }
        #region 命令处理与事件
        private async Task OnLoad()
        {
            if (!IsInitialized)
            {
                await _deviceManager.ConnectAllDevices();
                IsInitialized = true;
            }
        }

        private void OnRefresh()
        {
            // 双击：把自己的名字扔出去
            _globalInfo.CurrentScope = TestStatus;
            _eventAggregator.GetEvent<ExpandViewEvent>().Publish(TestStatus);
      
        }

        private void OnBackToProtocol()
        {
            // 返回：扔个空字符串出去
            _eventAggregator.GetEvent<ExpandViewEvent>().Publish("");
        }
        #endregion

        #region 重写
        public override void OnNavigatedTo(NavigationContext navigationContext)
        {
            base.OnNavigatedTo(navigationContext);
            if (navigationContext.Parameters.ContainsKey("Name"))
            {
                TestStatus = navigationContext.Parameters.GetValue<string>("Name");
                _globalInfo.ContextDic.Add(TestStatus, _scopedContext);
                _globalInfo.StepRunningDic.Add(TestStatus, _stepRunning);
                _globalInfo.ScopeDic.Add(TestStatus, _scope);
                _globalInfo.ConfigDic.Add(TestStatus, _systemConfig);
                if(_systemConfig.DefaultProgramFilePath != null&&File.Exists(_systemConfig.DefaultProgramFilePath))
                {
                    var filePath = _systemConfig.DefaultProgramFilePath;
                    _systemConfig.CurrentADPFile= _systemConfig.DefaultProgramFilePath;
                    // 读取 JSON 文件
                    string json = File.ReadAllText(filePath);

                    // 反序列化为 ProgramVM
                    var program = Newtonsoft.Json.JsonConvert.DeserializeObject<ProgramVM>(json);

                    if (program == null)
                    {
                        LoggerHelper.WarnWithNotify(_globalInfo.CurrentScope, $"文件格式不正确或为空: {filePath}");
                        return;
                    }

                    // 💡 2. 严格赋值给快照锁定下的当前工位上下文，实现数据完全隔离
                    _scopedContext.Program.Parameters = program.Parameters;
                    _scopedContext.Program.StepCollection = program.StepCollection;
                    _scopedContext.Program.ErrorStepCollection = program.ErrorStepCollection;
                    _scopedContext.CurrentFilePath = filePath;
                    foreach (var item in _systemConfig.SharedParameterList)
                    {
                        var parameter = _scopedContext?.Program?.Parameters?.FirstOrDefault(x => x.Name == item.ParameterName);

                        if (parameter != null)
                        {
                            parameter.Value = item.Value;
                        }
                    }
                }
            }
                
        }
        #endregion
    }
}