using Nancy;
using Nancy.Bootstrapper;
using Nancy.Hosting.Self;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Model;
using WcfControlMonitorLib;
using System.Security.Cryptography;
using Nancy.Helpers;
using DBFactory;
using System.Data;
using System.Diagnostics.Eventing.Reader;

namespace WindowsFormsApp1
{
    public class APIChannel : NancyModule
    {
        static DBOperator dbo = CStaticClass.dbo;
        static DBOperator dboMan = CStaticClass.dboM;
        static String ERROR = String.Empty;
        private static NancyHost _server;
        static string address = CommonClassLib.AppSettings.GetValue("Serveradderss");
        //private static ServiceReference1.I_Managely5Client I_ManageClient = new ServiceReference1.I_Managely5Client();
        public static void Start()
        {
            //_server = new NancyHost(new Bootstrapper(), new Uri("http://192.168.39.10:8080"));
            _server = new NancyHost(new Bootstrapper(), new Uri(address));
            _server.Start();
        }
      
        public APIChannel()
        {

            Get["/"] = _ => "This is WCS APIServer";
            ////查询
            //Post["/api/BindTrayInfo/AgvGetBindTrayInfo", true] = async (x, ct) =>
            //{
            //    var body = this.Request.Body;
            //    int length = (int)body.Length; // this is a dynamic variable
            //    byte[] data = new byte[length];
            //    body.Read(data, 0, length);

            //    string jsonStr = System.Text.Encoding.Default.GetString(data);
            //    return "a";//I_ManageClient.HandleControlAGVQueryApplyYB(jsonStr);
            //};


            #region WMS调用, 在此处理,出库以及移库任务 多条任务   任务下发
            Post["/api/wcs/thirdParty/receiveWmsTask", true] = async (x, ct) =>
            {
                try
                {
                    var body = this.Request.Body;
                    int length = (int)body.Length;
                    byte[] data = new byte[length];
                    body.Read(data, 0, length);
                    string jsonStr = System.Text.Encoding.Default.GetString(data);
                    CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "收到报文", jsonStr.ToString(), "");

                    CCallService.WMS_WCS_PARAM_OUT_MOVE wms_wcs = Model.JsonHelper.Deserialize<CCallService.WMS_WCS_PARAM_OUT_MOVE>(jsonStr);
                    //  CCallService.WCS_WMS_PARAM_OUT_MOVE wcs_wms = new CCallService.WCS_WMS_PARAM_OUT_MOVE();  //返回的报文
                    CCallService.OUT_MOVE_RES answer_outdata = new CCallService.OUT_MOVE_RES();//返回数据
                    string err = string.Empty;
                    string returnJson = string.Empty;
                    DataView dv = new DataView();
                    CCallService.OUT_MOVE_RES outReturn = new CCallService.OUT_MOVE_RES();
                    if (wms_wcs != null)
                    {
                        List<CCallService.OUT_MOVE_DATA> outdata = wms_wcs.tasks; //任务信息
                        int isOk = 0;
                        // CCallService.OUT_MOVE_RES outReturn = new CCallService.OUT_MOVE_RES();
                        foreach (var task in outdata)
                        {                          

                            IO_CONTROL outtask = new IO_CONTROL(task, wms_wcs.msgTime, task.taskType, wms_wcs.priority.ToString());

                            if (outtask.Insert_IOCONTROL() == true)
                            {
                                outReturn.data += "ID'" + task.taskId.ToString() + "'任务正常:";
                            }
                            else
                            {
                                isOk++;
                                outReturn.data += "ID'" + task.taskId.ToString() + "'任务下发失败:";
                            }
                            if (isOk == 0)
                            {
                                outReturn.code = 0;
                                outReturn.msg = "";
                            }
                            else
                            {
                                outReturn.code = 1;
                                outReturn.msg = "任务接收失败";
                            }
                        }

                    }
                    returnJson = Model.JsonHelper.Serializer(outReturn);
                    CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "返回报文", returnJson, "");
                    return returnJson;
                }
                catch (Exception ex) {
                    string errorjson = Model.JsonHelper.Serializer(new
                    {
                        code =1,
                        msg = "WCS解析json异常",
                        data = ex.Message.ToString()
                    });
                    CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "返回报文", ex.Message.ToString(), "");
                    return errorjson;
                }
            };
            #endregion

            #region WMS调用, 在此处理,取消任务 单条形式
            Post["/api/wcs/thirdParty/cancelWmsTask", true] = async (x, ct) =>
            {
                var body = this.Request.Body;
                int length = (int)body.Length;
                byte[] data = new byte[length];
                body.Read(data, 0, length);
                string jsonStr = System.Text.Encoding.Default.GetString(data);
                CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "收到报文", jsonStr.ToString(), "");
                CCallService.WMS_WCS_PARAM_CANCEL wms_wcs_cancel = Model.JsonHelper.Deserialize<CCallService.WMS_WCS_PARAM_CANCEL>(jsonStr);
                CCallService.WCS_WMS_PARAM_CANCEL wcs_wms_cancel = new CCallService.WCS_WMS_PARAM_CANCEL();  //返回的报文
                string err = string.Empty;
                string returnJson = string.Empty;
                DataView dv = new DataView();        

                if (wms_wcs_cancel != null)
                {
                    switch (wms_wcs_cancel.method)
                    {

                        case "wms_request_cancel": //WMS取消任务

                            CCallService.CANCEL_DATA canceldata = new CCallService.CANCEL_DATA();
                            canceldata = wms_wcs_cancel.data;
                            CCallService.CANCEL_RES_DATA cancelReturn = new CCallService.CANCEL_RES_DATA();
                            string sql = "select * from t_manage_task where FID = '" + canceldata.taskId + "' and FPALLETBARCODE = '" + canceldata.containerCode + "'";
                            dv = dbo.ExceSQL(sql).Tables[0].DefaultView;
                            if (dv.Count == 1)
                            {

                                int stepOk = Convert.ToInt32(dv[0]["FIntoStepOK"]);
                                if (stepOk == 0)
                                {
                                    try
                                    {
                                        sql = "delete from t_manage_task where FMANAGEID = '" + canceldata.taskId + "' and FPALLETBARCODE = '" + canceldata.containerCode + "'";
                                        int count = dbo.ExecuteSql(sql);
                                        if (count > 0)
                                        {
                                            cancelReturn.code = "00";
                                            cancelReturn.msg = "取消任务成功!";
                                            cancelReturn.taskId = cancelReturn.taskId;
                                        }
                                        else
                                        {
                                            cancelReturn.code = "01";
                                            cancelReturn.msg = "取消任务失败,WCS无法删除任务!";
                                            cancelReturn.taskId = cancelReturn.taskId;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        cancelReturn.code = "01";
                                        cancelReturn.msg = "取消任务失败,WCS无法删除任务!";
                                        cancelReturn.taskId = cancelReturn.taskId;
                                    }
                                }
                                else
                                {
                                    cancelReturn.code = "01";
                                    cancelReturn.msg = "取消任务失败,任务已执行!";
                                    cancelReturn.taskId = cancelReturn.taskId;
                                }

                            }
                            else if (dv.Count == 0)
                            {
                                cancelReturn.code = "00";
                                cancelReturn.msg = "取消任务成功,WCS中无此任务!" + canceldata.taskId;
                                cancelReturn.taskId = cancelReturn.taskId;

                            }
                            else
                            {
                                cancelReturn.code = "01";
                                cancelReturn.msg = "取消任务失败,WCS中有多条相同任务!相同的条码:" + canceldata.containerCode;
                                cancelReturn.taskId = cancelReturn.taskId;
                            }
                            wcs_wms_cancel.data = cancelReturn;
                            wcs_wms_cancel.timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                            wcs_wms_cancel.method = wms_wcs_cancel.method;
                            break;


                        default:

                            string errorjson = Model.JsonHelper.Serializer(new
                            {
                                method = wms_wcs_cancel.method,
                                timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                data = new
                                {
                                    code = "11",
                                    msg = "WCS解析jason异常"
                                }
                            });
                            CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "返回报文", errorjson, "");
                            return errorjson;
                    }

                }


                returnJson = Model.JsonHelper.Serializer(wcs_wms_cancel);
                CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "返回报文", returnJson, "");
                return returnJson;
            };
            #endregion

            #region test
            //Post["/STATUS", true] = async (x, ct) =>
            //{
            //    var body = this.Request.Body;
            //    int length = (int)body.Length;
            //    byte[] data = new byte[length];
            //    body.Read(data, 0, length);
            //    string jsonStr = System.Text.Encoding.Default.GetString(data);
            //    CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "收到报文", jsonStr.ToString(), "");

            //    CCallService.WMS_WCS_111 wms_wcs = Model.JsonHelper.Deserialize<CCallService.WMS_WCS_111>(jsonStr);
            //    CCallService.WCS_WMS_111 wcs_wms = new CCallService.WCS_WMS_111();  //返回的报文

            //    string err = string.Empty;
            //    string returnJson = string.Empty;
            //    DataView dv = new DataView();
            //    if (wms_wcs != null)
            //    {
            //        switch (wms_wcs.method)
            //        {
            //            case "wcs_stack_status"://WMS出库任务   


            //                List<CCallService.STATUS_111> outdata = wms_wcs.data;
            //                List<CCallService.OUT_MOVE_RES> answer_outdata = new List<CCallService.OUT_MOVE_RES>();
            //                foreach (var item in outdata)
            //                {
            //                    string a = item.battery;
            //                    string b = item.stackindex;

            //                    //IO_CONTROL outtask = new IO_CONTROL(item, wms_wcs.timestamp, 2);
            //                    //CCallService.OUT_MOVE_RES outReturn = new CCallService.OUT_MOVE_RES();
            //                    //if (outtask.Insert_IOCONTROL() == true)
            //                    //{
            //                    //    outReturn.code = "00";
            //                    //    outReturn.msg = "出库任务接收成功";
            //                    //    outReturn.taskId = item.taskId.ToString();
            //                    //}
            //                    //else
            //                    //{
            //                    //    outReturn.code = "01";
            //                    //    outReturn.msg = "出库任务接收失败!" + outtask.error_code;
            //                    //    outReturn.taskId = item.taskId.ToString();
            //                    //}
            //                    //answer_outdata.Add(outReturn);


            //                }
            //                wcs_wms.data = answer_outdata;
            //                wcs_wms.timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            //                wcs_wms.method = wms_wcs.method;
            //                break;



            //            default:

            //                string errorjson = Model.JsonHelper.Serializer(new
            //                {
            //                    method = wms_wcs.method,
            //                    timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
            //                    data = new
            //                    {
            //                        code = "11",
            //                        msg = "WCS解析jason异常"
            //                    }
            //                });
            //                CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "返回报文", errorjson, "");
            //                return errorjson;
            //        }

            //    }
            //    returnJson = Model.JsonHelper.Serializer(wcs_wms);
            //    CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "返回报文", returnJson, "");
            //    return returnJson;
            //};
            #endregion

        }


        #region 向 IO_CONTROL 插入出库倒库任务等 
        public class IO_CONTROL
        {
            string wms_id;
            int relative_id;
            string barcode;
            string startdevice;
            string enddevice;
            string begintime;
            int control_type;
            string warehouse ="1";
            string tasklevel;
            public StringBuilder error_code = new StringBuilder();

            StringBuilder sql = new StringBuilder();

            public IO_CONTROL(CCallService.OUT_MOVE_DATA outdata, string time,int controltype,string level)//出库 移库
            {
                error_code.Clear();
                wms_id = outdata.taskId;
                relative_id = -1;
                barcode = outdata.containerCode;
                if (outdata.taskType == 2 || outdata.taskType == 3)
                { //起点是库位
                    startdevice = outdata.startRow.ToString("D2") + "-" + outdata.startColumn.ToString("D2") + "-" + outdata.startLayer.ToString("D2");
                    enddevice = outdata.endNode;
                }
                else if(outdata.taskType == 1 || outdata.taskType == 4) //终点是库位
                {
                    startdevice = outdata.startNode;
                    enddevice = outdata.endRow.ToString("D2") + "-" + outdata.endColumn.ToString("D2") + "-" + outdata.endLayer.ToString("D2");
                }
                control_type = controltype;
                string dTime1 = DateTime.Now.ToString("u");
                begintime = dTime1.Substring(0, dTime1.Length - 1);
                tasklevel = level;
              
            }
            public IO_CONTROL(CCallService.IN_DATA indata, string time)//入库
            {
                error_code.Clear();
                wms_id = indata.taskId;
                relative_id = -1;
                barcode = indata.containerCode;
                startdevice = indata.sourceAddress;
                enddevice = indata.targetAddress;
                control_type = 1;
                string dTime1 = DateTime.Now.ToString("u");
                begintime = dTime1.Substring(0, dTime1.Length - 1);
                tasklevel = indata.tasklevel;
            }

            //检查参数是否正确
            bool CheckData()
            {
                Dictionary<string, WEBAPI_CKECKING> all_checking = new Dictionary<string, WEBAPI_CKECKING>();

                #region 从数据库中读取要检测的SQL
                sql.Clear();
                sql.Append("select * from WEBAPI_CKECKING");
                DataView dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;
                for(int i=0; i<dv.Count; i++)
                {
                    WEBAPI_CKECKING wac = new WEBAPI_CKECKING();
                   
                    wac.check_id = dv[i]["CKECK_ID"].ToString();
                    wac.check_name = dv[i]["CKECK_NAME"].ToString();
                    wac.sql = dv[i]["SQL"].ToString();
                    wac.des = dv[i]["DESCRIPTION"].ToString();

                    all_checking.Add(wac.check_name, wac);
                }
                #endregion

                error_code.Clear();

                #region 检查是否重复,CONTROL_ID, 托盘码重复, 起始货位重复,终止货位重复(结果大于零)

                sql.Clear();
                sql.Append(string.Format(all_checking["CONTROL_ID_REPEAT"].sql, wms_id));
                if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count > 0)
                {
                    error_code.Append(";").Append(all_checking["CONTROL_ID_REPEAT"].des);  //fid重复
                }

                //sql.Clear();
                //sql.Append(string.Format(all_checking["BARCODE_REPEAT"].sql, barcode));
                //if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count > 0)
                //{
                //    error_code.Append(";").Append(all_checking["BARCODE_REPEAT"].des);  //托盘条码重复
                //}
                if (string.IsNullOrEmpty(tasklevel))
                {
                    error_code.Append(";").Append("任务优先级为空");
                }
                if (string.IsNullOrEmpty(wms_id))
                {
                    error_code.Append(";").Append("任务号为空");
                }
                if (string.IsNullOrEmpty(barcode))
                {
                    error_code.Append(";").Append("条码为空");
                }

                if (int.TryParse(this.wms_id, out int controlid) == false)
                {
                    error_code.Append(";").Append(all_checking["CONTROL_ID_NOT_NUM"].des);  //controlid不为数字
                }


                if (control_type == 2 )//出库任务
                {

                    sql.Clear();
                    sql.Append(string.Format(all_checking["START_CEEE_REPEAT"].sql, startdevice, control_type));
                    if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count > 0)
                    {
                        error_code.Append(";").Append(all_checking["START_CEEE_REPEAT"].des);  //起始货位重复
                    }
                    if (this.startdevice.Length != 8)
                    {
                        error_code.Append(";").Append("起点").Append(all_checking["CELL_LENGTH_ERROR"].des);  //起点货位编码长度错误
                    }
                    sql.Clear();
                    sql.Append(string.Format(all_checking["CELL_NOT_EXIST"].sql, startdevice));
                    if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0)
                    {
                        error_code.Append(";").Append("起点").Append(all_checking["CELL_NOT_EXIST"].des);  //起点货位不存在

                    }

                    int endGate = 0;
                    if (int.TryParse(this.enddevice, out endGate) == false)
                    {
                        error_code.Append(";").Append(all_checking["END_GATE_ERROR"].des);  //终点站台不正确,无法转为整数
                    }

                    sql.Clear();
                    sql.Append(string.Format(all_checking["END_GATE_NOT_EXIST"].sql, enddevice));
                    if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0)
                    {
                        error_code.Append(";").Append(all_checking["END_GATE_NOT_EXIST"].des);  //终点站台不存在
                    }

                }

                if (control_type == 1)//入库任务
                {
                    sql.Clear();
                    sql.Append(string.Format(all_checking["END_CEEE_REPEAT"].sql, enddevice, control_type));
                    if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count > 0)
                    {
                        error_code.Append(";").Append(all_checking["END_CEEE_REPEAT"].des);  //终点货位重复
                    }
                    if (this.enddevice.Length != 8 )
                    {
                        error_code.Append(";").Append("终点").Append(all_checking["CELL_LENGTH_ERROR"].des);  //终点货位编码长度错误
                    }

                    sql.Clear();
                    sql.Append(string.Format(all_checking["CELL_NOT_EXIST"].sql, enddevice));
                    if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0)
                    {
                        error_code.Append(";").Append("终点").Append(all_checking["CELL_NOT_EXIST"].des);  //终点货位不存在
                    }
                    sql.Clear();
                    sql.Append(string.Format(all_checking["START_GATE_NOT_EXIST"].sql, startdevice));
                    if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0)
                    {
                        error_code.Append(";").Append(all_checking["START_GATE_NOT_EXIST"].des);  //起点站台不存在
                    }
                }

                if (control_type == 3) //移库任务
                {
                    if (this.startdevice.Length != 8)
                    {
                        error_code.Append(";").Append("起点").Append(all_checking["CELL_LENGTH_ERROR"].des);  //终点货位编码长度错误
                    }
                    if (this.enddevice.Length != 8 )
                    {
                        error_code.Append(";").Append("终点").Append(all_checking["CELL_LENGTH_ERROR"].des);  //终点货位编码长度错误
                    }

                    sql.Clear();
                    sql.Append(string.Format(all_checking["CELL_NOT_EXIST"].sql, startdevice));
                    if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0)
                    {
                        error_code.Append(";").Append("起点").Append(all_checking["CELL_NOT_EXIST"].des);  //起点货位不存在

                    }
                    sql.Clear();
                    sql.Append(string.Format(all_checking["CELL_NOT_EXIST"].sql, enddevice));
                    if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0)
                    {
                        error_code.Append(";").Append("终点").Append(all_checking["CELL_NOT_EXIST"].des);  //终点货位不存在
                    }

                    //移库任务如果不同层,校验不要移
                    if (startdevice.Substring(6, 2) != enddevice.Substring(6, 2))
                    {
                        error_code.Append(";").Append("移库任务起点终点层值不同");
                    }
                    if (startdevice == enddevice)
                    {
                        error_code.Append(";").Append("移库任务起点终点相同");
                    }

                }

                #endregion

                //检查托盘码

                if (error_code.Length == 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            
            //
            public bool Insert_IOCONTROL()
            {
                if (CheckData() == true)
                {
                    try
                    {
                        sql.Clear();
                        sql.Append(string.Format("INSERT INTO IO_CONTROL (CONTROL_ID, RELATIVE_CONTROL_ID, MANAGE_ID, STOCK_BARCODE, CONTROL_TASK_TYPE, CONTROL_TASK_LEVEL, START_WAREHOUSE_CODE, START_DEVICE_CODE, END_WAREHOUSE_CODE, END_DEVICE_CODE, CONTROL_BEGIN_TIME,CONTROL_STATUS) " +
                            "VALUES( {0},'{1}','{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}',{11})",
                            wms_id, -1, 0, barcode, control_type, tasklevel, warehouse, startdevice, warehouse, enddevice, begintime,0));
                        dbo.ExceSQL(sql.ToString());
                        return true;
                    }
                    catch(Exception ex)
                    {
                        error_code.Append("WCS插入IO_ONTROL表失败!");
                        return false;
                    }
                }
                
                return false;
            }

           
        }
        #endregion

        
       // public static  Dictionary<string, WEBAPI_CKECKING> all_checking = new Dictionary<string, WEBAPI_CKECKING>();

        public class WEBAPI_CKECKING
        {
            public string check_id;
            public string check_name;
            public string sql;
            public string des;
        }

        public class Bootstrapper : DefaultNancyBootstrapper
        {
            /// <summary>
            /// Register only NancyModules found in this assembly
            /// </summary>
            protected override IEnumerable<ModuleRegistration> Modules
            {
                get
                {
                    return GetType().Assembly.GetTypes().Where(type => type.BaseType == typeof(NancyModule)).Select(type => new ModuleRegistration(type));
                }
            }
        }
    }
}