using UIShare.UIViewModel;
using UIShare.PubEvent;
using Logger;
using Microsoft.IdentityModel.Logging;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using UIShare.ViewModelBase;
using Prism.Dialogs;
using Prism.Events;
using UIShare.GlobalVariable;

namespace TestingModule.ViewModels
{
    public class SingleStepEditViewModel:NavigateViewModelBase,IDisposable
    {
        #region 属性
        private Guid _ID;
        public Guid ID
        {
            get => _ID;
            set => SetProperty(ref _ID, value);
        }
        private StepVM _SelectedStep;
        public StepVM SelectedStep
        {
            get => _SelectedStep;
            set => SetProperty(ref _SelectedStep, value);
        }
        public ProgramVM Program
        {
            get => _ScopedContext.Program;
            set
            {
                if (_ScopedContext.Program != value)
                {
                    _ScopedContext.Program = value;
                    RaisePropertyChanged();
                }
            }
        }
        #endregion
        private ScopedContext _ScopedContext;
        private GlobalInfo _globalInfo;
        #region 命令
        public ICommand CancelEditCommand { get; set; }
        public ICommand SaveStepCommand { get; set; }
        #endregion
        public SingleStepEditViewModel(IContainerProvider containerProvider, ScopedContext scopedContext) : base(containerProvider)
        {
            _ScopedContext = scopedContext;
            _globalInfo=containerProvider.Resolve<GlobalInfo>();
            _eventAggregator.GetEvent<EditSetpEvent>().Subscribe(EditSingleStep);
            CancelEditCommand = new DelegateCommand(CancelEdit);
            SaveStepCommand = new DelegateCommand(SaveStep);
            _eventAggregator.GetEvent<DeletedStepEvent>().Subscribe(DisposeSelectedStep);
            _eventAggregator.GetEvent<ParamsChangedEvent>().Subscribe(ParamsChanged);
        }

        #region 委托命令
        private void ParamsChanged()
        {
            CancelEdit();
        }

        private void DisposeSelectedStep(Guid id)
        {
            if (SelectedStep == null) return;
            if(id== SelectedStep.ID)
            SelectedStep = null;
        }

        private void CancelEdit()
        {
            SelectedStep = null;
        }

        private void SaveStep()
        {
            if (SelectedStep == null || (SelectedStep.Method == null && SelectedStep.SubProgram == null))
            {
                return;
            }
            var steps = _ScopedContext.SelectedStepList=="主程序"?_ScopedContext.Program.StepCollection: _ScopedContext.Program.ErrorStepCollection;
            int index = steps.ToList().FindIndex(x => x.ID == ID);
            if (index >= 0)
            {
                steps[index] = SelectedStep;
                if (steps[index].Method != null)
                {
                    if (steps[index].StepType == "循环开始")
                    {
                        try
                        {
                            steps[index].LoopCount = Convert.ToInt32(SelectedStep.Method!.Parameters[0].Value);
                        }
                        catch
                        {
                            LoggerHelper.ErrorWithNotify(_globalInfo.CurrentScope,"循环指令参数设置错误：类型转换失败");
                        }
                    }
                    else
                    {   //设置步骤参数
                        (steps[index].OKGotoStepID, steps[index].NGGotoStepID) = GetOKNGGotoStepID(SelectedStep.GotoSettingString);
                        for (int i = 0; i < steps[index].Method.Parameters.Count; i++)
                        {
                            var editedParam = SelectedStep.Method!.Parameters[i];
                            var originalParam = steps[index].Method.Parameters[i];
                            if (editedParam.IsUseVar)
                            {
                                originalParam.VariableName = editedParam.VariableName;
                                originalParam.VariableID = _ScopedContext.Program.Parameters.FirstOrDefault(x => x.Name == editedParam.VariableName)!.ID;
                            }
                            originalParam.Value = editedParam.Value;
                            originalParam.IsUseVar = editedParam.IsUseVar;
                            originalParam.LowerLimit = editedParam.LowerLimit;
                            originalParam.UpperLimit = editedParam.UpperLimit;
                        }
                        var parameters = new DialogParameters
                            {
                               { "Title", "提示" },
                               { "Message", "保存成功！" },
                               { "Icon", "info" },
                               { "ShowOk", true }
                           };
                        _dialogService.ShowDialog("MessageBox", parameters);
                    }
                }
                else if (steps[index].SubProgram != null)
                {
                    if (SelectedStep.SubProgram.Parameters.Where(x => x.VariableName == null && x.IsUseVar == true).FirstOrDefault() != null)
                    {
                        var parameters1 = new DialogParameters
                            {
                               { "Title", "警告" },
                               { "Message", "选中变量不得为空！" },
                               { "Icon", "warn" },
                               { "ShowOk", true },
                           };
                        _dialogService.ShowDialog("MessageBox",parameters1);
                        return;
                    }
                    (steps[index].OKGotoStepID, steps[index].NGGotoStepID) = GetOKNGGotoStepID(SelectedStep.GotoSettingString);
                    for (int i = 0; i < steps[index].SubProgram.Parameters.Count; i++)
                    {
                        var editedParam = SelectedStep.SubProgram!.Parameters[i];
                        var originalParam = steps[index].SubProgram.Parameters[i];
                        if (editedParam.IsUseVar)
                        {
                            originalParam.VariableName = editedParam.VariableName;
                            originalParam.VariableID = _ScopedContext.Program.Parameters.FirstOrDefault(x => x.Name == editedParam.VariableName)!.ID;
                        }
                        originalParam.Value = editedParam.Value;
                        originalParam.IsUseVar = editedParam.IsUseVar;
                        originalParam.LowerLimit = editedParam.LowerLimit;
                        originalParam.UpperLimit = editedParam.UpperLimit; 
                    }
                    var parameters = new DialogParameters
                            {
                               { "Title", "提示" },
                               { "Message", "保存成功！" },
                               { "Icon", "info" },
                               { "ShowOk", true }
                           };
                    _dialogService.ShowDialog("MessageBox", parameters);
                }
            }

        }
        private (Guid,Guid) GetOKNGGotoStepID(string GotoSettingString)
        {
            if (string.IsNullOrWhiteSpace(GotoSettingString))
                return (Guid.Empty, Guid.Empty);

            var match = Regex.Match(GotoSettingString, @"^(\d+)\s*/\s*(\d+)$");
            if (match.Success)
            {
                int ok = int.Parse(match.Groups[1].Value);
                int ng = int.Parse(match.Groups[2].Value);

                Guid okGuid = _ScopedContext.Program.StepCollection.ElementAtOrDefault(ok-1)?.ID ?? Guid.Empty;
                Guid ngGuid = _ScopedContext.Program.StepCollection.ElementAtOrDefault(ng-1)?.ID ?? Guid.Empty;

                return (okGuid, ngGuid);
            }
            return (Guid.Empty, Guid.Empty);
        }
        private void EditSingleStep()
        {
            if (_ScopedContext.SelectedStep == null) return;
            ID = _ScopedContext.SelectedStep.ID;
            SelectedStep = new StepVM(_ScopedContext.SelectedStep);
        }
        #endregion
        public void Dispose()
        {
            try
            {
                // 1. 【核心修复】必须严格退订所有全局 Prism 事件
                _eventAggregator?.GetEvent<EditSetpEvent>()?.Unsubscribe(EditSingleStep);
                _eventAggregator?.GetEvent<DeletedStepEvent>()?.Unsubscribe(DisposeSelectedStep);
                _eventAggregator?.GetEvent<ParamsChangedEvent>()?.Unsubscribe(ParamsChanged);

                // 2. 清空当前正在编辑的步骤副本，断开前台绑定，防止 UI 视图树悬挂
                SelectedStep = null!;

                // 3. 断开对工位隔离上下文的强引用
                _ScopedContext = null!;
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"释放单步编辑组件（SingleStepEditViewModel）资源失败: {ex.Message}");
            }
        }

    }
}
