using Jc.SnowId;
using Khd.Core.Application.Interface;
using Khd.Core.Domain.Dto.webapi;
using Khd.Core.Domain.Models;
using Khd.Core.EntityFramework;
using Masuit.Tools;
using Masuit.Tools.Logging;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System;
using System.Linq;
using Z.EntityFramework.Plus;

namespace Khd.Core.Application
{
    public class WcsTaskApplication : IWcsTaskApplication
    {
        private readonly DefaultDbContext _dbContext;
        private readonly static JcSnowId _snowId = new JcSnowId();

        public WcsTaskApplication(IServiceProvider serviceProvider)
        {
            _dbContext = serviceProvider.GetService<DefaultDbContext>();
        }

        public WcsTask Get(int id)
        {
            var entity = _dbContext.WcsTask
                .Where(c => 1 == 1)
                .FirstOrDefault();
            return entity;
        }

        public WcsTask Add(WcsTask model)
        {
            var entity = _dbContext.Add(model);
            _dbContext.SaveChanges();
            return entity.Entity;

        }

        public WcsTask Update(WcsTask model)
        {
            var list = _dbContext.WcsTask.Where(t => t.objid == model.objid).Update(a => model);
            return model;
        }

        /// <summary>
        /// 接收agv接收任务通知接口
        /// </summary>
        /// <param name="agvCallbackDto"></param>
        /// <returns></returns>
        public ReponseagvCallbackDto AgvCallback(agvCallbackDto agvCallbackDto)
        {
            ReponseagvCallbackDto reponseagvCallbackDto = new ReponseagvCallbackDto();
            try
            {
                _dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                WcsTask wcsTask = _dbContext.WcsTask.FirstOrDefault(t => t.taskCode == agvCallbackDto.taskCode);
                if (wcsTask != null)
                {
                    //start 开始   end结束   continue继续
                    //待取货
                    if (agvCallbackDto.method.ToLower() == "start")
                    {
                        wcsTask.taskStatus = 2;
                        _dbContext.WcsTask.Update(wcsTask);
                        _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 2 });
                        _dbContext.SaveChanges();
                        reponseagvCallbackDto.code = "0";
                        reponseagvCallbackDto.message = "成功";
                    }
                    if (agvCallbackDto.method.ToLower() == "con")
                    {
                        wcsTask.taskStatus = 4;
                        _dbContext.WcsTask.Update(wcsTask);
                        _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 4 });
                        _dbContext.SaveChanges();
                        reponseagvCallbackDto.code = "0";
                        reponseagvCallbackDto.message = "成功";
                    }
                    //已取货待放货
                    if (agvCallbackDto.method.ToLower() == "continue")
                    {

                        wcsTask.taskStatus = 3;
                        _dbContext.WcsTask.Update(wcsTask);
                        _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 3 });
                        _dbContext.SaveChanges();
                        reponseagvCallbackDto.code = "0";
                        reponseagvCallbackDto.message = "成功";
                    }
                    //放货完成
                    if (agvCallbackDto.method.ToLower() == "end")
                    {
                        if (wcsTask.nextPointId != 10)
                        {
                            wcsTask.taskStatus = 5;

                            _dbContext.WcsTask.Update(wcsTask);
                            _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 5 });
                            _dbContext.SaveChanges();
                            reponseagvCallbackDto.code = "0";
                            reponseagvCallbackDto.message = "成功";
                        }
                        else
                        {
                            wcsTask.taskStatus = 6;
                            _dbContext.WcsTask.Update(wcsTask);
                            _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 6 });
                            _dbContext.SaveChanges();
                            reponseagvCallbackDto.code = "0";
                            reponseagvCallbackDto.message = "成功";
                        }
                    }
                }
                else
                {
                    reponseagvCallbackDto.code = "1";
                    reponseagvCallbackDto.message = "未找到当前任务";
                }
            }
            catch (Exception ex)
            {
                LogManager.Error(ex);
                reponseagvCallbackDto.code = "1";
                reponseagvCallbackDto.message = ex.Message;
            }
            //返回请求
            reponseagvCallbackDto.reqCode = reponseagvCallbackDto.reqCode;
            return reponseagvCallbackDto;

        }

        /// <summary>
        /// 入库完成
        /// </summary>
        /// <returns></returns>
        public string InWare(long taskId)
        {
            return "";
        }

        /// <summary>
        /// 出库完成
        /// </summary>
        /// <returns></returns>
        public string OutWare(long taskId)
        {
            return "";
        }

        /// <summary>
        /// 背负式Agv通知完成
        /// </summary>
        /// <param name="agvCompeletedRequest"></param>
        /// <returns></returns>
        public AgvCompeletedResponse MesToAgvComplete(AgvCompeleted agvCompeletedRequest)
        {
            AgvCompeletedResponse agvCompeletedResponse = new AgvCompeletedResponse();
            try
            {
                _dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                BaseEquip baseEquip = _dbContext.BaseEquip.FirstOrDefault(t => t.equipNo == agvCompeletedRequest.endStationCode);
                if (baseEquip != null)
                {
                    var wcsTask = _dbContext.WcsTask
                        .Where(t => (t.taskType == 32 || t.taskType == 48) && (t.endPointId == baseEquip.objid || t.currPointId == baseEquip.objid))
                        .OrderBy(t => t.createTime)
                        .FirstOrDefault();
                    if (wcsTask != null)
                    {
                        LogManager.Info($"agvComplete接口找到任务：{wcsTask.ToJsonString()}");
                        if (wcsTask.taskType != 48 && wcsTask.taskStatus != 0)
                        {
                            wcsTask.taskStatus = 7;
                            _dbContext.WcsTask.Update(wcsTask);
                            _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 7 });
                            _dbContext.SaveChanges();
                            agvCompeletedResponse.code = "0";
                            agvCompeletedResponse.message = "成功";
                            LogManager.Info($"agvComplete更新任务状态7{wcsTask.ToJsonString()}");
                        }
                        else if (wcsTask.taskStatus != 0)
                        {
                            wcsTask.taskStatus = 4;
                            _dbContext.WcsTask.Update(wcsTask);
                            _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 7 });
                            _dbContext.SaveChanges();
                            agvCompeletedResponse.code = "0";
                            agvCompeletedResponse.message = "成功";
                        }
                        else
                        {
                            agvCompeletedResponse.code = "1";
                            agvCompeletedResponse.message = "未找到当前任务";
                        }
                    }
                    else
                    {
                        agvCompeletedResponse.code = "1";
                        agvCompeletedResponse.message = "未找到当前任务";
                    }
                }
                else
                {
                    agvCompeletedResponse.code = "1";
                    agvCompeletedResponse.message = "未找到当前工位";
                }
            }
            catch (Exception ex)
            {
                LogManager.Error(ex);
                agvCompeletedResponse.code = "1";
                agvCompeletedResponse.message = ex.Message;
            }
            return agvCompeletedResponse;
        }

        /// <summary>
        /// 4楼到5楼原材料入口继续
        /// </summary>
        /// <param name="taskContinue"></param>
        /// <returns></returns>
        public AgvCompeletedResponse TaskContinue(TaskContinue taskContinue)
        {
            AgvCompeletedResponse compeletedResponse = new AgvCompeletedResponse();
            try
            {
                _dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                var wcsTask = _dbContext.WcsTask
                    .Where(t => t.taskType == 47)
                    .Where(t => t.materialId == taskContinue.materialId)
                    .FirstOrDefault();
                if (wcsTask != null)
                {
                    wcsTask.useFlag = 1;
                    _dbContext.WcsTask.Update(wcsTask);
                    _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(a => new WcsTaskLog { useFlag = 1 });
                    _dbContext.SaveChanges();
                    compeletedResponse.code = "0";
                    compeletedResponse.message = "成功";
                }
                else
                {
                    compeletedResponse.code = "1";
                    compeletedResponse.message = "未找到当前任务";
                }
            }
            catch (Exception ex)
            {
                LogManager.Error(ex);
                compeletedResponse.code = "1";
                compeletedResponse.message = ex.Message;
            }
            return compeletedResponse;
        }

        /// <summary>
        /// 柜体拆分区通知返库
        /// </summary>
        /// <param name="taskReturn"></param>
        /// <returns></returns>
        public AgvCompeletedResponse TaskReturn(TaskReturn taskReturn)
        {
            AgvCompeletedResponse compeletedResponse = new AgvCompeletedResponse();
            try
            {
                _dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                WcsTask wcsTask = _dbContext.WcsTask
                    .Where(t => t.taskType == 28)
                    .Where(t => t.endPointNo == taskReturn.endStationCode)
                    .FirstOrDefault();
                if (wcsTask != null)
                {
                    wcsTask.useFlag = 1;
                    _dbContext.WcsTask.Update(wcsTask);
                    _dbContext.WcsTask.Where(t => t.objid == wcsTask.objid).Update(a => new WcsTask { useFlag = 1 });
                    _dbContext.SaveChanges();
                    compeletedResponse.code = "0";
                    compeletedResponse.message = "成功";
                }
                else
                {
                    compeletedResponse.code = "1";
                    compeletedResponse.message = "未找到当前任务";
                }
            }
            catch (Exception ex)
            {
                LogManager.Error(ex);
                compeletedResponse.code = "1";
                compeletedResponse.message = ex.Message;
            }
            return compeletedResponse;
        }

        public ReponseagvCallbackDto AgvCallback2(agvCallbackDto agvCallbackDto)
        {
            ReponseagvCallbackDto reponseagvCallbackDto = new ReponseagvCallbackDto();
            try
            {
                _dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());

                WcsTask wcsTask = _dbContext.WcsTask.FirstOrDefault(t => t.taskCode == agvCallbackDto.taskCode);
                if (wcsTask != null)
                {
                    //start 开始   end结束   continue继续
                    //待取货
                    if (agvCallbackDto.method.ToLower() == "start")
                    {
                        wcsTask.taskStatus = 2;
                        _dbContext.WcsTask.Update(wcsTask);
                        _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 2 });
                        _dbContext.SaveChanges();
                        reponseagvCallbackDto.code = "0";
                        reponseagvCallbackDto.message = "成功";
                    }
                    if (agvCallbackDto.method.ToLower() == "con")
                    {
                        wcsTask.taskStatus = 4;
                        _dbContext.WcsTask.Update(wcsTask);
                        _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 4 });
                        _dbContext.SaveChanges();
                        reponseagvCallbackDto.code = "0";
                        reponseagvCallbackDto.message = "成功";
                    }
                    //已取货待放货
                    if (agvCallbackDto.method.ToLower() == "continue")
                    {
                        if (wcsTask.taskStatus > 3)
                        {
                            wcsTask.taskStatus = 5;
                            _dbContext.WcsTask.Update(wcsTask);
                            _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 5 });
                            _dbContext.SaveChanges();
                            reponseagvCallbackDto.code = "0";
                            reponseagvCallbackDto.message = "成功";
                        }
                        else
                        {
                            wcsTask.taskStatus = 3;
                            _dbContext.WcsTask.Update(wcsTask);
                            _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 3 });
                            _dbContext.SaveChanges();
                            reponseagvCallbackDto.code = "0";
                            reponseagvCallbackDto.message = "成功";
                        }
                    }
                    //放货完成
                    if (agvCallbackDto.method.ToLower() == "end")
                    {
                        wcsTask.taskStatus = 7;
                        _dbContext.WcsTask.Update(wcsTask);
                        _dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 7 });
                        _dbContext.SaveChanges();
                        reponseagvCallbackDto.code = "0";
                        reponseagvCallbackDto.message = "成功";
                    }
                }

            }
            catch (Exception ex)
            {
                LogManager.Error(ex);
                reponseagvCallbackDto.code = "1";
                reponseagvCallbackDto.message = ex.Message;
            }
            //返回请求
            reponseagvCallbackDto.reqCode = reponseagvCallbackDto.reqCode;
            return reponseagvCallbackDto;
        }

        public ReponseMessage CallMaterial(CallMaterial callMaterial)
        {
            ReponseMessage reponseMessage = new ReponseMessage();
            try
            {
                _dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                WmsRawOutstock wmsRawOutstock = _dbContext.WmsRawOutstock.FirstOrDefault(t => t.rawOutstockId == Convert.ToInt64(callMaterial.rawOutstockId));
                if (wmsRawOutstock != null)
                {
                    bool hasTask = _dbContext.WcsTask.Where(t => t.currPointId == 31).Any();
                    bool hasTaskManual = _dbContext.WcsTaskManual.Where(t => t.endPointId == 31 || t.currPointId == 31 || t.taskType == 999).Any();
                    if (hasTask || hasTaskManual)
                    {
                        reponseMessage.code = "1";
                        reponseMessage.message = "当前有任务，请等待任务完成后再申请";
                    }
                    else
                    {
                        BaseEquip endEquip = _dbContext.BaseEquip.First(t => t.objid == 31);
                        BaseEquip baseEquip = _dbContext.BaseEquip.First(t => t.objid == 9);
                        WcsTaskManual wcsTaskManual = new WcsTaskManual();
                        wcsTaskManual.taskType = 999;
                        wcsTaskManual.objid = _snowId.NextId();
                        wcsTaskManual.orderId = Convert.ToInt64(callMaterial.rawOutstockId);
                        _dbContext.Add(wcsTaskManual);
                        _dbContext.SaveChanges();
                        reponseMessage.code = "0";
                        reponseMessage.message = "成功";
                    }
                }
                else
                {
                    reponseMessage.code = "1";
                    reponseMessage.message = "未找到当前申请单的任务";
                }
            }
            catch (Exception ex)
            {
                reponseMessage.code = "1";
                reponseMessage.message = ex.Message;
                LogManager.Error(ex);
            }
            return reponseMessage;
        }

        public ReponseMessage AGVTaskComplete()
        {
            ReponseMessage reponseMessage = new ReponseMessage();
            try
            {
                _dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                bool hasTask = _dbContext.WcsTask.Where(t => t.taskType == 41).Any();
                if (!hasTask)
                {
                    reponseMessage.code = "0";
                    reponseMessage.message = "成功";
                }
                else
                {
                    reponseMessage.code = "1";
                    reponseMessage.message = "当前不可翻转";
                }
            }
            catch (Exception ex)
            {
                reponseMessage.code = "1";
                reponseMessage.message = ex.Message;
                LogManager.Error(ex);
            }
            return reponseMessage;
        }

        public ReponseMessage CallAgvStopOrStart(CallAgvStopOrStart agvStopOrStart)
        {
            try
            {
                string Ip = "172.16.12.24";
                int Port = 8182;
                if (agvStopOrStart.Meth.ToLower() == "stop")
                {
                    var AgvMessage = new
                    {
                        reqCode = _snowId.NextId().ToString(),
                        robots = new string[] { agvStopOrStart.AgvCode }
                    };
                    string result = HttpHelper.SendPostMessage(Ip, Port, "rcms/services/rest/hikRpcService/stopRobot", AgvMessage.ToJsonString());
                    ReponseMessage reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                    return reponseMessage;
                }
                else if (agvStopOrStart.Meth.ToLower() == "start")
                {
                    var AgvMessage = new
                    {
                        reqCode = _snowId.NextId().ToString(),
                        robots = new string[] { agvStopOrStart.AgvCode }
                    };
                    string result = HttpHelper.SendPostMessage(Ip, Port, "rcms/services/rest/hikRpcService/resumeRobot", AgvMessage.ToJsonString());
                    ReponseMessage reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(result);
                    return reponseMessage;
                }
                else
                {
                    return new ReponseMessage() { code = "1", message = "传入Meth不正确" };
                }
            }
            catch
            {
                return new ReponseMessage() { code = "1", message = "调用失败" };
            }
        }


        /// <summary>
        /// 取消预调度
        /// </summary>
        /// <returns></returns>
        public ReponseMessage CancelPreScheduling()
        {
            try
            {
                _dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
                var baseEquip = _dbContext.BaseEquip.FirstOrDefault(x => x.objid == 11);
                var executeTask = new
                {
                    reqCode = new JcSnowId().NextId().ToString(),
                    positionCode = "CTU_IN",
                    nextTask = -1
                };
                string executeMessage = JsonConvert.SerializeObject(executeTask);
                string executeResult = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms/services/rest/hikRpcService/genPreScheduleTask", executeMessage);
                ReponseMessage reponseMessage = JsonConvert.DeserializeObject<ReponseMessage>(executeResult);
                return reponseMessage;

            }catch (Exception ex)
            {
                return new ReponseMessage() { code = "1", message = "调用失败" };
            }
        }
    }
}