using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using PlcSiemens.Core.Extension;
using ServiceCenter;
using ServiceCenter.Attributes;
using ServiceCenter.Extensions;
using ServiceCenter.Redis;
using ServiceCenter.SqlSugars;
using System.Net.NetworkInformation;
using System.Text;
using WCS.Core;
using WCS.Entity;
using WCS.Entity.Protocol.DataStructure;
using WCS.Entity.Protocol.SRM;
using WCS.WorkEngineering.Extensions;
using WCS.WorkEngineering.Systems;
using WCS.WorkEngineering.WebApi.Models.WCS.Request;
using WCS.WorkEngineering.WebApi.Models.WCS.Response;
using WCS.WorkEngineering.WebApi.Models.WMS.Response;

namespace WCS.WorkEngineering.WebApi.Controllers
{
    public interface IDeviceWriter
    {
        [HttpPost]
        void Write(DeviceTypeEnum deviceType, string devCode, string protocol, string propName, string value);
    }

    /// <summary>
    ///  设备Ip通讯检测结构
    /// </summary>
    public class DeviceIpTestResults
    {
        public string Ip { get; set; }

        public bool Result { get; set; }
    }

    /// <summary>
    /// WCS相关接口控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class WcsController : ControllerBase, IDeviceWriter
    {
        /// <summary>
        ///  获取设备信息
        /// </summary>
        /// <param name="type"></param>
        /// <param name="name">设备名称</param>
        /// <returns></returns>
        [HttpGet]
        public object GetDeviceInfo(string type, string name)
        {
            var obj = World.GetSystemInstance<GetDeviceSystem>().Invoke(new Tuple<string, string>(type, name));
            return obj;
        }

        /// <summary>
        ///  获取设备配置信息接口
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public List<Device> GetDeviceList()
        {
            return Device.All.ToList();
        }

        /// <summary>
        ///  设备信息写入接口
        /// </summary>
        [HttpPost]
        public void GetDevList()
        {
            var a = RedisHub.Monitor.LRange("Packs", 0, 80000);
            var packs = a.Select(JsonConvert.DeserializeObject<DeviceDataPack>).ToList();
        }

        /// <summary>
        ///  任务处理接口
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost, Log("任务处理接口")]
        public SRes<HandleTaskResponse> HandleTask([FromBody] HandleTaskRequest req)
        {
            var response = new SRes<HandleTaskResponse>() { ResCode = ResponseStatusCodeEnum.Sucess, ResDataList = new List<HandleTaskResponse>() };

            switch (req.Type)
            {
                //取消任务
                case HandleTaskTypeEnum.取消任务:
                    SqlSugarHelper.Do(db =>
                    {
                        foreach (var item in req.TaskIds)
                        {
                            var task = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.ID == item).First();
                            if (task != null)
                            {
                                //验证wms是否能取消
                                var res = WmsApi.HandleTaskVerify(response, item, 106);
                                if (res == null) continue;

                                switch (task.Type)
                                {
                                    case TaskType.SetPlate:
                                        if (task.Status != Entity.TaskStatus.WaitingToExecute)
                                        {
                                            response.ResDataList.Add(new HandleTaskResponse()
                                            {
                                                IsSuccess = false,
                                                TaskNo = item,
                                                Message = $"只能取消待执行状态组盘任务",
                                            });
                                            continue;
                                        }
                                        break;

                                    case TaskType.EnterDepot:
                                        if (task.Status > Entity.TaskStatus.WaitingToExecute && task.Status > Entity.TaskStatus.AGVExecution)
                                        {
                                            response.ResDataList.Add(new HandleTaskResponse()
                                            {
                                                IsSuccess = false,
                                                TaskNo = item,
                                                Message = $"只能取消待执行状态入库任务",
                                            });
                                            continue;
                                        }
                                        break;

                                    case TaskType.OutDepot:
                                        if (task.Status > Entity.TaskStatus.WaitingToExecute)
                                        {
                                            response.ResDataList.Add(new HandleTaskResponse()
                                            {
                                                IsSuccess = false,
                                                TaskNo = item,
                                                Message = $"只能取消待执行状态出库任务",
                                            });
                                            continue;
                                        }

                                        break;

                                    case TaskType.TransferDepot:
                                        if (task.Status > Entity.TaskStatus.WaitingToExecute)
                                        {
                                            response.ResDataList.Add(new HandleTaskResponse()
                                            {
                                                IsSuccess = false,
                                                TaskNo = item,
                                                Message = $"无法取消{task.Status.GetDescription()}的移库任务,只能取消新建/待执行的移库任务",
                                            });
                                            continue;
                                        }
                                        break;

                                    case TaskType.Delivery:

                                        break;

                                    case TaskType.EmptyInit:
                                        if (task.Status != Entity.TaskStatus.WaitingToExecute)
                                        {
                                            response.ResDataList.Add(new HandleTaskResponse()
                                            {
                                                IsSuccess = false,
                                                TaskNo = item,
                                                Message = $"只能取消待执行状态空轮初始化任务",
                                            });
                                            continue;
                                        }
                                        break;

                                    default:
                                        throw new ArgumentOutOfRangeException();
                                }

                                var cancelRes = WmsApi.CarryTaskInfo(response, item, 106);
                                if (cancelRes == null) continue;

                                //找到对应的AGV任务
                                var agv = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.ID == task.AgvTaskID && v.AgvStatus < AGVTaskStatus.MissionCompleted).SplitTable(v => v.Take(2)).First();
                                if (agv != null)
                                {
                                    if (!agv.AgvID.IsNullOrEmpty())
                                    {
                                        var cancelTaskUpdateRes = AgvApi.CancelAgvTask(response, item, agv.AgvID);
                                        //if (cancelTaskUpdateRes == null) continue;
                                    }
                                    agv.Status = AGVTaskStatus.Cancel;
                                    agv.AgvStatus = AGVTaskStatus.Cancel;
                                    db.Default.Updateable(agv).SplitTable(x=>x.Take(2)).ExecuteCommand();
                                }
                                //更新任务状态
                                task.Status = Entity.TaskStatus.Cancel;
                                task.EndTime = DateTime.Now;
                                task.EditWho = req.User;
                                task.ManualRemarks = req.ManualRemarks;
                                db.Default.Updateable(task).ExecuteCommand();
                                task.AddWCS_TASK_DTL(db.Default, "未知", "任务取消");
                            }
                            else
                            {
                                response.ResDataList.Add(new HandleTaskResponse()
                                {
                                    IsSuccess = false,
                                    TaskNo = item,
                                    Message = $"未找到对应任务{item}"
                                });
                            }
                        }
                    });
                    break;
                // 完成任务
                case HandleTaskTypeEnum.完成任务:
                    SqlSugarHelper.Do(db =>
                    {
                        foreach (var item in req.TaskIds)
                        {
                            var task = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.ID == item).First();
                            if (task == null) continue;
                            switch (task.Type)
                            {
                                case TaskType.OutDepot:
                                    {
                                        var res = WmsApi.HandleTaskVerify(response, item, 99);
                                        if (res == null) continue;

                                        switch (task.Type)
                                        {
                                            case TaskType.OutDepot:
                                                if (task.Status >= Entity.TaskStatus.Finish)
                                                {
                                                    response.ResDataList.Add(new HandleTaskResponse()
                                                    {
                                                        IsSuccess = false,
                                                        TaskNo = item,
                                                        Message = $"只能完成未完成状态的任务",
                                                    });
                                                    continue;
                                                }
                                                break;

                                            case TaskType.SetPlate:
                                                break;

                                            case TaskType.EnterDepot:
                                                break;

                                            case TaskType.TransferDepot:
                                                break;

                                            case TaskType.Delivery:
                                                break;

                                            case TaskType.EmptyInit:
                                                break;

                                            default:
                                                throw new ArgumentOutOfRangeException();
                                        }

                                        var cancelRes = WmsApi.CarryTaskInfo(response, item, 99);
                                        if (cancelRes == null) continue;

                                        //找到对应的AGV任务
                                        var agv = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.ID == task.AgvTaskID && v.AgvStatus < AGVTaskStatus.MissionCompleted).SplitTable(v => v.Take(2)).First();
                                        if (agv != null)
                                        {
                                            //if (!agv.AgvID.IsNullOrEmpty())
                                            //{
                                            //    var cancelTaskUpdateRes = CancelAgvTask(response, item, agv.AgvID);
                                            //    if (cancelTaskUpdateRes == null) continue;
                                            //}
                                            agv.Status = AGVTaskStatus.MissionCompleted;
                                            agv.AgvStatus = AGVTaskStatus.MissionCompleted;
                                            db.Default.Updateable(agv).SplitTable(x=>x.Take(2)).ExecuteCommand();
                                        }
                                        //更新任务状态
                                        task.Status = Entity.TaskStatus.Finish;
                                        task.EndTime = DateTime.Now;
                                        task.EditWho = req.User;
                                        task.ManualRemarks = req.ManualRemarks;
                                        db.Default.Updateable(task).ExecuteCommand();
                                        task.AddWCS_TASK_DTL(db.Default, "未知", "任务完成");
                                        break;
                                    }
                                case TaskType.EnterDepot:
                                    {
                                        var res = WmsApi.HandleTaskVerify(response, item, 99);
                                        if (res == null) continue;

                                        switch (task.Type)
                                        {
                                            case TaskType.EnterDepot:
                                                if (task.Status >= Entity.TaskStatus.Finish)
                                                {
                                                    response.ResDataList.Add(new HandleTaskResponse()
                                                    {
                                                        IsSuccess = false,
                                                        TaskNo = item,
                                                        Message = $"只能完成未完成状态的任务",
                                                    });
                                                    continue;
                                                }
                                                if (task.AddrTo.Length < 6)
                                                {
                                                    response.ResDataList.Add(new HandleTaskResponse()
                                                    {
                                                        IsSuccess = false,
                                                        TaskNo = item,
                                                        Message = $"只能完成已分配货位的任务",
                                                    });
                                                    continue;
                                                }
                                                break;

                                            case TaskType.SetPlate:
                                                break;

                                            case TaskType.OutDepot:
                                                break;

                                            case TaskType.TransferDepot:
                                                break;

                                            case TaskType.Delivery:
                                                break;

                                            case TaskType.EmptyInit:
                                                break;

                                            default:
                                                throw new ArgumentOutOfRangeException();
                                        }

                                        var cancelRes = WmsApi.CarryTaskInfo(response, item, 99);
                                        if (cancelRes == null) continue;

                                        //找到对应的AGV任务
                                        var agv = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.ID == task.AgvTaskID && v.AgvStatus < AGVTaskStatus.MissionCompleted).SplitTable(v => v.Take(2)).First();
                                        if (agv != null)
                                        {
                                            //if (!agv.AgvID.IsNullOrEmpty())
                                            //{
                                            //    var cancelTaskUpdateRes = CancelAgvTask(response, item, agv.AgvID);
                                            //    if (cancelTaskUpdateRes == null) continue;
                                            //}
                                            agv.Status = AGVTaskStatus.MissionCompleted;
                                            agv.AgvStatus = AGVTaskStatus.MissionCompleted;
                                            db.Default.Updateable(agv).SplitTable(x=>x.Take(2)).ExecuteCommand();
                                        }
                                        //更新任务状态
                                        task.Status = Entity.TaskStatus.Finish;
                                        task.EndTime = DateTime.Now;
                                        task.EditWho = req.User;
                                        task.ManualRemarks = req.ManualRemarks;

                                        db.Default.Updateable(task).ExecuteCommand();
                                        task.AddWCS_TASK_DTL(db.Default, "未知", "任务完成");
                                        break;
                                    }
                                case TaskType.SetPlate:
                                case TaskType.TransferDepot:
                                case TaskType.Delivery:
                                case TaskType.EmptyInit:
                                default:
                                    response.ResDataList.Add(new HandleTaskResponse()
                                    {
                                        IsSuccess = false,
                                        TaskNo = item,
                                        Message = $"未找到对应任务{item}"
                                    });
                                    break;
                            }
                        }
                    });
                    break;

                case HandleTaskTypeEnum.重新下发AGV任务:
                    SqlSugarHelper.Do(db =>
                    {
                        foreach (var item in req.TaskIds)
                        {
                            var task = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.ID == item).First();
                            if (task != null)
                            {
                                switch (task.Type)
                                {
                                    //组盘任务
                                    case TaskType.SetPlate:
                                        response.ResDataList.Add(new HandleTaskResponse()
                                        {
                                            IsSuccess = false,
                                            TaskNo = item,
                                            Message = $"组盘任务无AGV执行流程",
                                        });
                                        continue;
                                    //入库任务
                                    //一楼入库
                                    case TaskType.EnterDepot when task.Floor == 1:
                                        break;
                                    //二楼入库
                                    case TaskType.EnterDepot when task.Floor == 2:
                                        response.ResDataList.Add(new HandleTaskResponse()
                                        {
                                            IsSuccess = false,
                                            TaskNo = item,
                                            Message = $"二楼入库任务重新下发AGV未实现",
                                        });
                                        continue;
                                    //出库
                                    case TaskType.OutDepot:
                                        break;
                                    //移库
                                    case TaskType.TransferDepot:
                                        response.ResDataList.Add(new HandleTaskResponse()
                                        {
                                            IsSuccess = false,
                                            TaskNo = item,
                                            Message = $"组盘任务无AGV执行流程",
                                        });
                                        continue;
                                    //搬运
                                    case TaskType.Delivery when task.Floor == 1:
                                        break;

                                    case TaskType.Delivery when task.Floor == 2:
                                        response.ResDataList.Add(new HandleTaskResponse()
                                        {
                                            IsSuccess = false,
                                            TaskNo = item,
                                            Message = $"二楼搬运任务重新下发AGV未实现",
                                        });
                                        continue;
                                    //空轮初始化
                                    case TaskType.EmptyInit:
                                        response.ResDataList.Add(new HandleTaskResponse()
                                        {
                                            IsSuccess = false,
                                            TaskNo = item,
                                            Message = $"空轮初始化无AGV执行流程",
                                        });
                                        continue;
                                }

                                //找到对应的AGV任务
                                var agv = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.ID == task.AgvTaskID).SplitTable(v => v.Take(2)).First();
                                if (agv != null)
                                {
                                    agv.Status = AGVTaskStatus.NewBuild;
                                    agv.AgvStatus = AGVTaskStatus.NewBuild;
                                    db.Default.Updateable(agv).SplitTable(x=>x.Take(2)).ExecuteCommand();
                                }

                                task.Status = task.Floor switch
                                {
                                    1 => Entity.TaskStatus.WaitingToExecute,
                                    2 => Entity.TaskStatus.ConveyorExecution,
                                    _ => task.Status
                                };

                                task.AddWCS_TASK_DTL(db.Default, "AGV", "重新下发AGV任务");
                                db.Default.Updateable(task).ExecuteCommand();
                            }
                            else
                            {
                                response.ResDataList.Add(new HandleTaskResponse()
                                {
                                    IsSuccess = false,
                                    TaskNo = item,
                                    Message = $"未找到对应任务{item}"
                                });
                            }
                        }
                    });
                    break;

                case HandleTaskTypeEnum.调整优先级:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
            }
            return response;
        }

        /// <summary>
        ///  堆垛机测试
        /// </summary>
        /// <param name="srmcod">堆垛机编号</param>
        /// <param name="typeEnum">任务类型</param>
        /// <param name="value1">起始行</param>
        /// <param name="value2">起始列</param>
        /// <param name="value3">起始层</param>
        /// <param name="value4">目标行</param>
        /// <param name="value5">目标列</param>
        /// <param name="value6">目标层</param>
        [HttpPost]
        public void SrmDeBug(string srmcod, SrmTaskType typeEnum, short value1, short value2, short value3, short value4, short value5, short value6)
        {
            World.GetSystemInstance<SrmDebugSystem>().Invoke(new SrmDebugInfo
            {
                SrmCode = srmcod,
                srmTaskType = typeEnum,
                SLine = value1,
                SCol = value2,
                SLayer = value3,
                ELine = value4,
                ECol = value5,
                ELayer = value6
            });
        }

        /// <summary>
        ///  设备信息写入接口
        /// </summary>
        /// <param name="deviceType">需要写入信息的设备类型</param>
        /// <param name="devCode">设备编号</param>
        /// <param name="protocol">设备协议类名</param>
        /// <param name="propName">写入字段名</param>
        /// <param name="value">值</param>
        [HttpPost]
        public void Write(DeviceTypeEnum deviceType, string devCode, string protocol, string propName, string value)
        {
            World.GetSystemInstance<DeviceWriteSystem>().Invoke(new DeviceWriteInfo
            {
                DeviceType = deviceType,
                Code = devCode,
                Protocol = protocol,
                Property = propName,
                Value = value
            });
        }

        #region 设备IP相关

        /// <summary>
        /// 检查Ip是否正常联通
        /// </summary>
        /// <param name="strIpOrDName">输入参数,表示IP地址或域名</param>
        /// <returns></returns>
        public static bool PingIpOrDomainName(string strIpOrDName)
        {
            try

            {
                var objPingSender = new Ping();

                var objPinOptions = new PingOptions
                {
                    DontFragment = true
                };

                const string data = "";

                var buffer = Encoding.UTF8.GetBytes(data);

                const int intTimeout = 120;

                var objPinReply = objPingSender.Send(strIpOrDName, intTimeout, buffer, objPinOptions);

                var strInfo = objPinReply.Status.ToString();

                return strInfo == "Success";
            }
            catch (Exception)

            {
                return false;
            }
        }

        /// <summary>
        ///  获取设备IP检测结果
        /// </summary>
        /// <returns>设备IP检测结果</returns>
        [HttpGet]
        public List<DeviceIpTestResults> DeviceIpTest()
        {
            if (!ServiceHub.DeviceIPList.Any()) throw new Exception("未配置任何Ip");
            var deviceIpTestResults = new List<DeviceIpTestResults>();
            ServiceHub.DeviceIPList.ForEach(ip =>
            {
                deviceIpTestResults.Add(new DeviceIpTestResults
                {
                    Ip = ip,
                    Result = PingIpOrDomainName(ip)
                });
            });

            return deviceIpTestResults;
        }

        /// <summary>
        ///  获取设备Ip集合
        /// </summary>
        /// <returns>设备Ip集合</returns>
        [HttpGet]
        public List<string> GetDeviceIpList()
        {
            if (!ServiceHub.DeviceIPList.Any()) throw new Exception("未配置任何Ip");
            return ServiceHub.DeviceIPList;
        }

        #endregion 设备IP相关
    }
}
