using BPASmartClient.DRCoffee;
using BPASmartClient.EventBus;
using BPASmartClient.Helper;
using BPASmartClient.Message;
using BPASmartClient.Model;
using BPASmartClient.Model.咖啡机.Enum;
using BPASmartClient.Peripheral;
using BPASmartClient.SerialPort;
using System;
using System.Collections.Generic;
using System.Threading;
using static BPASmartClient.EventBus.EventBus;

namespace BPASmartClient.DRCoffee
{
    /// <summary>
    /// 咖啡机
    /// </summary>
    public class CoffeeMachine :BasePeripheral
    {
        //通讯代理
        SerialPortClient commProxy = null;
        //数据仓库
        private DataStorage<byte> dataStorage = new DataStorage<byte>();
        //是否下发指令，主线程等待
        private bool free = false;
        //状态询问指令
        private byte[] cmdAsk;
        //Dr咖啡机基础协议
        private DrCoffeePackage drinksOrder = new DrCoffeePackage();
        //串口COM口
        public string PortName { get; set; }
        //串口波特率
        public string BaudRate { get; set; }
        //心跳时间
        private DateTime lastRefreshTime = DateTime.MinValue;
        /// <summary>
        /// 是否在线
        /// </summary>
        public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } }

        //private volatile static CoffeeMachine _Instance;
        //public static CoffeeMachine GetInstance => _Instance ?? (_Instance = new CoffeeMachine());
        public CoffeeMachine()
        {
            DrCoffeePackage package = new DrCoffeePackage();
            package.CommCmd = DrCoffeeCommCmd.饮品制作指令;
            cmdAsk = DrCoffee.Packe(package);
        }

        /// <summary>
        /// 主线程开始运行
        /// </summary>
        public override void Start()
        {
            try
            {
                commProxy.Start();
                IsConnected = true;
                free = false;
                MainLoop();
            }
            catch (Exception ex)
            {
                MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述：[{ex.Message}]");
            }
        }

        /// <summary>
        /// 停止运行
        /// </summary>
        public override void Stop()
        {
            try
            {
                commProxy.Stop();
                IsConnected = false;
                free = true;
            }
            catch (Exception ex)
            {
                MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述：[{ex.Message}]");
            }
        }

        /// <summary>
        /// 主循环，循环询问状态
        /// </summary>
        private void MainLoop()
        {
            ThreadManage.GetInstance().StartLong(new Action(() =>
            {
                if (!free)
                {
                    commProxy.SendData(cmdAsk);
                }
                Thread.Sleep(200);
            }),"咖啡机询问线程");

            ThreadManage.GetInstance().StartLong(new Action(() =>
            {
                List<byte> temp = new List<byte>();
                //一系列解包
                while (dataStorage.GetSize() > 0)
                {
                    
                    byte item = dataStorage.GetData();
                    if (DrCoffee.HEADER == item)
                    {
                        if (temp.Count == DrCoffee.LENGTH - 1)
                        {
                            temp.Add(item);
                            var package = DrCoffee.UnPack(temp.ToArray());
                            temp.Clear();
                            ProcessPackage(package);
                        }
                        else
                        {
                            temp.Clear();
                            temp.Add(item);
                        }
                        continue;
                    }
                    else
                    {
                        if (temp.Count == 1 && item != DrCoffee.LENGTH)
                        {
                            temp.Clear();
                            continue;
                        }
                        temp.Add(item);
                    }
                }
                Thread.Sleep(5);
            }),"咖啡机解析线程");
        }

        /// <summary>
        /// 咖啡机状态解析
        /// </summary>
        /// <param name="package"></param>
        public void ProcessPackage(DrCoffeePackage package)
        {
            
            if (((DrCoffeeStatus)status["Status"]) == DrCoffeeStatus.Running && package.Status != DrCoffeeStatus.Running)
            {
                status["Status"] = package.Status;
                
                lastRefreshTime = DateTime.Now;
                new DRCoffee_CoffeEndCookEvent() { DeviceId = DeviceId }.Publish();
            }
            else status["Status"] = package.Status;
            status["AppStatus"] = package.ApplicationStatus;
            status["Warning"] = package.Warning;
            status["Fault"] = package.Fault;
            
            if ((DrCoffeeStatus)status["Status"] == DrCoffeeStatus.Warning
                || (DrCoffeeStatus)status["Status"] == DrCoffeeStatus.Fault
                || (DrCoffeeWarning)status["Warning"] != DrCoffeeWarning.无警告
                || (DrCoffeeFault)status["Fault"] != DrCoffeeFault.无故障
                )
            {
                IsWork = false;
                
            }
            else
                IsWork = true; 
        }

        protected override void InitStatus()
        {
            status["Status"] = DrCoffeeStatus.Wait;
            status["AppStatus"] = DrCoffeeAppStatus.应用无状态;
            status["Warning"] = DrCoffeeWarning.无警告;
            status["Fault"] = DrCoffeeFault.无故障;
        }

        public override void Init()
        {
            commProxy = new SerialPortClient(PortName,(BaudRates)Enum.Parse(typeof(BaudRates),BaudRate));
            commProxy.SetDataStorage(dataStorage);

            //咖博士咖啡机制作
            EventBus.EventBus.GetInstance().Subscribe<DRCoffee_MakeCoffeeEvent>(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack)
            {
                try
                {
                    free = true;
                    Thread.Sleep(200);
                    drinksOrder.CommCmd = DrCoffeeCommCmd.饮品制作指令;
                    drinksOrder.DrinksCode = ((DRCoffee_MakeCoffeeEvent)@event).DrinkCode;
                    commProxy.SendData(DrCoffee.Packe(drinksOrder));
                    Thread.Sleep(200);
                    free = false;
                }
                catch (Exception ex)
                {
                    MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述：[{ex.Message}]");
                }
            });

            //咖博士咖啡机取消制作咖啡
            EventBus.EventBus.GetInstance().Subscribe<DRCoffee_CancelMakeCoffeeEvent>(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack)
            {
                try
                {
                    free = true;
                    Thread.Sleep(200);
                    drinksOrder.CommCmd = DrCoffeeCommCmd.取消应用指令;
                    drinksOrder.DrinksCode = 0;
                    commProxy.SendData(DrCoffee.Packe(drinksOrder));
                    Thread.Sleep(200);
                    free = false;
                }
                catch (Exception ex)
                {
                    MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述：[{ex.Message}]");
                }
            });

            //咖博士咖啡机模式设置
            EventBus.EventBus.GetInstance().Subscribe<DRCoffee_CoffeeCommCmdEvent>(DeviceId,delegate (IEvent @event,EventCallBackHandle callBack)
            {
                try
                {
                    free = true;
                    Thread.Sleep(200);
                    drinksOrder.CommCmd = ((DRCoffee_CoffeeCommCmdEvent)@event).CommCmd;
                    commProxy.SendData(DrCoffee.Packe(drinksOrder));
                    Thread.Sleep(200);
                    free = false;
                }
                catch (Exception ex)
                {
                    MessageLog.GetInstance.ShowEx($"BPASmartClient.DRCoffee 中引发错误,CoffeeMachine 类,描述：[{ex.Message}]");
                }
            });
            InitStatus();
            //测试
            Start();
        }

    }
}
