using BOB.Models;
using Common.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;

namespace BOB.ViewModels
{
    public class SingleStepEditViewModel:BindableBase
    {
        #region 属性
        private Guid _ID;
        public Guid ID
        {
            get => _ID;
            set => SetProperty(ref _ID, value);
        }
        private StepModel _SelectedStep;
        public StepModel SelectedStep
        {
            get => _SelectedStep;
            set => SetProperty(ref _SelectedStep, value);
        }
        public ProgramModel Program
        {
            get => _globalVariables.Program;
            set
            {
                if (_globalVariables.Program != value)
                {
                    _globalVariables.Program = value;
                    RaisePropertyChanged();
                }
            }
        }
        #endregion
        private GlobalVariables _globalVariables;
        private IEventAggregator _eventAggregator;
        private IDialogService _dialogService;
        public ICommand CancelEditCommand { get; set; }
        public ICommand SaveStepCommand { get; set; }
        public SingleStepEditViewModel(GlobalVariables globalVariables,IEventAggregator eventAggregator,IDialogService dialogService)
        {
            _globalVariables= globalVariables;
            _eventAggregator= eventAggregator;
            _dialogService = dialogService;
            _eventAggregator.GetEvent<EditSetpEvent>().Subscribe(EditSingleSetp);
            CancelEditCommand = new DelegateCommand(CancelEdit);    
            SaveStepCommand = new DelegateCommand(SaveStep);
            _eventAggregator.GetEvent<DeletedStepEvent>().Subscribe(DisposeSelectedStep);
            _eventAggregator.GetEvent<ParamsChangedEvent>().Subscribe(ParamsChanged);
        }

        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 = _globalVariables.Program.StepCollection;
            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("循环指令参数设置错误：类型转换失败");
                        }
                    }
                    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 = _globalVariables.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 = _globalVariables.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 = _globalVariables.Program.StepCollection.ElementAtOrDefault(ok-1)?.ID ?? Guid.Empty;
                Guid ngGuid = _globalVariables.Program.StepCollection.ElementAtOrDefault(ng-1)?.ID ?? Guid.Empty;

                return (okGuid, ngGuid);
            }
            return (Guid.Empty, Guid.Empty);
        }
        private void EditSingleSetp()
        {
            ID = _globalVariables.SelectedStep.ID;
            SelectedStep = new StepModel(_globalVariables.SelectedStep);
        }
    }
}
