using DbCommon.BusinessCore.BaseCore;
using DbCommon.Enties.DbModels;
using ProjectManagementSystem.Device.CasunBox;
using ProjectManagementSystem.Common.Config;
using ProjectManagementSystem.Common.Log;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ProjectManagementSystem.Common.Core
{
    public class BoxControl
    {
        private IBoxCommunication communication;

        private LocationPropertyManager m_locationManager = new LocationPropertyManager();
        private ConcurrentQueue<InfoBox> m_infoBoxesQueue = new ConcurrentQueue<InfoBox>();

        public IBoxCommunication Communication { get { return communication; } }

        public BoxControl(IBoxCommunication boxCommunication)
        {
            communication = boxCommunication;
            communication.OnLogMsg += Communication_OnLoging;
            communication.OnInfoBox += Communication_OnInfoBox;
            communication.Start();

            if(communication.IsStart)
            {
                Task.Factory.StartNew(UserThread);
            }
        }

        public void BoxLightOff(int route)
        {
            CommandButtonOff data = new CommandButtonOff();
            data.Route = route;
            communication.CommandEnqueue(data);
        }
        public void BoxQuery(int route)
        {
            CommandQuery data = new CommandQuery();
            data.Route = route;
            communication.CommandEnqueue(data);
        }
        public void BoxSetLight(int lightNumber, int lightType)
        {
            CommandSetLight data = new CommandSetLight();
            data.LightType = (byte)lightType;
            data.Route = lightNumber;
            communication.CommandEnqueue(data);
        }

        private void Communication_OnInfoBox(InfoBox infoBox)
        {
            m_infoBoxesQueue.Enqueue(infoBox);
        }

        private void Communication_OnLoging(string obj, Exception ex)
        {
            if (ex == null)
            {
                CLog.Instance.GetLog("System").WriteDebug(obj);
            }
            else
            {
                CLog.Instance.GetLog("System").WriteException("Exception", obj, ex);
            }
        }

        public void RouteProc()
        {
            while (m_infoBoxesQueue.TryDequeue(out InfoBox infoBox))
            {
                if(infoBox.EBoxDevice != EnumBoxDevice.CallBox) 
                {
                    continue;
                }

                if(!infoBox.Called
                    && !infoBox.CancelCall)
                {
                    continue;
                }

                string infoCall = infoBox.Called ? "叫料" : "叫料取消";
                CLog.Instance.GetLog("System").WriteInfo($"线路{infoBox.Route} {infoCall}");

                int route = infoBox.Route;
                var routeConfig = ExcelConfig.Instance.GetRouteConfig(route);
                if (routeConfig != null
                    && !string.IsNullOrEmpty(routeConfig.LocationCode))
                {
                    string location = routeConfig.LocationCode;
                    LocationStatus status = infoBox.Called ?
                        (LocationStatus)routeConfig.CallLineStauts : (LocationStatus)routeConfig.CancelLineStauts;
                    bool result = true;

                    if (location.Contains(","))
                    {
                        string[] loacations = location.Split(new char[] { ',' });

                        for (int i = 0; i < loacations.Length; i++)
                        {
                            result &= m_locationManager.UpdateStatusNotLocked(loacations[i], status);
                        }
                    }
                    else
                    {
                        result = m_locationManager.UpdateStatusNotLocked(location, status);
                    }

                    if(result)
                    {
                        CLog.Instance.GetLog("System").WriteInfo($"更新库位状态成功：{location}：{status}");
                    }
                }
            }
        }

        private void UserThread()
        {
            byte conter = 0;
            while (true)
            {
                try
                {
                    //if(conter == 0)
                    //{
                    //    BoxQuery(0);
                    //}
                    RouteProc();
                }
                catch (Exception ex)
                {
                    CLog.Instance.GetLog("System").WriteException("Exception", ex);
                    Thread.Sleep(5000);
                }

                conter++;
                Thread.Sleep(100);
            }
        }
    }
}
