using Microsoft.AspNetCore.Mvc;
using NetTaste;
using Newtonsoft.Json;
using PlcSiemens.Core.Extension;
using ServiceCenter.Attributes;
using ServiceCenter.Logs;
using ServiceCenter.Redis;
using ServiceCenter.SqlSugars;
using WCS.Core;
using WCS.Entity;
using WCS.Entity.Protocol.Station;
using WCS.WorkEngineering.Extensions;
using WCS.WorkEngineering.Systems;
using WCS.WorkEngineering.WebApi.Models.AGV;
using WCS.WorkEngineering.WebApi.Models.AGV.Request;
using WCS.WorkEngineering.WebApi.Models.AGV.Response;

namespace WCS.WorkEngineering.WebApi.Controllers
{
    /// <summary>
    /// AGV相关接口控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class AgvController : ControllerBase
    {
        static object lockerApplyEmptySpool = new object();
        static object lockerAgvCallback = new object();
        /// <summary>
        ///  AGV任务下发测试
        /// </summary>
        /// <param name="type">任务类型</param>
        /// <param name="code">RFID</param>
        /// <param name="pos">目标位置</param>
        /// <returns></returns>
        [HttpPost]
        public string AgvDebug(int type, string code, string pos)
        {
            try
            {
                switch (type)
                {
                    case 1:
                        AgvApi.机台补空(pos, code, "1");
                        break;

                    case 2:
                        //AgvApi.机台补满();
                        break;

                    case 3:
                        AgvApi.满轮入库(code, pos, Guid.NewGuid().ToString().Replace("-", ""), "1");
                        break;

                    default:
                        break;
                }
                return "成功";
            }
            catch (Exception ex)
            {
                return $"Error-----" +
                      $"{ex.Message}------" +
                      $"{ex.StackTrace}";
            }
        }

        /// <summary>
        ///  背负式AGV请求出库任务
        /// </summary>
        /// <param name="reqDto">请求参数</param>
        /// <returns></returns>
        [HttpPost]
        public ApplyEmptySpoolResponse ApplyEmptySpool([FromBody] AgvFillEmptySpaceRequest reqDto)
        {
            return new ApplyEmptySpoolResponse()
            {
                ResCode = Models.WMS.Response.ResponseStatusCodeEnum.AccountError,
                ResMsg = "接口已禁用,已经改为主动下发方式"
            };
            var key = $"WCS:Lock:AGV:{nameof(ApplyEmptySpool)}";
            ApplyEmptySpoolResponse agvFill = new ApplyEmptySpoolResponse();
            lock (lockerApplyEmptySpool)
            {
                LogHub.InterfacePublish(nameof(ApplyEmptySpool), $"传入参数--{JsonConvert.SerializeObject(reqDto)}");
                if (RedisHub.Default.Get(key) != null)
                {
                    agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
                    agvFill.ResMsg = $"[{nameof(ApplyEmptySpool)}]--触发并发管控";
                    return agvFill;
                }
                RedisHub.Default.Set(key, nameof(ApplyEmptySpool), 60);
            }
            try
            {

                try
                {
                    agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
                    if (!World.IsStart)
                    {
                        agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
                        agvFill.ResMsg = "WCS初始化中";
                        return agvFill;
                    }
                    var obj = World.GetSystemInstance<GetDeviceSystem>().Invoke("输送机") as List<Station>;

                    // 检测三个站台是否有货
                    obj = obj.Where(v => v.Entity.Code is "1012" or "1014" or "1016").Where(v => v.Data3.Status.HasFlag(StatusEunm.PH_Status)).ToList();
                    if (!obj.Any())
                    {
                        agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
                        agvFill.ResMsg = "无空轮";
                        return agvFill;
                    }
                    SqlSugarHelper.Do(db =>
                    {
                        //查询此请求是否已经有过任务
                        var existtask = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(tabs => tabs.Take(2)).Where(v =>  v.EditWho == reqDto.Reqid ).Select(v => v).ToList();
                        if (existtask != null && existtask.Any())
                        {
                            var temp = existtask.ToList().First();
                            agvFill.LocCode = temp.Station;
                            agvFill.SpoolType = "4";
                            agvFill.ResMsg = "";
                            agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.Sucess;
                            agvFill.TaskCode = temp.AgvID;
                        }
                        else
                        {
                            var res = WmsApi.GetTunnelEmptyConCount();

                            var agvStations = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(tabs => tabs.Take(2))
                                                .Where(v => v.Status < AGVTaskStatus.Complete3 && (v.TaskType == AGVTaskType.CallForMaterial || (v.TaskType == AGVTaskType.CallMaterial && v.WorkShop == 111 && v.Status >= AGVTaskStatus.Confirm))).Select(v => v.Station).ToList();
                            obj = obj.Where(v => !agvStations.Contains(v.Entity.Code)).ToList();
                            if (!obj.Any())
                            {
                                agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
                                agvFill.ResMsg = "无可用取货站点";
                                return;
                            }

                            foreach (var item in res.ResDataList)
                            {
                                var station = Device.All.Where(v => v.Code == "TY" + item.Tunnel.ToString())
                                                        .Select(v => v.Targets).SelectMany(v => v)
                                                        .Where(v => v.HasProtocol(typeof(IStation520)))
                                                        .Where(v => v.Code is "1012" or "1014" or "1016")
                                                        .FirstOrDefault();
                                item.Tunnel = station.ToInt();
                            }
                            var stationNo = res.ResDataList.OrderBy(v => v.Count).Select(v => v.Tunnel.ToString()).ToList();
                            var dev = obj.MinBy(v => stationNo.IndexOf(v.Entity.Code));
                            var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == dev.Data.TaskNumber) ?? throw new Exception("无有效任务");

                            if (task.BusType != "一楼立库出空轮" && task.TaskGroupKey != "1")
                            {
                                agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
                                agvFill.ResMsg = $"{dev.Entity.Code}不可用";
                                return;
                            }
                            var id = db.GetAGVTaskId();
                            var agv = new WCS_AgvTaskInfo()
                            {
                                ID = id,
                                AgvID = $"HJBK{id}{task.ID}",
                                TaskType = AGVTaskType.CallForMaterial,
                                Status = AGVTaskStatus.NewBuild,
                                Station = dev.Entity.Code,
                                AddWho = "WCS",
                                EditWho = reqDto.Reqid//请求id暂存
                            };
                            //创建对应的AGV任务
                            db.Default.Insertable(agv).SplitTable().ExecuteCommand();

                            task.AgvTaskID = agv.ID;
                            task.Status = Entity.TaskStatus.AGVExecution;
                            db.Default.Updateable(task).ExecuteCommand();
                            task.AddWCS_TASK_DTL(db, dev.Entity.Code, "AGV", "agv执行中");

                            agvFill.LocCode = dev.Entity.Code;
                            agvFill.SpoolType = "4";
                            agvFill.ResMsg = "";
                            agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.Sucess;
                            agvFill.TaskCode = agv.AgvID;
                        }

                    });
                }
                catch (Exception ex)
                {
                    agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
                    agvFill.ResMsg = ex.Message;
                }
                LogHub.InterfacePublish(nameof(ApplyEmptySpool), $"返回参数{JsonConvert.SerializeObject(agvFill)}");

            }
            finally
            {
                RedisHub.Default.Del(key);
            }
            return agvFill;
        }

        /// <summary>
        /// AGV执行回调
        /// </summary>
        /// <param name="reqDto"></param>
        /// <returns></returns>
        [HttpPost]
        public AgvCallbackResponse AgvCallback([FromBody] AgvCallbackRequest reqDto)
        {
            return new AgvCallbackResponse()
            {
                code = AgvResponseCode.Error,
                message = "接口已禁用"
            };

            var key = $"WCS:Lock:AGV:{nameof(AgvCallback)+ reqDto.taskCode}";
            var res = new AgvCallbackResponse() { code = AgvResponseCode.Fail, message = "失败" };
            lock (lockerAgvCallback)
            {
                if (RedisHub.Default.Get(key) != null)
                {
                    res.code = AgvResponseCode.Error;
                    res.message = $"[{nameof(AgvCallback) + reqDto.taskCode}]--触发并发管控";
                    return res;
                }
                RedisHub.Default.Set(key, nameof(AgvCallback), 60);
            }
            try
            {
                //if (RedisHub.Default.Get(key) != null)
                //{
                //    res.code = AgvResponseCode.Error;
                //    res.message = $"[{nameof(AgvCallback)}]--触发并发管控";
                //}
                //else
                //{
                    //RedisHub.Default.Set(key, nameof(AgvCallback));
                    WCS_TaskInfo taskInfo = null;
                    try
                    {
                        SqlSugarHelper.Do(db =>
                        {
                            //跟据AGVid找到对应的AGV任务
                            var agvTask = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.AgvID == reqDto.taskCode && v.Status < AGVTaskStatus.MissionCompleted).SplitTable(tabs => tabs.Take(2)).First();
                            if (agvTask == null)
                            {
                                res.code = AgvResponseCode.Fail;
                                res.message = "未找到对应的AGV任务";

                            }
                            else
                            {
                                switch (reqDto.method)
                                {
                                    //case "start": //表示请求巷道
                                    //    agvTask.Status = AGVTaskStatus.RequestOrPermission1;
                                    //    break;

                                    //case "end": //表示请求巷道
                                    //    agvTask.Status = AGVTaskStatus.RequestOrPermission1;
                                    //    break;

                                    case "applyContinue": //表示手动调用请求巷道
                                        agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission1;
                                        break;

                                    case "applyContinueManaual": //表示请求巷道
                                        agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission1;
                                        agvTask.Status = AGVTaskStatus.Confirm;
                                        break;
                                    case "applySecurity": //表示请求放货或取货
                                        agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission2;
                                        break;

                                    case "end_1": //一楼出满任务完成
                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
                                        break;

                                    case "hjend_2": //补空任务完成
                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
                                        break;

                                    case "endhjBM": //取满任务完成
                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
                                        break;

                                    case "end": //二楼出满任务完成
                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
                                        break;

                                    case "tcEnd": //机台补空任务完成
                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
                                        break;

                                    case "exc_end": //异常信息上抛-值不匹配
                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
                                        break;

                                    case "outbin": //小车退出取货位
                                        agvTask.AgvStatus = AGVTaskStatus.Complete3;
                                        break;

                                    case "cancel": //取消任务
                                                   //agvTask.AgvStatus = AGVTaskStatus.Cancel;
                                        break;

                                    default:
                                        break;
                                }
                                db.Default.Updateable(agvTask).SplitTable(x => x.Take(2)).ExecuteCommand();
                                res.code = AgvResponseCode.Success;
                                res.message = "成功";
                            }


                        });
                    }
                    catch (Exception ex)
                    {
                        res.code = AgvResponseCode.Error;
                        res.message = ex.Message;
                    }
                //}
            }
            finally
            {
                RedisHub.Default.Del(key);
            }
            return res;
        }
    }
}
