using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;
using System.Web.Security;
using System.Web.SessionState;
using System.Web.Http;
using System.Xml.Linq;
using System.Threading.Tasks;
using RestSharp;
using System.Configuration;
using Newtonsoft.Json;
using BLWWS.PMS;
using System.Collections.Concurrent;
using BLWWS.PMS.Common;
using Microsoft.Extensions.Logging;
using NLog;
using System.IO;
using System.Text;
using Quartz.Impl;
using Quartz;
using MoNi_QianLiMa.Job;

namespace MyQianLiMa
{
    public class Global : HttpApplication
    {
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();
        public static ConcurrentDictionary<string, string> GlobalData { get; }
            = new ConcurrentDictionary<string, string>();

        System.Timers.Timer timer;
        System.Timers.Timer token_timer;
        void Application_Start(object sender, EventArgs e)
        {
            // 在应用程序启动时运行的代码
            GlobalConfiguration.Configure(WebApiConfig.Register);

            try
            {
                string filepath = Server.MapPath("config.json");
                string str = File.ReadAllText(filepath, Encoding.UTF8);
                var d = JsonConvert.DeserializeObject<ConfigData>(str);
                Application.Add("config", d);

                //获取token数据
                //token_timer = new System.Timers.Timer();
                //token_timer.Interval = 30 * 60 * 1000;
                //token_timer.Elapsed += Token_timer_Elapsed; ;
                //token_timer.Start();

                GetTokenData().Wait();

                //获取实际上的数据
                timer = new System.Timers.Timer();
                timer.Interval = 30 * 1000;
                timer.Elapsed += Timer_Elapsed;
                timer.Start();

            }
            catch (Exception ex)
            {
                _logger.Error("Application_start: " + ex.Message);
            }

            try
            {
                StdSchedulerFactory factory = new StdSchedulerFactory();
                IScheduler scheduler = factory.GetScheduler().Result;//Scheduler:调度程序


                // 启动任务调度器
                scheduler.Start().Wait();
                string jobKey = "Get_Token";
                IJobDetail jobDetail = JobBuilder.Create<GetTokenJob>()
                     .WithIdentity(jobKey)
                     .UsingJobData("RequestUrl", "nouser")
                     .Build();

                ITrigger trigger = TriggerBuilder.Create()
                    .WithIdentity("GetTokenData")
                    .StartNow()
                    .WithSimpleSchedule(x =>
                    {
                        x.WithIntervalInMinutes(20).RepeatForever();
                        //x.WithIntervalInSeconds(5).RepeatForever();
                        //x.WithIntervalInHours(1).RepeatForever();
                    })
                    .Build();

                scheduler.ScheduleJob(jobDetail, trigger).Wait();

            }
            catch (Exception ex)
            {
                _logger.Error("Application_start: " + ex.Message);
            }
        }




        public static string BaseUrl = ConfigurationManager.AppSettings["qianlima_httpurl"];
        public static string UserCode = ConfigurationManager.AppSettings["UserCode"];
        public static string UserKey = ConfigurationManager.AppSettings["UserKey"];
        private static readonly string _key = ConfigurationManager.AppSettings["key"];
        public static string qianlima_orgUnitNo = ConfigurationManager.AppSettings["qianlima_orgUnitNo"];

        private async void Token_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                await GetTokenData();
            }
            catch (Exception ex)
            {
                _logger.Error("GetToken: " + ex.Message);
            }
        }

        public static string QianLiMa_LoginToken = "qianlima_token";

        public static string QianLiMa_DingDan = "qianlima_order";
        public async Task GetTokenData()
        {
            //Dictionary<string, string> Params = new Dictionary<string, string>();
            //Params.Add("userCode", UserCode);
            //Params.Add("key", UserKey);
            //var tokenstr = await Send_Http_Request_Params("/iPMSAPI/iPMSApiService/api/applySecurityToken", Params);
            //if (!string.IsNullOrEmpty(tokenstr))
            //{
            //    var dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(tokenstr);
            //    string token = dic["securityToken"];
            //    Application.Add(QianLiMa_LoginToken, token);
            //}
            string token = await GetToken_G();
            if (!string.IsNullOrEmpty(token))
            {
                GlobalData.AddOrUpdate(QianLiMa_LoginToken, token, (k, v) =>
                {
                    return token;
                });
                //Application.Add(QianLiMa_LoginToken, token);
            }
        }
        public static async Task<string> GetToken_G()
        {
            Dictionary<string, string> Params = new Dictionary<string, string>();
            Params.Add("userCode", UserCode);
            Params.Add("key", UserKey);

            var tokenstr = await Send_Http_Request_Params("/iPMSAPI/iPMSApiService/api/applySecurityToken", Params);

            if (!string.IsNullOrEmpty(tokenstr))
            {
                var dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(tokenstr);
                string token = dic["securityToken"];
                return token;
            }
            return "";
        }


        /// <summary>
        /// 获取千里马的数据
        /// </summary>
        /// <returns></returns>
        public async Task GetHotelData()
        {
            try
            {
                ConfigData data = null;
                object OOO = Application["config"];
                if (OOO != null)
                {
                    data = OOO as ConfigData;
                }

                if (data == null)
                {
                    return;
                }
                foreach (var HHH in data.DuiJieInfos)
                {
                    string code = HHH.hotel_code;
                    RData r = new RData();

                    QHotelData h = new QHotelData();
                    h.hostName = "Stephen-PC";
                    h.lang = "zh-CN";
                    h.optCode = UserCode;
                    h.userCode = UserCode;

                    h.orgUnitNo = qianlima_orgUnitNo;
                    h.productCode = "zh-CN";
                    //object ooo = Application[QianLiMa_LoginToken];

                    string ooo = "";
                    GlobalData.TryGetValue(QianLiMa_LoginToken, out ooo);
                    if (string.IsNullOrEmpty(ooo))
                    {
                        return;
                    }
                    h.securityToken = ooo;

                    ParamsData paramsData = new ParamsData();
                    //paramsData.gstStat = "默认查在住状态";

                    r.@params = paramsData;
                    r.integratedRequest = h;


                    var tokenstr = await Send_Http_Request_Json("iPMSAPI/iPMSApiService/api/queryInHouseList", r);
                    _logger.Error("获取到千里马酒店的数据为：" + tokenstr);
                    if (!string.IsNullOrEmpty(tokenstr))
                    {
                        var dic = JsonConvert.DeserializeObject<QianLiMaReturnInfo>(tokenstr);
                        var ll = dic.resultList;

                        var T = new List<Tuple<int, string, string, string, string, string>>();
                        foreach (CustomerData item in ll)
                        {
                            var tu = new Tuple<int, string, string, string, string, string>(
                                    item.accid,
                                    item.docno,
                                    item.doctype,
                                    item.gstTel,
                                    item.gstname,
                                    item.rmno
                                );
                            T.Add(tu);
                        }
                        var U = CSRedisCacheHelper.Get<List<Tuple<int, string, string, string, string, string>>>(QianLiMa_DingDan);
                        if (U == null)
                        {
                            CSRedisCacheHelper.Set(QianLiMa_DingDan, T);
                        }
                        else
                        {
                            var Take_T = U as List<Tuple<int, string, string, string, string, string>>;

                            //开房的
                            var NewAdd = T.Except(Take_T);

                            string errormsg = "";
                            if (NewAdd.Count() > 0)
                            {
                                foreach (var item in NewAdd)
                                {
                                    //item.accid,
                                    //item.docno,
                                    //item.doctype,
                                    //item.gstTel,
                                    //item.gstname,
                                    //item.rmno
                                    string ti = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                                    string tj = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd HH:mm:ss");

                                    string Item2 = item.Item2;
                                    if (string.IsNullOrEmpty(item.Item2))
                                    {
                                        Item2 = "";
                                    }

                                    string Item5 = item.Item5;
                                    if (string.IsNullOrEmpty(item.Item5))
                                    {
                                        Item5 = "";
                                    }
                                    string xmldata = XmlGenerate(item.Item1, Item2, Item5, ti, tj);

                                    _logger.Error("检测到开房：" + item.Item1 + " RoomNo:" + item.Item6);
                                    b.CheckIn(_key, code, item.Item6, DateTime.Now, xmldata, ref errormsg, "", Item2);
                                    _logger.Error("检测到开房：errormsg: " + errormsg);
                                }
                            }

                            //退房的
                            var CheckOut = Take_T.Except(T);
                            if (CheckOut.Count() > 0)
                            {
                                foreach (var item in CheckOut)
                                {
                                    _logger.Error("检测到退房,RoomNo:" + item.Item6);
                                    b.CheckOut(_key, code, item.Item6, DateTime.Now, ref errormsg);
                                    _logger.Error("检测到退房,error:" + errormsg);
                                }
                            }

                            CSRedisCacheHelper.Set(QianLiMa_DingDan, T);
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Error("GetHotelData: " + ex.Message);
                _logger.Error("GetHotelData: " + ex.StackTrace);
            }
        }

        /// <summary>
        /// 发送json数据
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="json"></param>
        /// <returns></returns>
        public static async Task<string> Send_Http_Request_Json(string Url, object json)
        {
            var client1 = new RestClient(BaseUrl);
            //var client1 = new RestClient("http://localhost:5132");
            var request1 = new RestRequest(Url, Method.POST);

            request1.AddJsonBody(json);

            var response = client1.Execute(request1);
            var content = response.Content;
            return content;
        }

        /// <summary>
        /// 发送url编码数据
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="Params"></param>
        /// <returns></returns>
        public static async Task<string> Send_Http_Request_Params(string Url, Dictionary<string, string> Params)
        {
            var client1 = new RestClient(BaseUrl);
            var request1 = new RestRequest(Url, Method.POST);

            foreach (KeyValuePair<string, string> item in Params)
            {
                request1.AddParameter(item.Key, item.Value);
            }

            var response = client1.Execute(request1);
            var content = response.Content;
            return content;
        }

        private ServiceReference1.blwwsSoapClient b = new ServiceReference1.blwwsSoapClient();
        private async void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                timer.Stop();
                await GetHotelData();
                timer.Start();
            }
            catch (Exception ex)
            {
                _logger.Error("GetHotelData: " + ex.Message);
            }
        }

        //<interface orderno= 入 住 单 号
        //    cost= 费 用
        //    roomtype= 房 型
        //    breakfast=1(是否含早) occupancy=入住人数 deposit=押金 >
        //        <item
        //    idtype="0" //0 身份证，1 护照，2 军官证，3 其他
        //    idcard="441323xxxxxxxxxxxx" //证件号
        //    customer="张三" //姓名
        //    sex="男" //性别：男、女
        //    country="0" //0 国内，1 国际
        //    checkindate="2015-07-01 13:45:20" /> //入住日期
        //    checkoutdate="2015-07-02 13:45:20" /> //离店日期
        //</interface>
        public string XmlGenerate(decimal orderno, string idcardno, string customername, string checkintdatetime, string checkoutdatetime)
        {
            XElement xelement = new XElement("interface",
                 new XAttribute[]
                 {
                    new XAttribute("orderno",orderno),
                    new XAttribute("cost","100"),
                    new XAttribute("roomtype",""),
                    new XAttribute("breakfast",""),
                    new XAttribute("occupancy",""),
                    new XAttribute("deposit","")
                 },
                 new XElement("item",
                     new XAttribute[]
                     {
                        new XAttribute("idtype", "0"),
                        new XAttribute("idcard", idcardno),
                        new XAttribute("customer", customername),
                        new XAttribute("sex", "1"),
                        new XAttribute("country", "1"),
                        new XAttribute("checkindate", checkintdatetime),
                        new XAttribute("checkoutdate",checkoutdatetime)
                     })
                 );
            string hhh = xelement.ToString();
            return hhh;
        }

    }
}