using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WCS.BLL.DbModels;
using WCS.BLL.Tool;
using WCS.DAL.Db;
using WCS.DAL.DbModels;
using WCS.Model;
using WCS.Model.ApiModel.AGV;
using WCS.Model.ApiModel.InOutRecord;
using WCS.Model.ApiModel.MXBackgroundThread;

namespace WCS.BLL.Manager
{
    //AGV动作相关
    public static class AGVManager
    {
        public static void InitBackgroundThread()
        {
            #region 定时任务:定时查询任务状态
            Task.Run(() =>
            {
                while (true)
                {
                    //每5秒同步一次
                    Thread.Sleep(3000);
                    try
                    {
                        var url = @"http://192.168.18.150:8181/rcms/services/rest/hikRpcService/queryTaskStatus";

                        var tasks = DbHelp.db.Queryable<AgvTask>()
                                                        .Where(t => t.CreateTime > DateTime.Now.AddDays(-7)) //只查询7天内agv任务数据
                                                        .Where(t => t.TaskStatus != TaskStatusEnum.取消完成 && t.TaskStatus != TaskStatusEnum.已结束)
                                                        .OrderBy(t => t.Id)
                                                        .ToList();
                        if (tasks != null && tasks.Count > 0)
                        {
                            for (int i = 0; i < tasks.Count; i++)
                            {
                                try
                                {
                                    //请求RCS获取任务状态
                                    var data = new AGVQueryTaskStatusRequest();
                                    data.taskCodes.Add(tasks[i].TaskCode);

                                    var result = ApiHelp.GetDataFromHttp<AGVQueryTaskStatusResponse>(url, data, "POST", true);
                                    if (result != null && result.code == "0" && result.data != null && result.data.Count > 0)
                                    {
                                        var isUpdate = false;
                                        //获取成功 是否与当前任务状态一致 如果不一致 进行更新
                                        var responseData = result.data.First();
                                        if (responseData.agvCode != tasks[i].AgvCode)
                                        {
                                            isUpdate = true;
                                            tasks[i].AgvCode = responseData.agvCode;
                                        }
                                        if (responseData.taskStatus != tasks[i].TaskStatus.ToString())
                                        {
                                            Enum.TryParse<TaskStatusEnum>(responseData.taskStatus, out TaskStatusEnum status);
                                            isUpdate = true;
                                            tasks[i].TaskStatus = status;

                                            //取消任务时 货架数据需要更新
                                            if (status == TaskStatusEnum.取消完成)
                                            {
                                                var shelf = DbHelp.db.Queryable<ShelfInfo>()
                                                                     .Where(t => t.ShelfCode == tasks[i].ShelfCode)
                                                                     .Where(t => t.CurrentTaskCode == tasks[i].TaskCode)
                                                                     .Where(t => t.DestinationLocationId == tasks[i].EndLocationId)
                                                                     .First();
                                                if (shelf != null)
                                                {
                                                    shelf.DestinationLocationId = 0;
                                                    shelf.DestinationLocaiotnCode = string.Empty;
                                                    shelf.TransStatus = TransStatusEnum.静止;
                                                    shelf.CurrentTaskCode = string.Empty;
                                                    DbHelp.db.Updateable(shelf).ExecuteCommand();
                                                }
                                            }

                                        }
                                        if (isUpdate)
                                        {
                                            tasks[i].ModifyTime = DateTime.Now;
                                            if (tasks[i].TaskStatus != TaskStatusEnum.已创建 && tasks[i].TaskStatus != TaskStatusEnum.正在执行 )
                                            {
                                                tasks[i].AgvStatus = "-";
                                            }
                                            DbHelp.db.Updateable(tasks[i]).ExecuteCommand();
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Logs.Write("【定时任务】获取任务状态异常：" + ex.Message);
                                }
                                Thread.Sleep(50);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logs.Write("【定时任务】获取任务状态异常：" + ex.Message);
                    }
                }
            });
            #endregion
        }

        public static object lockFlag = new object();
        /// <summary>
        /// 产生AGV点到点搬运任务
        /// </summary>
        public static AGVResponseModel GenAgvSchedulingTask(LocationInfo startLocation, LocationInfo endLocation, string shelfCode, string createUser)
        {
            var url = @"http://192.168.18.150:8181/rcms/services/rest/hikRpcService/genAgvSchedulingTask";
            var startPositionCodePathItem = new PositionCodePathItem()
            {
                positionCode = startLocation.RcsStoreCode,
            };
            var endPositionCodePathItem = new PositionCodePathItem()
            {
                positionCode = endLocation.RcsStoreCode,
            };
            List<PositionCodePathItem> positionCodePathItems = new List<PositionCodePathItem>();

            positionCodePathItems.Add(startPositionCodePathItem);
            positionCodePathItems.Add((endPositionCodePathItem));

            //任务只允许一个一个发送
            lock (lockFlag)
            {
                //正在执行中的任务
                var tasks = DbHelp.db.Queryable<AgvTask>()
                                     .Where(t => t.TaskStatus == TaskStatusEnum.已创建 || t.TaskStatus == TaskStatusEnum.正在执行)
                                     .ToList();
                //校验货架
                if (tasks.Where(t => t.ShelfCode == shelfCode).Any())
                {
                    return new AGVResponseModel()
                    {
                        code = "-999",
                        message = $"货架[{shelfCode}]已有执行中的任务!",
                    };
                }
                //校验起点
                if (tasks.Where(t => t.StratLocationId == startLocation.Id).Any())
                {
                    return new AGVResponseModel()
                    {
                        code = "-999",
                        message = $"工位[{startLocation.LocationCode}]作为起点已有执行中的任务!",
                    };
                }
                //校验终点
                if (tasks.Where(t => t.EndLocationId == endLocation.Id).Any())
                {
                    return new AGVResponseModel()
                    {
                        code = "-999",
                        message = $"工位[{endLocation.LocationCode}]作为终点已有执行中的任务!",
                    };
                }

                var body = new GenAgvSchedulingTaskRequest()
                {
                    positionCodePath = positionCodePathItems,
                };
                var response = ApiHelp.GetDataFromHttp<AGVResponseModel>(url, body, "POST", true);
                if (response.code == "0" && response.message == "成功")
                {
                    //生成任务数据
                    var task = new AgvTask()
                    {
                        ShelfCode = shelfCode,
                        RequestCode = body.reqCode,
                        TaskCode = body.taskCode,
                        TaskType = "GenAgvSchedulingTask",
                        StratLocationId = startLocation.Id,
                        StartLocationCode = startLocation.LocationCode,
                        EndLocationId = endLocation.Id,
                        EndLocationCode = endLocation.LocationCode,
                        CreateUser = createUser
                    };
                    DbHelp.db.Insertable(task).ExecuteCommand();
                }

                return response;
            }
        }

        public static AGVResponseModel GenAgvSchedulingTaskForResend(LocationInfo startLocation, LocationInfo endLocation, AgvTask agvTask, string shelfCode, string createUser)
        {
            var url = @"http://192.168.18.150:8181/rcms/services/rest/hikRpcService/genAgvSchedulingTask";
            var startPositionCodePathItem = new PositionCodePathItem()
            {
                positionCode = startLocation.RcsStoreCode,
            };
            var endPositionCodePathItem = new PositionCodePathItem()
            {
                positionCode = endLocation.RcsStoreCode,
            };
            List<PositionCodePathItem> positionCodePathItems = new List<PositionCodePathItem>();

            positionCodePathItems.Add(startPositionCodePathItem);
            positionCodePathItems.Add((endPositionCodePathItem));

            //任务只允许一个一个发送
            lock (lockFlag)
            {
                //正在执行中的任务
                var tasks = DbHelp.db.Queryable<AgvTask>()
                                     .Where(t => t.TaskStatus == TaskStatusEnum.已创建 || t.TaskStatus == TaskStatusEnum.正在执行)
                                     .ToList();
                //校验货架
                if (tasks.Where(t => t.ShelfCode == shelfCode).Any())
                {
                    return new AGVResponseModel()
                    {
                        code = "-999",
                        message = $"货架[{shelfCode}]已有执行中的任务!",
                    };
                }
                //校验起点
                if (tasks.Where(t => t.StratLocationId == startLocation.Id).Any())
                {
                    return new AGVResponseModel()
                    {
                        code = "-999",
                        message = $"工位[{startLocation.LocationCode}]作为起点已有执行中的任务!",
                    };
                }
                //校验终点
                if (tasks.Where(t => t.EndLocationId == endLocation.Id).Any())
                {
                    return new AGVResponseModel()
                    {
                        code = "-999",
                        message = $"工位[{endLocation.LocationCode}]作为终点已有执行中的任务!",
                    };
                }

                agvTask.TaskCode = agvTask.TaskCode + "_resend";
                agvTask.CreateTime = DateTime.Now;
                agvTask.CreateUser = createUser;

                var body = new GenAgvSchedulingTaskRequest()
                {
                    taskCode = agvTask.TaskCode,
                    positionCodePath = positionCodePathItems,
                };
                var response = ApiHelp.GetDataFromHttp<AGVResponseModel>(url, body, "POST", true);
                if (response.code == "0" && response.message == "成功")
                {
                    //DbHelp.db.Updateable(agvTask).ExecuteCommand();
                    //生成任务数据
                    var task = new AgvTask()
                    {
                        ShelfCode = shelfCode,
                        RequestCode = body.reqCode,
                        TaskCode = agvTask.TaskCode,
                        TaskType = "GenAgvSchedulingTask",
                        StratLocationId = startLocation.Id,
                        StartLocationCode = startLocation.LocationCode,
                        EndLocationId = endLocation.Id,
                        EndLocationCode = endLocation.LocationCode,
                        CreateUser = createUser
                    };
                    DbHelp.db.Insertable(task).ExecuteCommand();
                }

                return response;
            }
        }

        /// <summary>
        /// RCS取消任务
        /// </summary>
        /// <param name="agvTask"></param>
        /// <returns></returns>
        public static AGVResponseModel CancelTask(AgvTask agvTask)
        {
            try
            {
                var url = @"http://192.168.18.150:8181/rcms/services/rest/hikRpcService/cancelTask";

                //任务只允许一个一个发送
                lock (lockFlag)
                {
                    var body = new AGVCancelTaskRequest()
                    {
                        taskCode = agvTask.TaskCode,
                    };

                    var response = ApiHelp.GetDataFromHttp<AGVResponseModel>(url, body, "POST", true);
                    if (response.code == "0" && response.message == "成功")
                    {
                        //取消会统一在后台线程更新

                        //agvTask.TaskStatus = Model.ApiModel.AGV.TaskStatusEnum.取消完成;
                        //DbHelp.db.Updateable(agvTask).ExecuteCommand();
                    }
                    return response;
                }
            }
            catch (Exception ex)
            {
                return new AGVResponseModel()
                {
                    code = "-1",
                    message = $"发生异常：{ex.Message}"
                };
            }
        }

        /// <summary>
        /// RCS货架绑定 解绑
        /// </summary>
        /// <param name="agvTask"></param>
        /// <returns></returns>
        public static AGVResponseModel BindPodAndBerth(string shelfCode, string locationCode, BindPodAndBerthMethod bindPodAndBerthMethod)
        {
            try
            {
                //货架绑定解绑地址
                var url = @"http://192.168.18.150:8181/rcms/services/rest/hikRpcService/bindPodAndBerth";

                //任务只允许一个一个发送
                lock (lockFlag)
                {
                    var body = new AGVBindPodAndBerthRequest()
                    {
                        podCode = shelfCode,
                        positionCode = locationCode,
                        pointCode = locationCode,
                        indBind = ((int)bindPodAndBerthMethod).ToString(),
                    };
                    var response = ApiHelp.GetDataFromHttp<AGVResponseModel>(url, body, "POST", true);
                    //if (response.code == "0" && response.message == "成功")
                    //{

                    //}
                    return response;
                }
            }
            catch (Exception ex)
            {
                return new AGVResponseModel()
                {
                    code = "-1",
                    message = $"发生异常：{ex.Message}"
                };
            }
        }

        public static void RefreshAgvStatus()
        {
            try
            {
                Logs.Write("[刷新AGV状态]开始刷新AGV状态");
                var url = @"http://192.168.18.150:8181/rcms-dps/rest/queryAgvStatus";
                var body = new AGVQueryAgvStatusRequest();
                var response = ApiHelp.GetDataFromHttpShortTime<AGVQueryAgvStatusResponse>(url, body, "POST", true);
                if (response == null)
                {
                    Logs.Write("[刷新AGV状态]Response为空！");
                    return;
                }
                //response不为空 更新task表的状态
                var tasks = DbHelp.db.Queryable<AgvTask>()
                                     .Where(t => t.TaskStatus == TaskStatusEnum.已创建 || t.TaskStatus == TaskStatusEnum.正在执行)
                                     .ToList();
                if (tasks == null || tasks.Count == 0)
                {
                    Logs.Write("[刷新AGV状态]状态为执行中或者已创建的任务为空！");
                }
                foreach (var task in tasks)
                {
                    var agvCode = task.AgvCode;
                    if (string.IsNullOrEmpty(agvCode))
                    {
                        continue;
                    }
                    var dataItem = response?.data.Where(t => t.robotCode == agvCode).FirstOrDefault();
                    if (dataItem == null)
                    { 
                        continue ;
                    }

                    var str = string.Empty;
                    switch (dataItem.status)
                    {
                        case "1":
                            str = "任务完成";
                            break;
                        case "2":
                            str = "任务执行中";
                            break;
                        case "3":
                            str = "任务异常";
                            break;
                        case "4":
                            str = "任务空闲";
                            break;
                        case "5":
                            str = "机器人暂停";
                            break;
                        case "6":
                            str = "举升货架状态";
                            break;
                        case "7":
                            str = "充电状态";
                            break;
                        case "8":
                            str = "弧线行走中";
                            break;
                        case "9":
                            str = "充满维护";
                            break;
                        case "11":
                            str = "背货未识别";
                            break;
                        case "12":
                            str = "货架偏角过大";
                            break;
                        case "13":
                            str = "运动库异常";
                            break;
                        case "14":
                            str = "货码无法识别";
                            break;
                        case "15":
                            str = "货码不匹配";
                            break;
                        case "16":
                            str = "举升异常";
                            break;
                        case "17":
                            str = "充电桩异常";
                            break;
                        case "18":
                            str = "电量无增加";
                            break;
                        case "20":
                            str = "充电指令角度错误";
                            break;
                        case "21":
                            str = "平台下发指令错误";
                            break;
                        case "23":
                            str = "外力下放";
                            break;
                        case "24":
                            str = "货架位置偏移";
                            break;
                        case "25":
                            str = "小车不在锁定区";
                            break;
                        case "26":
                            str = "下放重试失败";
                            break;
                        case "27":
                            str = "货架摆歪";
                            break;
                        case "28":
                            str = "举升电池电量太低";
                            break;
                        case "29":
                            str = "后退角度偏大";
                            break;
                        case "30":
                            str = "未背货架举升";
                            break;
                        case "31":
                            str = "区域锁定失败";
                            break;
                        case "33":
                            str = "旋转申请暂时失败";
                            break;
                        case "34":
                            str = "地图切换点地码未识别";
                            break;
                        default:
                            str = "未知状态";
                            break;
                    }
                    //更新状态
                    task.AgvStatus = str;
                }
                DbHelp.db.Updateable(tasks).UpdateColumns(t => new { t.AgvStatus }).ExecuteCommand();
                Logs.Write("[刷新AGV状态]结束刷新AGV状态");
            }
            catch (Exception ex)
            {
                Logs.Write($"[刷新AGV状态]遇到异常{ex.Message}\r\n{ex.StackTrace}");
            }
        }

    }

    /// <summary>
    /// 解绑或者绑定
    /// </summary>
    public enum BindPodAndBerthMethod
    {
        解绑 = 0,
        绑定 = 1,
    }
}
