using CommunityToolkit.Mvvm.Messaging;
using CsvHelper;
using CsvHelper.Configuration;
using Dm;
using MegaRobo.Entities;
using ServiceReference1;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Task = System.Threading.Tasks.Task;

namespace MegaRobo.C00225155.ControlDevices
{
    public class LabxService
    {
        public Guid abortWaitingHeadTaskId = new Guid();
        public BasicSystemIntegrationServiceClient _serviceClient;
        public List<Instrument> Instruments { get; set; }
        public Dictionary<Guid, Instrument> CurTaskID { get; set; }
        public LabxService()
        {
            _serviceClient = new BasicSystemIntegrationServiceClient();
        }
        public async Task<List<Instrument>> GetInstruments(string instrumentName)
        {
            try
            {
                var instrument = await _serviceClient.GetThisInstrumentsByNameAsync(instrumentName);
                return instrument.ToList();
            }
            catch (Exception ex)
            {
                WeakReferenceMessenger.Default.Send(new ConfirmMessage()
                {
                    Header = $"labx获取设备发生异常\r\n请联系供应商！！",
                    Content = $"{ex.ToString()}",
                    OkButtonContent = "继续",
                    CancelButtonContent = "取消",
                });
                return null;
            }
        }

        public async void CreateNewTask(string methodName, string taskName)
        {
            //Get the method based on method user ID
            Method method = await _serviceClient.GetThisMethodByUserDefinedIdAsync(methodName);
            var taskId = _serviceClient.CreateTaskAsync(
            method.BusinessId, taskName, false, new TaskParameterSet());
        }

        public async Task<TaskResultSet> CreateAndStartNewTaskMove(string methodName, string taskName, int holeNum, Instrument instrument)
        {
            Method method = await _serviceClient.GetThisMethodByUserDefinedIdAsync(methodName);
            var methodparameter = await _serviceClient.GetMethodMetaDataAsync(method.BusinessId);
            TaskParameterSet taskParameterSet = new TaskParameterSet();
            IntegerTypeMethodParameter parameter = new IntegerTypeMethodParameter();
            parameter.MethodFunctionName = methodparameter.MethodParameters[0].MethodFunctionName;
            parameter.MethodFunctionPropertyName = methodparameter.MethodParameters[0].MethodFunctionPropertyName;
            parameter.Value = holeNum;
            taskParameterSet.GlobalMethodParameters = new MethodParameter[1];
            taskParameterSet.GlobalMethodParameters[0] = parameter;

            Guid taskId = await _serviceClient.CreateTaskAsync(method.BusinessId, taskName, false, taskParameterSet);
            await _serviceClient.StartTaskAsync(taskId, instrument.InstrumentId);
            //CurTaskID.Add( taskId, instrument );
            TaskState taskState;
            do
            {
                taskState = await _serviceClient.GetTaskStateAsync(taskId);
                if (taskState.State != TaskStateType.Aborted && taskState.State != TaskStateType.Completed)
                {
                    await Task.Delay(1000);
                }
            } while (taskState.State != TaskStateType.Completed && taskState.State != TaskStateType.Aborted);
            if (taskState.State == TaskStateType.Completed)
            {
                var result = await _serviceClient.GetTaskResultsAsync(taskId);
                //CurTaskID.Remove(taskId);
                //var RE=  result.Samples[0].Results[0].Scalar.ValueMember;
                return result;
            }
            return null;
        }

        /// <summary>
        /// 等待放置加样头
        /// </summary>
        /// <param name="instrument"></param>
        /// <param name="methodName"></param>
        /// <param name="taskName"></param>
        /// <param name="defaultvalue"></param>
        /// <returns></returns>
        public async Task<TaskResultSet> StartWaitingForHead(Instrument instrument, string methodName = "Dosing Head", string taskName = "Dosing Head", decimal defaultvalue = 0)
        {
            try
            {
                Method method = await _serviceClient.GetThisMethodByUserDefinedIdAsync(methodName);
                var methodparameter = await _serviceClient.GetMethodMetaDataAsync(method.BusinessId);

                TaskParameterSet taskParameterSet = new TaskParameterSet
                {
                    GlobalMethodParameters = new MethodParameter[4]
                   {
                        new DecimalTypeMethodParameter{MethodFunctionName = "Number1",MethodFunctionPropertyName = "DefaultValue",Value = defaultvalue},
                        new DecimalTypeMethodParameter{MethodFunctionName = "Dosing1",MethodFunctionPropertyName = "TargetWeight",Value = 5000m},  //单位是mg
                        new DecimalTypeMethodParameter{MethodFunctionName = "Dosing1",MethodFunctionPropertyName = "DosingUpperTolerance",Value = 1m},
                        new DecimalTypeMethodParameter{MethodFunctionName = "Dosing1",MethodFunctionPropertyName = "DosingLowerTolerance",Value = 1m}
                   },
                };

                Guid taskId = await _serviceClient.CreateTaskAsync(method.BusinessId, taskName, false, taskParameterSet);
                abortWaitingHeadTaskId = taskId;
                await _serviceClient.StartTaskAsync(taskId, instrument.InstrumentId);
                TaskState taskState;
                do
                {
                    taskState = await _serviceClient.GetTaskStateAsync(taskId);
                    if (taskState.State != TaskStateType.Running)
                    {
                        await Task.Delay(2000);
                    }
                } while (taskState.State != TaskStateType.Running);

                return null;
            }
            catch (Exception ex)
            {
                WeakReferenceMessenger.Default.Send(new ConfirmMessage()
                {
                    Header = $"梅特勒粉末研磨模块异常",
                    Content = $"{ex.ToString()}",
                    OkButtonContent = "继续",
                    CancelButtonContent = "取消",
                });
                return null;
            }
        }

        /// <summary>
        /// 停止等待加样头
        /// </summary>
        /// <returns></returns>
        public async Task AbortWaitingForHead()
        {
            await _serviceClient.AbortTaskAsync(abortWaitingHeadTaskId);
        }


        /// <summary>
        /// 梅特勒粉末天平模块步骤
        /// </summary>
        /// <param name="instrument"></param>
        /// <param name="methodName"></param>
        /// <param name="taskName"></param>
        /// <param name="defaultvalue"></param>
        /// <param name="targetweight">目标重量，单位mg</param>
        /// <param name="upT"></param>
        /// <param name="dnT"></param>
        /// <returns></returns>
        public async Task<double> MTPowderModuleControlStep(Instrument instrument, string methodName, string taskName, decimal defaultvalue = 0, decimal targetweight = 0, decimal upT = 0, decimal dnT = 0)
        {
            double addResult = 0;
            try
            {

                Method method = await _serviceClient.GetThisMethodByUserDefinedIdAsync(methodName);
                var methodparameter = await _serviceClient.GetMethodMetaDataAsync(method.BusinessId);
                //defaultvalue= 0 关门  =1开门  =2置零  =3去皮  =4 开始加样  =5 粉末头复位
                TaskParameterSet taskParameterSet = new TaskParameterSet
                {
                    GlobalMethodParameters = new MethodParameter[4]
                    {
                        new DecimalTypeMethodParameter{MethodFunctionName = "Number1",MethodFunctionPropertyName = "DefaultValue",Value = defaultvalue},
                        new DecimalTypeMethodParameter{MethodFunctionName = "Dosing1",MethodFunctionPropertyName = "TargetWeight",Value = targetweight},  //单位是mg
                        new DecimalTypeMethodParameter{MethodFunctionName = "Dosing1",MethodFunctionPropertyName = "DosingUpperTolerance",Value = upT},
                        new DecimalTypeMethodParameter{MethodFunctionName = "Dosing1",MethodFunctionPropertyName = "DosingLowerTolerance",Value = dnT}
                    },
                };

                Guid taskId = await _serviceClient.CreateTaskAsync(method.BusinessId, taskName, false, taskParameterSet);
                await _serviceClient.StartTaskAsync(taskId, instrument.InstrumentId);
                TaskState taskState;
                do
                {
                    taskState = await _serviceClient.GetTaskStateAsync(taskId);
                    if (taskState.State != TaskStateType.Aborted && taskState.State != TaskStateType.Completed)
                    {
                        await Task.Delay(2000);
                    }
                } while (taskState.State != TaskStateType.Completed && taskState.State != TaskStateType.Aborted);
                if (defaultvalue == 4 && taskState.State == TaskStateType.Completed)
                {
                    var result = await _serviceClient.GetTaskResultsAsync(taskId);
                    //CurTaskID.Remove(taskId);
                    decimal RE = result.TaskResults[1].Scalar.ValueMember;
                    addResult = (double)RE;
                    return addResult;
                }
                return addResult;

            }
            catch (Exception ex)
            {
                WeakReferenceMessenger.Default.Send(new ConfirmMessage()
                {
                    Header = $"梅特勒粉末研磨模块异常",
                    Content = $"{ex.ToString()}",
                    OkButtonContent = "继续",
                    CancelButtonContent = "取消",
                });
                return addResult;
            }
        }


        /// <summary>
        /// 加粉控制
        /// </summary>
        /// <param name="instrument"></param>
        /// <param name="methodName"></param>
        /// <param name="taskName"></param>
        /// <param name="defaultValue"></param>
        /// <param name="height"></param>
        /// <param name="targetweight"></param>
        /// <param name="upT"></param>
        /// <param name="dnT"></param>
        /// <returns></returns>
        public async Task<double> MTPowderModuleAddPowder(Instrument instrument, string methodName, string taskName, decimal defaultValue, decimal height = 140.8m, decimal targetweight = 0, decimal upT = 0, decimal dnT = 0)
        {
            double addResult = 0;
            try
            {

                Method method = await _serviceClient.GetThisMethodByUserDefinedIdAsync(methodName);
                var methodparameter = await _serviceClient.GetMethodMetaDataAsync(method.BusinessId);
                //defaultvalue= 0 关门  =1开门  =2置零  =3去皮  =4 开始加样  =5 粉末头复位
                TaskParameterSet taskParameterSet = new TaskParameterSet
                {
                    GlobalMethodParameters = new MethodParameter[4]
                    {
                        new DecimalTypeMethodParameter{MethodFunctionName = "Dosingsettings1",MethodFunctionPropertyName = "AbsoluteDosingPositionSpan",Value = height},
                        new DecimalTypeMethodParameter{MethodFunctionName = "Dosing1",MethodFunctionPropertyName = "TargetWeight",Value = targetweight},  //单位是mg
                        new DecimalTypeMethodParameter{MethodFunctionName = "Dosing1",MethodFunctionPropertyName = "DosingUpperTolerance",Value = upT},
                        new DecimalTypeMethodParameter{MethodFunctionName = "Dosing1",MethodFunctionPropertyName = "DosingLowerTolerance",Value = dnT}
                    },
                };

                Guid taskId = await _serviceClient.CreateTaskAsync(method.BusinessId, taskName, false, taskParameterSet);
                await _serviceClient.StartTaskAsync(taskId, instrument.InstrumentId);
                TaskState taskState;
                do
                {
                    taskState = await _serviceClient.GetTaskStateAsync(taskId);
                    if (taskState.State != TaskStateType.Aborted && taskState.State != TaskStateType.Completed)
                    {
                        await Task.Delay(2000);
                    }
                } while (taskState.State != TaskStateType.Completed && taskState.State != TaskStateType.Aborted);
                if (defaultValue == 4 && taskState.State == TaskStateType.Completed)
                {
                    var result = await _serviceClient.GetTaskResultsAsync(taskId);
                    try
                    {
                        //CurTaskID.Remove(taskId);
                        decimal RE = result.TaskResults[0].Scalar.ValueMember;
                        addResult = (double)RE;
                    }
                    catch (Exception ex)
                    {
                        //MessageBox.Show($"加粉异常-{ex.Message}");
                        addResult = 0;
                    }
                    
                    return addResult;
                }
                return addResult;

            }
            catch (Exception ex)
            {
                WeakReferenceMessenger.Default.Send(new ConfirmMessage()
                {
                    Header = $"梅特勒粉末研磨模块异常",
                    Content = $"{ex.ToString()}",
                    OkButtonContent = "继续",
                    CancelButtonContent = "取消",
                });
                return addResult;
            }
        }
    }
}