using Microsoft.Extensions.Logging;
using SlnMesnac.Repository.service;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using SlnMesnac.Repository;
using SlnMesnac.Repository.service.Impl;
using TouchSocket.Sockets;
using SlnMesnac.Model.domain;
using SlnMesnac.TouchSocket;
using System.Timers;
using SlnMesnac.Model.Enum;
using HslCommunication.Enthernet;
using System.Threading;

namespace SlnMesnac.Business.@base
{
    public class BaseTaskInfoBusiness
    {
        private TcpServer _tcpServer = null;
        public Action<AirportTask> _Taskaction;
        public Action<string> _RefreshLogMessageAction;
        private static BaseTaskInfoBusiness instance;
        private ILogger<BaseTaskInfoBusiness> _logger;
        private IAirportTaskService _Taskservice;
        private IAGVStateService _AGVStateService;
        public BaseTaskInfoBusiness(ILogger<BaseTaskInfoBusiness> logger, IAirportTaskService Taskservice, IAGVStateService agvService, TcpServer tcpServer)
        {
            _logger = logger;
            _tcpServer = tcpServer;
            _Taskservice = Taskservice;
            _AGVStateService = agvService;
            InitClearTimer();
            //doWhileGetAGVTaskInfo();
        }
        public static BaseTaskInfoBusiness GetInstance(ILogger<BaseTaskInfoBusiness> logger, IAirportTaskService Taskservice, IAGVStateService agvService, TcpServer tcpServer)
        {
            if (instance == null)
            {
                instance = new BaseTaskInfoBusiness(logger, Taskservice,agvService, tcpServer);
            }
            return instance;
        }

        private void doWhileGetAGVTaskInfo()
        {
            try
            {
                Task.Run((() =>
                {
                    while (true)
                    {
                        GetAGVTaskInfo(null,null);
                        Task.Delay(1000);
                    }


                }));

            }
            catch (Exception ex)
            {

            }
        }
        private void InitClearTimer()
        {
            System.Timers.Timer timer = new System.Timers.Timer
            {
                Interval = 1000, // 每天执行一次
                AutoReset = true,
                
            };
            timer.Elapsed += GetAGVTaskInfo;
            timer.Start();

        }
        /// <summary>
        /// 获取任务列表
        /// </summary>
        private void GetAGVTaskInfo(object source, ElapsedEventArgs e)
        {
            try
            {
                List<AirportTask> Task = _Taskservice.GetAGVTaskInfos();
                if (Task != null)
                {
                    if (Task.Count > 0)
                    {
                        _RefreshLogMessageAction?.Invoke("任务数量:" + Task.Count);
                        foreach (var TaskItem in Task)
                        {
                            //AGV未派发，AMR未派发
                            if (string.IsNullOrEmpty(TaskItem.agvno) && string.IsNullOrEmpty(TaskItem.manipulatorno))
                            {
                                _RefreshLogMessageAction?.Invoke($"正在为AGV，AMR分配任务...");
                                _logger.LogInformation($"正在为AGV，AMR分配任务");
                                //查询AGV设备状态及AMR设备状态
                                //这里要看AGV是否会立刻更新状态
                                CreateAGVTask(TaskItem);
                                //查询机械臂状态
                            }
                            //AGV已派发，AMR未派发
                            if (!string.IsNullOrEmpty(TaskItem.agvno) && string.IsNullOrEmpty(TaskItem.manipulatorno))
                            {
                                //查询AMR状态
                                CreateAMRTask(TaskItem);
                                _RefreshLogMessageAction?.Invoke($"正在为AMR分配任务...");

                                _logger.LogInformation($"正在为AMR分配任务");
                            }
                            //AGV未派发，AMR已派发
                            if (string.IsNullOrEmpty(TaskItem.agvno) && !string.IsNullOrEmpty(TaskItem.manipulatorno))
                            {
                                _RefreshLogMessageAction?.Invoke($"正在为AGV分配任务...");

                                _logger.LogInformation($"正在为AGV分配任务");

                            }
                            _Taskaction?.Invoke(TaskItem);

                        }

                    }
                }
              



            }
            catch (Exception ex)
            {

            }
        }
        /// <summary>
        /// 向AMR派发任务
        /// </summary>
        /// <param name="AirportTask"></param>
        /// <returns></returns>
        private bool CreateAMRTask(AirportTask AirportTask)
        {
            bool iflag = false;
            try
            {
                iflag = true;
                List<AGVState> State = GetAgvState(AgvType.AMR);
                foreach (var AgvItem in State)
                {
                    //根据规则筛选最优AGV
                    if (AgvItem.agvworkstate == "任务空闲")
                    {
                        _logger.LogInformation($"获取空闲AMR列表");
                        _RefreshLogMessageAction?.Invoke("执行站台[" + AirportTask.conveyorno + "]，下发" + "[" + AirportTask.taskno + "]任务");
                        //调用派发任务接口,向任务状态为任务空闲的AGV派发任务
                        bool iTaskflag = true;
                        if (iTaskflag)
                        {
                            _RefreshLogMessageAction?.Invoke("[" + AgvItem.agvno + "]AMR，执行任务[" + AirportTask.taskno + "]");
                            AgvItem.taskno = AirportTask.taskno;
                            AgvItem.agvworkstate = "任务执行中";
                            AgvItem.refreshtime = DateTime.Now;
                            _AGVStateService.UpdateAsync(AgvItem);

                            //更新任务信息表状态为执行中
                            AirportTask.manipulatorno = AgvItem.agvno;
                            AirportTask.taskstate = "执行中";
                            _Taskservice.UpdateTaskAsync(AirportTask);
                            break;
                        }
                    }
                }
                return iflag;
            }
            catch (Exception ex)
            {
                return iflag;
            }
        }

        /// <summary>
        /// 向AGV派发任务
        /// </summary>
        /// <returns></returns>
        private bool CreateAGVTask(AirportTask AirportTask)
        {
            bool iflag = false;
            try
            {
                iflag = true;
                List<AGVState> State = GetAgvState(AgvType.AGV);
                foreach (var AgvItem in State)
                {
                    //根据规则筛选最优AGV
                    if (AgvItem.agvworkstate == "任务空闲")
                    {
                        _logger.LogInformation($"获取空闲AGV列表");
                        _RefreshLogMessageAction?.Invoke("执行站台[" + AirportTask.conveyorno + "]，下发" + "[" + AirportTask.taskno + "]任务");
                        //调用派发任务接口,向任务状态为任务空闲的AGV派发任务
                        bool iTaskflag = true;
                        if (iTaskflag)
                        {
                            _RefreshLogMessageAction?.Invoke("[" + AgvItem.agvno + "]AGV，执行任务[" + AirportTask.taskno + "]");
                            AgvItem.taskno = AirportTask.taskno;
                            AgvItem.agvworkstate = "任务执行中";
                            AgvItem.refreshtime = DateTime.Now;
                            _AGVStateService.UpdateAsync(AgvItem);

                            //更新任务信息表状态为执行中
                            AirportTask.agvno = AgvItem.agvno;
                            AirportTask.taskstate = "执行中";
                            _Taskservice.UpdateTaskAsync(AirportTask);
                            break;
                        }
                    }
                }
                return iflag;
            }
            catch (Exception ex)
            {
                return iflag;
            }
        }
        /// <summary>
        /// 获取agv设备状态
        /// </summary>
        /// <returns></returns>
        private List<AGVState> GetAgvState(AgvType AgvType)
        {
            List<AGVState> State = null;
            try
            {
                State = _AGVStateService.GetAgvState(AgvType);
                return State;
            }
            catch (Exception ex)
            {
                return State;
            }

        }


    }
}