using CommunityToolkit.Mvvm.Messaging;
using MegaRobo.C00225155.Entities;
using MegaRobo.C00225155.Entities.Entity_DB;
using MegaRobo.Contract;
using MegaRobo.ControlDevices;
using MegaRobo.Entities;
using MegaRobo.Logger;
using MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.Hamilton5mlDevices;
using MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml.Linq;

namespace MegaRobo.C00225155.AppServer.ExecuteWorks
{
    /// <summary>
    /// 这里主要是针对配置站服务，控制1ml移液枪的逻辑
    /// </summary>
    public partial class StationService_ReactionProcessing : StationServiceBase
    {
        /// <summary>
        /// 1ml枪头 Z轴初始化
        /// </summary>
        /// <returns></returns>
        private async Task GunZAxisInit_M1()
        {
            this.Logger.LogInformation($"{DeviceNames.Pipette_React_1ml}Z轴初始化");

            //莫名其妙的每次初始化都需要重新连接一次，不知道为什么
            pipetteService_1ml.Disconnect();
            await pipetteService_1ml.ConnectionAsync();

            var dictResult = await pipetteService_1ml.InitZaxis();
            if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
            {
                string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
                this.Logger.LogError($"{DeviceNames.Pipette_React_1ml}Z轴初始化失败,{PipetteErrorDic[errorkey]}");
            }

        }

        /// <summary>
        /// 1ml枪头 总初始化
        /// </summary>
        /// <returns></returns>
        private async Task GunAllInit_M1()
        {
            this.Logger.LogInformation($"{DeviceNames.Pipette_React_1ml}总初始化");
            var dictResult = await pipetteService_1ml.InitZaxis();
            if (dictResult != null)
            {
                dictResult = await pipetteService_1ml.InitPump();
            }
            if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
            {
                string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
                this.Logger.LogError($"{DeviceNames.Pipette_React_1ml}总初始化失败,{PipetteErrorDic[errorkey]}");
            }
        }

        /// <summary>
        /// 1ml枪头 取TIP头
        /// </summary>
        /// <returns></returns>
        private async Task<bool> GunPickUpTip_M1(double tipVolumn)
        {
            ushort tipType = 7;
            if (tipVolumn == 300)//300ul slim的有滤芯的、导电的枪头
            {
                tipType = 9;  
            }
            else if (tipVolumn == 50) //50ul的有滤芯的、导电的枪头
            {
                tipType = 3;
            }
            else    
            {
                tipType = 7;//1000ul的有滤芯的、导电的枪头
            }
            this.Logger.LogInformation($"{DeviceNames.Pipette_React_1ml}取Tip");
            var dictResult = await pipetteService_1ml.TipInstall(tipType: tipType);
            await pipetteService_1ml.InitZaxis(); //Z轴带动泵模块向上运动到最高处 
            if (dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00") || dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "76"))
            {
                this.Logger.LogInformation($"{DeviceNames.Pipette_React_1ml}取Tip成功");
                return true;
            }
            else if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
            {
                string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
                WeakReferenceMessenger.Default.Send(new ConfirmMessage()
                {
                    Header = $"{DeviceNames.Pipette_React_1ml}取Tip失败",
                    Content = $"{PipetteErrorDic[errorkey]}",
                    OkButtonContent = "继续",
                    CancelButtonContent = "取消",
                });
                this.Logger.LogError($"{DeviceNames.Pipette_React_1ml}取Tip失败,{PipetteErrorDic[errorkey]}");
                await GunAllInit_M1();
                return false;
            }
            return false;
        }

        public async Task ZMove(uint pos)
        {
            IEnumerable<uint> pipetteIdList = new List<uint> { 1 };
            pipetteIdList = pipetteService_1ml.PipetteList.Select(x => x.Id);
            foreach (var id in pipetteIdList)
            {
                var dictRes = await pipetteService_1ml.MoveZaxis(0, id);
            }
        }

        /// <summary>
        /// 1ml枪头  丢弃Tip头
        /// </summary>
        /// <returns></returns>
        private async Task GunDiscardTip_M1()
        {
            this.Logger.LogInformation($"{DeviceNames.Pipette_React_1ml}丢Tip");
            //var dictResult = await pipetteService_1ml.TipUninstall(1);
            //await pipetteService_1ml.InitZaxis();
            //if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
            //{
            //    this.Logger.LogError($"{DeviceNames.Pipette_Config_1ml}丢Tip失败,{dictResult.LastOrDefault().Value}");
            //}
            var dictResult = await pipetteService_1ml.InitPump();
            await pipetteService_1ml.InitZaxis();
            if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
            {
                string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
                WeakReferenceMessenger.Default.Send(new ConfirmMessage()
                {
                    Header = $"{DeviceNames.Pipette_React_1ml}丢Tip失败",
                    Content = $"{PipetteErrorDic[errorkey]}",
                    OkButtonContent = "继续",
                    CancelButtonContent = "取消",
                });
                this.Logger.LogError($"{DeviceNames.Pipette_React_1ml}丢Tip失败,{PipetteErrorDic[errorkey]}");
                await GunAllInit_M1();
            }
        }

        private async Task GunAbsorb_M1(string funcType, string liquidName, int tiporder, double absorbVolumn)
        {
            IList<uint> listId = new List<uint>() { 1 };
            var curLiqud = await this.dataAccessService.LoadEntitiesAsync<Liquid_lml_React>(x => x.FuncType == funcType && x.LiquidName == liquidName && (x.TipType == tiporder));
            var curLiqud_M1 = curLiqud.FirstOrDefault();
            curLiqud_M1.LiquidVolume = (int)Math.Abs(absorbVolumn * curLiqud_M1.Ratio);
            //for (int i = 1; i < 3; i++) //若吸液失败，二次吸液
            {
                this.Logger.LogInformation($"{DeviceNames.Pipette_React_1ml}开始吸液,吸液量{curLiqud_M1.LiquidVolume}ul");
                var dictResult = await OnSuckFluid(pipetteService_1ml, listId, curLiqud_M1, 1, 1);
                if (dictResult != null)
                {
                    if (dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
                    {
                        this.Logger.LogInformation($"{DeviceNames.Pipette_React_1ml}吸液成功");
                        await pipetteService_1ml.InitZaxis();
                    }
                    else
                    {
                        string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
                        this.Logger.LogError($"{DeviceNames.Pipette_React_1ml}吸液失败,{PipetteErrorDic[errorkey]}");
                        WeakReferenceMessenger.Default.Send(new ConfirmMessage()
                        {
                            Header = $"{DeviceNames.Pipette_React_1ml}吸液失败",
                            Content = $"{PipetteErrorDic[errorkey]}",
                            OkButtonContent = "继续",
                            CancelButtonContent = "取消",
                        });
                        await pipetteService_1ml.InitZaxis();
                    }
                }
                else
                {
                    await pipetteService_1ml.InitZaxis();
                }
            }
        }

        /// <summary>
        /// 1ml枪头 分液
        /// </summary>
        /// <param name="liquidName">液体名称</param>
        /// <param name="volumn">分液体积</param>
        /// <returns></returns>
        private async Task GunDispensing_M1(string funcType, string liquidName, int tipOrder, double volumn)
        {
            Liquid_lml_React curLiqud_M1 = new Liquid_lml_React();
            IList<uint> listId = new List<uint>() { 1 };
            this.Logger.LogInformation($"{DeviceNames.Pipette_React_1ml}开始分液,分液量{volumn}ul");
            var curLiqud = await this.dataAccessService.LoadEntitiesAsync<Liquid_lml_React>(x => x.FuncType == funcType && x.LiquidName == liquidName && (x.TipType == tipOrder));
            curLiqud_M1 = curLiqud.FirstOrDefault();
            var dictResult = await OnDispenFluid(pipetteService_1ml, listId, curLiqud_M1, 100);//(uint)Math.Abs(volumn)
            if (!dictResult.All(x => this.GetPipetteReturnCode(x.Value) == "00"))
            {
                string errorkey = this.GetPipetteReturnCode(dictResult.LastOrDefault().Value);
                this.Logger.LogError($"{DeviceNames.Pipette_React_1ml}分液失败,{PipetteErrorDic[errorkey]}");
                WeakReferenceMessenger.Default.Send(new ConfirmMessage()
                {
                    Header = $"{DeviceNames.Pipette_React_1ml}分液失败",
                    Content = $"{PipetteErrorDic[errorkey]}",
                    OkButtonContent = "继续",
                    CancelButtonContent = "取消",
                });
                await pipetteService_1ml.InitZaxis();
            }
            else
            {
                this.Logger.LogInformation($"{DeviceNames.Pipette_React_1ml}分液成功");
                await pipetteService_1ml.InitZaxis();
            }
        }

        private async Task<IDictionary<uint, string>> OnSuckFluid(PipetteService pipetteService, IList<uint> listId, Liquid_lml_React liquidProduct, int subid, int asperIndex = 1)
        {
            IDictionary<uint, string> resultData;
            try
            {
                if (liquidProduct == null) return null;
                uint platformCode = (uint)liquidProduct.PlatformCode;//平台平台编号
                uint liquidReagentCode = (uint)liquidProduct.LiquidParamId; //移液枪液体编号
                uint vol = (uint)liquidProduct.LiquidVolume;//吸液体积
                uint ge = (uint)liquidProduct.ContainerPlateIndex;//容器编号
                uint lld = (uint)liquidProduct.LiqLedetec;//是否液面探测
                uint pos = (uint)liquidProduct.AspireHeight;
                IList<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)> idArrayParams = new List<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)>();
                foreach (var id in listId)
                {
                    idArrayParams.Add((id, vol, liquidReagentCode, pos, ge, platformCode, lld));
                }
                resultData = await pipetteService.SuckFluid(idArrayParams);
            }
            catch (Exception ex)
            {
                this.Logger.LogError($"{DeviceNames.Pipette_React_1ml}吸液异常:{ex}");
                throw;
            }
            return resultData;
        }

        private async Task<IDictionary<uint, string>> OnDispenFluid1(PipetteService pipetteService, IList<uint> listId, Liquid_lml_React liquidProduct, uint dispos)
        {
            IDictionary<uint, string> resultData = new Dictionary<uint, string>();
            try
            {
                if (liquidProduct == null) return null;
                uint platformCode = (uint)liquidProduct.PlatformCode;//平台平台编号
                uint liquidReagentCode = (uint)liquidProduct.LiquidParamId; //移液枪液体编号
                uint vol = (uint)liquidProduct.LiquidVolume;//吸液体积
                uint ge = (uint)liquidProduct.ContainerPlateIndex;//容器编号
                uint lld = (uint)liquidProduct.LiqLedetec;//是否液面探测
                uint pos = dispos;//吸液高度
                IList<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)> idArrayParams = new List<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)>();
                foreach (var id in listId)
                {
                    idArrayParams.Add((id, vol, liquidReagentCode, pos, ge, platformCode, 0));
                }
                resultData = await pipetteService.DrainageFluid(idArrayParams);
            }
            catch (Exception ex)
            {
                this.Logger.LogError($"{DeviceNames.Pipette_React_1ml}分液异常,异常原因:{ex}");
            }
            return resultData;
        }


        private async Task<IDictionary<uint, string>> OnDispenFluid(PipetteService pipetteService, IList<uint> listId, Liquid_lml_React liquidProduct, uint volume)
        {
            IDictionary<uint, string> resultData = new Dictionary<uint, string>();
            try
            {
                if (liquidProduct == null) return null;
                uint platformCode = (uint)liquidProduct.PlatformCode;//平台平台编号
                uint liquidReagentCode = (uint)liquidProduct.LiquidParamId;//移液枪液体编号
                uint ge = (uint)liquidProduct.ContainerPlateIndex;//容器编号
                uint lld = (uint)liquidProduct.LiqLedetec;//是否液面探测
                uint pos = (uint)liquidProduct.DispenHeight;//分液高度
                uint vol = volume;
                IList<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)> idArrayParams = new List<(uint id, uint vol, uint lq, uint pos, uint ge, uint go, uint lb)>();
                foreach (var id in listId)
                {
                    idArrayParams.Add((id, vol, liquidReagentCode, pos, ge, platformCode, 0));
                }
                resultData = await pipetteService.DrainageFluid(idArrayParams);
            }
            catch (Exception ex)
            {
                this.Logger.LogError($"{DeviceNames.Pipette_React_1ml}分液异常,异常原因:{ex.ToString()}");
            }
            return resultData;
        }

    }
}
