using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using RestSharp;
using System.Net;
using Newtonsoft.Json.Linq;
using Common;
using Newtonsoft.Json;

namespace CommonEntity
{
    public class User
    {
        public string username { get; set; }
        public string password { get; set; }
        public int oauth_id { get; set; }
    }
    public class FCS_ReturnInfo
    {
        public int success { get; set; }
        public FCS_ReturnData data { get; set; }
    }
    // {"success": 1, "data": true, "rmsg": {"code": "s_job_orders", "param": ["JO-0001970-01"]}}
    public class FCS_JobResponse
    {
        public int success { get; set; }
        public bool data { get; set; }
        //"rmsg": 
        //[
        //{
        //    "code": "s_user_not_found",
        //    "param": []
        //}
        //]
        public List<FCSJobResponseData> rmsg { get; set; }

    }
    public class FCSJobResponseData
    {
        public string code { get; set; }
        public List<string> param { get; set; }
    }
    public class FCS_ReturnData
    {
        public bool is_authenticated { get; set; }
        public string access_token { get; set; }
        public string refresh_token { get; set; }
        public bool show_password_expire { get; set; }
        public string password_expired_date { get; set; }
        public bool password_expired { get; set; }
        public bool valid_license_access { get; set; }
        public bool require_reset { get; set; }
        public string property_config { get; set; }
        public string show_pp { get; set; }
        public int oauth_id { get; set; }
        public bool is_ip_valid { get; set; }
        public bool is_support_aliyun { get; set; }
    }

    public class FCS_JobRequest
    {
        public List<string> location_uuid { get; set; }
        public List<FCS_service_items> service_items { get; set; }
        public string remark { get; set; }
        public string assigned_to { get; set; }
        public int user_type { get; set; }
        public bool get_details { get; set; }
    }
    public class FCS_service_items
    {
        public string item_uuid { get; set; }
        public int quantity { get; set; }
    }
    public struct FCS_OrderData
    {
        public string LocationUUID { get; set; }
        public string ItemUUID { get; set; }
        public string PropertyID { get; set; }
        public string ItemType { get; set; }
        public string OrderUUID { get; set; }
        public string OrderNo { get; set; }
        public string HotelCode { get; set; }
        public string RoomNUMBER { get; set; }
        public string HostNUMBER { get; set; }
    }
    public class FCS_Response
    {
        public int success { get; set; }
        public List<FCS_R_DataItem> data { get; set; }
        public RMSG rmsg { get; set; }
    }
    public class FCS_R_DataItem
    {
        public string job_no { get; set; }
        public string job_status_colour { get; set; }
        public string job_uuid { get; set; }
    }
    public class RMSG
    {
        public string code { get; set; }
        public List<string> param { get; set; }
    }


    /// <summary>
    /// 查询 类
    /// </summary>
    public class QueryFCSOrder
    {
        public string filter { get; set; }
        public OrderQueryItem column_filter { get; set; }
    }
    public class OrderQueryItem
    {
        public string field { get; set; }
        public List<string> value { get; set; }
    }

    public class QueryOrderResponse
    {
        public string success { get; set; }
        public List<Dictionary<string, string>> data { get; set; }
        public object[] rmsg { get; set; }
    }

    public class RR
    {
        private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(RR));
        private static void SSLXieYi()
        {
            //ssl 协议不兼容
            var A = (SecurityProtocolType)48;
            var B = (SecurityProtocolType)192;
            var C = (SecurityProtocolType)768;
            var D = (SecurityProtocolType)3072;
            var E = (SecurityProtocolType)12288;
            ServicePointManager.SecurityProtocol = A | B | C | D | E;
        }
        public static void Login(string FCSLoginUrl, string FCSLoginUserName, string FCSLoginPassWord, string HotelCode, string RoomNum)
        {
            try
            {

                SSLXieYi();

                var client1 = new RestClient(FCSLoginUrl);
                var request1 = new RestRequest("/api/security/authenticate", Method.POST);

                Dictionary<string, string> dic = new Dictionary<string, string>();
                User us = new User();
                us.username = FCSLoginUserName;
                us.password = FCSLoginPassWord;
                us.oauth_id = 1;
                request1.AddJsonBody(us);


                Interface3Log w1 = new Interface3Log();
                w1.HotelCode = HotelCode;
                w1.RoomNumber = RoomNum;
                w1.TriggerTime = DateTime.Now;
                w1.ActionData = new HttpActionData() { RequestData = Newtonsoft.Json.JsonConvert.SerializeObject(dic) };
                w1.CommandType = ChangLiangValue.CommandType_FCS;

                var q1 = Newtonsoft.Json.JsonConvert.SerializeObject(w1);
                CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q1);

                var QQQ = client1.Execute(request1);
                HttpStatusCode HHH = QQQ.StatusCode;
                if (HHH == HttpStatusCode.Created || HHH == HttpStatusCode.OK)
                {
                    string ddd = QQQ.Content;

                    Interface3Log w2 = new Interface3Log();
                    w2.HotelCode = HotelCode;
                    w2.RoomNumber = RoomNum;
                    w2.TriggerTime = DateTime.Now;
                    w2.ActionData = new HttpActionData() { ResponseData = ddd };
                    w2.CommandType = ChangLiangValue.CommandType_FCS;

                    var q2 = Newtonsoft.Json.JsonConvert.SerializeObject(w2);
                    CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q2);

                    var FFFA = Newtonsoft.Json.JsonConvert.DeserializeObject<FCS_ReturnInfo>(ddd);

                    //string TokenKey = CacheKey.FCSToken;

                    string TokenKey = CacheKey.FCSToken + "_" + HotelCode;
                    CSRedisCacheHelper.Set_Partition(TokenKey, FFFA, 1);
                }
            }
            catch (Exception ex)
            {
                logger.Error("FCS Login Error" + ex.Message);
                logger.Error(ex.StackTrace);
            }

            //client1.ExecuteAsync(request1, (response) =>
            //{
            //    Console.WriteLine(response.Content);
            //});
        }


        public static void JobRequest(string AccessToken, string location_uuid, string item_uuid, string FCSLoginUrl, string UserName, string PassWord, string PropertyID, string code, string roomno, string remarkdata, string itemclass)
        {
            if (string.IsNullOrEmpty(item_uuid))
            {
                return;
            }


            SSLXieYi();

            var client1 = new RestClient(FCSLoginUrl);
            var request1 = new RestRequest("/api-secure/job/request", Method.POST);

            FCS_JobRequest fff = new FCS_JobRequest();
            fff.location_uuid = new List<string>() { location_uuid };
            fff.service_items = new List<FCS_service_items>() 
            { 
                new FCS_service_items()
                {
                    item_uuid=item_uuid,
                    quantity=1
                }
            };
            fff.remark = remarkdata;
            fff.assigned_to = "auto";
            fff.user_type = 1;
            fff.get_details = true;


            string WER = Newtonsoft.Json.JsonConvert.SerializeObject(fff);

            logger.Error("push data is " + WER);
            logger.Error("push token is " + AccessToken);
            request1.AddHeader("token", AccessToken);
            //下面这个是个定值
            request1.AddHeader("property", PropertyID);
            request1.AddParameter("payload", WER);

            Interface3Log w1 = new Interface3Log();
            w1.HotelCode = code;
            w1.RoomNumber = roomno;
            w1.TriggerTime = DateTime.Now;
            w1.ActionData = new HttpActionData() { RequestData = Newtonsoft.Json.JsonConvert.SerializeObject(WER) };
            w1.CommandType = ChangLiangValue.CommandType_FCS;

            var q1 = Newtonsoft.Json.JsonConvert.SerializeObject(w1);
            CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q1);

            client1.ExecuteAsync(request1, (QQQ) =>
                {
                    HttpStatusCode HHH = QQQ.StatusCode;

                    string FHS = QQQ.Content;

                    Interface3Log w2 = new Interface3Log();
                    w2.HotelCode = code;
                    w2.RoomNumber = roomno;
                    w2.TriggerTime = DateTime.Now;
                    w2.ActionData = new HttpActionData() { ResponseData = FHS };
                    w2.CommandType = ChangLiangValue.CommandType_FCS;

                    var q2 = Newtonsoft.Json.JsonConvert.SerializeObject(w2);
                    CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q2);

                    //{
                    //  "success": 1,
                    //  "data": [
                    //    {
                    //      "job_no": "JO-0004548-01",
                    //      "job_status_colour": "#FA8C16",
                    //      "job_uuid": "b1dcb088-6dbc-4ca5-a1c4-0a8b951113fd"
                    //    }
                    //  ],
                    //  "rmsg": {
                    //    "code": "s_job_orders",
                    //    "param": [
                    //      "JO-0004548-01"
                    //    ]
                    //  }
                    //}
                    logger.Error("PushData 返回值为:" + FHS);
                    logger.Error("PushData Status:" + HHH.ToString());
                    if (string.IsNullOrEmpty(FHS))
                    {
                        return; 
                    }
                    JObject jsonObject = JObject.Parse(FHS);
                    var error = jsonObject.SelectToken("error");
                    //如果有错
                    if (error != null)
                    {
                        Login(FCSLoginUrl, UserName, PassWord, code, roomno);
                    }
                    else
                    {
                        if (itemclass.Equals("Clean"))
                        {
                            logger.Error("写入订单"+FHS);
                            //FCS_Response
                            var FFF = JsonConvert.DeserializeObject<FCS_Response>(FHS);
                            var JJJ = FFF.data.FirstOrDefault();
                            if (JJJ != null)
                            {
                                string orderuuid = JJJ.job_uuid;
                                FCS_OrderData f = new FCS_OrderData();
                                f.OrderUUID = orderuuid;
                                f.PropertyID = PropertyID;
                                f.ItemType = "Clean";
                                f.OrderNo = JJJ.job_no;
                                f.ItemUUID = item_uuid;
                                f.LocationUUID = location_uuid;
                                f.HotelCode = code;
                                f.RoomNUMBER = roomno;
                                string fsa = Newtonsoft.Json.JsonConvert.SerializeObject(f);
                                //这个是 供轮循的时候调用使用
                                CSRedisCacheHelper.HMSet(3, 60 * 24, CacheKey.FCSOrder, Guid.NewGuid().ToString("N"), fsa);

                                //这个是供 取消订单的时候使用的
                                //这个只 支持 取消 清理
                                logger.Error("记录入循环:"+orderuuid);
                                CSRedisCacheHelper.Set_PartitionWithTime(CacheKey.FCSRoom_Mapping_Order + "_" + location_uuid, orderuuid, 24 * 60, 3);
                            }
                        }
                    }
                    if (HHH == HttpStatusCode.OK)
                    {
                    }
                });
        }
        /// <summary>
        /// FCS数据推送
        /// </summary>
        /// <param name="Item_UUID"></param>
        public static void FCS_PushData(string Item_UUID, string location_UUID, string PropertyUUID, string LoginUrl, string UserName, string PassWord, string code, string roomno, string remarkdata = "", string HOSTNUMBER = "")
        {
            try
            {
                if (string.IsNullOrEmpty(Item_UUID))
                {
                    return;
                }
                //logger.Error("FCS push data");
                if (!string.IsNullOrEmpty(location_UUID))
                {
                    //string Key = CacheKey.FCSToken;

                    string Key = CacheKey.FCSToken + "_" + code;
                    var TokenTakeOut = CSRedisCacheHelper.Get_Partition<FCS_ReturnInfo>(Key, 1);
                    if (TokenTakeOut == null)
                    {
                        logger.Error("FCS login");
                        RR.Login(LoginUrl, UserName, PassWord, code, roomno);
                    }
                    else
                    {
                        logger.Error("FCS push action data");

                        string ItemClass = "";
                        if (!string.IsNullOrEmpty(HOSTNUMBER))
                        {
                            ItemClass = "Clean";
                        }
                        logger.Error("FCS push action itemclass:" + ItemClass);
                        RR.JobRequest(TokenTakeOut.data.access_token, location_UUID, Item_UUID, LoginUrl, UserName, PassWord, PropertyUUID, code, roomno, remarkdata, ItemClass);

                        if (!string.IsNullOrEmpty(HOSTNUMBER))
                        {
                            string CleanTrigger = CacheKey.CleanFCS_TriggerCount + "_" + HOSTNUMBER;
                            CSRedisCacheHelper.Set_PartitionWithTime<int>(CleanTrigger, 1, 1);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error("FCS PushData Error: " + ex.Message);
            }
        }


        /// <summary>
        /// 取消Job
        /// </summary>
        /// <param name="AccessToken"></param>
        /// <param name="location_uuid"></param>
        /// <param name="item_uuid"></param>
        /// <param name="FCSLoginUrl"></param>
        /// <param name="UserName"></param>
        /// <param name="PassWord"></param>
        /// <param name="PropertyID"></param>
        /// <param name="HotelCode"></param>
        /// <param name="RoomNo"></param>
        /// <param name="remarkdata"></param>
        /// <param name="itemclass"></param>
        public static void JobCancelRequest(string AccessToken, string FCSLoginUrl, string PropertyID, string HotelCode, string RoomNo, string OrderId)
        {
            if (string.IsNullOrEmpty(OrderId))
            {
                return;
            }
            SSLXieYi();

            string RUrl = string.Format("/api-secure/job/order/{0}/cancelled", OrderId);
            var client1 = new RestClient(FCSLoginUrl);
            var request1 = new RestRequest(RUrl, Method.POST);

            logger.Error("push data is " + OrderId);
            logger.Error("push token is " + AccessToken);
            request1.AddHeader("token", AccessToken);
            //下面这个是个定值
            request1.AddHeader("property", PropertyID);

            Interface3Log w1 = new Interface3Log();
            w1.HotelCode = HotelCode;
            w1.RoomNumber = RoomNo;
            w1.TriggerTime = DateTime.Now;
            w1.ActionData = new HttpActionData() { RequestData = OrderId };
            w1.CommandType = ChangLiangValue.CommandType_FCS;

            var q1 = Newtonsoft.Json.JsonConvert.SerializeObject(w1);
            CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q1);

            client1.ExecuteAsync(request1, (QQQ) =>
                {
                    HttpStatusCode HHH = QQQ.StatusCode;

                    string FHS = QQQ.Content;
                    logger.Error("cancel PushData not data is" + FHS);

                    Interface3Log w2 = new Interface3Log();
                    w2.HotelCode = HotelCode;
                    w2.RoomNumber = RoomNo;
                    w2.TriggerTime = DateTime.Now;
                    w2.ActionData = new HttpActionData() { ResponseData = FHS };
                    w2.CommandType = ChangLiangValue.CommandType_FCS;

                    var q2 = Newtonsoft.Json.JsonConvert.SerializeObject(w2);
                    CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q2);

                });
        }
        public static void FCS_CancelOrderJob(string location_UUID, string PropertyUUID, string LoginUrl, string UserName, string PassWord, string code, string roomno, string OrderUUID = "")
        {
            try
            {
                if (string.IsNullOrEmpty(OrderUUID))
                {
                    return;
                }
                if (!string.IsNullOrEmpty(location_UUID))
                {
                    string Key = CacheKey.FCSToken;
                    var TokenTakeOut = CSRedisCacheHelper.Get_Partition<FCS_ReturnInfo>(Key, 1);
                    if (TokenTakeOut == null)
                    {
                        logger.Error("FCS login");
                        RR.Login(LoginUrl, UserName, PassWord, code, roomno);
                    }
                    else
                    {
                        logger.Error("FCS cancel push action data");
                        RR.JobCancelRequest(TokenTakeOut.data.access_token, LoginUrl, PropertyUUID, code, roomno, OrderUUID);
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error("FCS PushData Error: " + ex.Message);
            }
        }
    }
}
