using System;
using System.Linq;
using System.Data;
using System.Threading;
using Library;
using LitJson;
using MySystem.Models.Push;
using System.Collections.Generic;

namespace MySystem
{   
    public class PushHelper
    {
        public readonly static PushHelper Instance = new PushHelper();
        private PushHelper()
        {
        }

        public void Start()//启动
        {
            Thread thread = new Thread(threadStart);
            thread.IsBackground = true;
            thread.Start();
        }

        private void threadStart()
        {
            while (true)
            {
                try
                {
                    DoSomeThing();
                }
                catch(Exception ex)
                {
                    Utils.WriteLog(DateTime.Now.ToString() + "\n" + ex.ToString(), "通用推送日志异常");
                }
                Thread.Sleep(120000);
            }
        }

        //要执行的方法
        public void DoSomeThing()
        {
            WebCMSEntities db = new WebCMSEntities();
            //查找开通推送的商户
            var merchants = db.Merchant.Where(m => m.Status == 1).ToList();
            foreach(var merchant in merchants)
            {
                string RsaPubKey = merchant.RsaPubKey;
                string RsaPriKey = merchant.RsaPriKey;
                string AesSecret = merchant.AesSecret;
                string MerchantNo = merchant.MerchantNo;
                string MerchantName = merchant.MerchantName;

                //查找商户开通的推送项目
                var pushObj = db.PushObj.Where(m => m.Status == 1 && m.MerchantId == merchant.Id).ToList();
                foreach(var pushItem in pushObj)
                {
                    string FieldList = pushItem.FieldList;
                    string TableName = pushItem.TableName;
                    TableName = SourceHelper.Instance.MatchExpressionVal(TableName);
                    int EncryptMode = pushItem.EncryptMode;
                    string NoticeUrl = pushItem.NoticeUrl;
                    string Title = pushItem.Title;
                    int MerchantId = pushItem.MerchantId;

                    string QueryField = "";
                    List<string> PushField = new List<string>();
                    Dictionary<string, string> Trans = new Dictionary<string, string>();
                    JsonData fieldJson = JsonMapper.ToObject(FieldList);
                    for (int i = 0; i < fieldJson.Count; i++)
                    {
                        JsonData item = fieldJson[i];
                        if(!string.IsNullOrEmpty(item["name"].ToString())) QueryField += item["name"].ToString() + ",";
                        if(item["push"].ToString() == "1")
                        {
                            PushField.Add(item["name"].ToString());
                            Trans.Add(item["name"].ToString(), item["trans"].ToString());
                        }
                    }

                    //构造抓取数据sql
                    string sql = "select " + QueryField.TrimEnd(',') + " from u_" + TableName + " where 1=1";
                    var condiList = db.PushObjCondition.Where(m => m.PushObjId == pushItem.Id).ToList();
                    foreach(var condi in condiList)
                    {
                        int QueryCondition = condi.QueryCondition;
                        if(QueryCondition == 1)
                        {
                            sql += " and " + condi.QueryField + "='" + condi.QueryVal + "'";
                        }
                        else if(QueryCondition == 2)
                        {
                            sql += " and " + condi.QueryField + " like '%" + condi.QueryVal + "%'";
                        }
                        else if(QueryCondition == 3)
                        {
                            sql += " and " + condi.QueryField + ">" + condi.QueryVal + "";
                        }
                        else if(QueryCondition == 4)
                        {
                            sql += " and " + condi.QueryField + "<" + condi.QueryVal + "";
                        }
                        else if(QueryCondition == 5)
                        {
                            string[] QueryValList = condi.QueryVal.Split('|');
                            sql += " and " + condi.QueryField + ">=" + QueryValList[0] + " and " + condi.QueryField + "<=" + QueryValList[1] + "";
                        }
                        else if(QueryCondition == 6)
                        {
                            string[] QueryValList = condi.QueryVal.Split('|');
                            sql += " and " + condi.QueryField + ">='" + QueryValList[0] + "' and " + condi.QueryField + "<='" + QueryValList[1] + "'";
                        }
                        else if(QueryCondition == 7)
                        {
                            sql += " and " + condi.QueryField + " in (" + condi.QueryVal + ")";
                        }
                        else if(QueryCondition == 8)
                        {
                            sql += " and " + condi.QueryField + " in ('" + condi.QueryVal.Replace(",", "','") + "')";
                        }
                        else if(QueryCondition == 9)
                        {
                            string[] QueryValList = condi.QueryVal.Split(',');
                            sql += " and (";
                            int index = 0;
                            foreach(string QueryVal in QueryValList)
                            {
                                index += 1;
                                sql += condi.QueryField + "=" + QueryVal;
                                if(index < QueryValList.Length)
                                {
                                    sql += " or ";
                                }
                            }
                            sql += ")";
                        }
                        else
                        {
                            sql += " and " + condi.QueryField + "='" + condi.QueryVal + "'";
                        }
                    }

                    //抓取数据开始post数据
                    int StartId = pushItem.QueryId;
                    sql = sql.Replace("${QueryId}$", StartId.ToString());
                    sql += " order by id limit 10";
                    DataTable dt = CustomerSqlConn.dtable(sql, AppConfig.Base.SqlConnStr);
                    foreach(DataRow dr in dt.Rows)
                    {
                        SortedList<string, string> obj = new SortedList<string, string>();
                        foreach(DataColumn dc in dt.Columns)
                        {
                            if(PushField.Contains(dc.ColumnName))
                            {
                                string val = dr[dc.ColumnName].ToString();
                                string tran = Trans[dc.ColumnName];
                                if(!string.IsNullOrEmpty(val))
                                {
                                    if(!string.IsNullOrEmpty(tran))
                                    {
                                        if(tran.StartsWith("*"))
                                        {
                                            decimal num = decimal.Parse(val) * int.Parse(tran.Substring(1));
                                            val = num.ToString("f0");
                                        }
                                    }
                                    if(dc.DataType == typeof(DateTime))
                                    {
                                        val = DateTime.Parse(val).ToString("yyyy-MM-dd HH:mm:ss");
                                    }
                                    obj.Add(dc.ColumnName, val);
                                }
                            }
                        }
                        int Status = 0;
                        string PushData = "";
                        string PushDataEncrypt = "";
                        if(EncryptMode == 1)
                        {
                            string noticeId = Guid.NewGuid().ToString();
                            if(obj.ContainsKey("order_id"))
                            {
                                noticeId = obj["order_id"];
                            }
                            PushData = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
                            LogHelper.Instance.WriteLog("原始数据：" + PushData, "推送数据日志");
                            string content = EncryptHelper.Encrypt1(obj, AesSecret);
                            LogHelper.Instance.WriteLog("加密数据：" + content, "推送数据日志");
                            obj = new SortedList<string, string>();
                            obj.Add("type", Title);
                            obj.Add("notice_id", noticeId);
                            obj.Add("timestamp", DateTime.Now.ToString("yyyyMMddHHmmssfff") + function.get_Random(8));
                            obj.Add("content", content);
                            string requestJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
                            PushDataEncrypt = requestJson;
                            LogHelper.Instance.WriteLog("请求参数：" + PushDataEncrypt, "推送数据日志");
                            LogHelper.Instance.WriteLog("请求地址：" + NoticeUrl, "推送数据日志");
                            string result = function.PostWebRequest(NoticeUrl, requestJson, "application/json");
                            LogHelper.Instance.WriteLog("返回报文：" + result + "\n\n", "推送数据日志");
                            if(result.Replace(" ", "").Contains("\"code\":\"200\""))
                            {
                                Status = 1;
                            }
                        }
                        PushRecord rec = db.PushRecord.Add(new PushRecord()
                        {
                            CreateDate = DateTime.Now,
                            UpdateDate = DateTime.Now,
                            Status = Status,
                            PushData = PushData,
                            PushDataEncrypt = PushDataEncrypt,
                            PushObjId = pushItem.Id,
                            MerchantId = merchant.Id
                        }).Entity;
                        db.SaveChanges();
                        if(Status != 1)
                        {
                            db.RePushQueue.Add(new RePushQueue()
                            {
                                CreateDate = DateTime.Now,
                                RePushUrl = NoticeUrl,
                                RePushDate = RePushHelper.Instance.GetNextTime(1),
                                Times = 1,
                                PushData = PushData,
                                PushDataEncrypt = PushDataEncrypt,
                                PushObjId = pushItem.Id,
                                MerchantId = merchant.Id,
                                PushRecordId = rec.Id,
                            });
                        }
                        db.SaveChanges();
                        StartId = int.Parse(dr["id"].ToString());
                    }
                    var edit = db.PushObj.FirstOrDefault(m => m.Id == pushItem.Id);
                    if(edit != null)
                    {
                        edit.QueryId = StartId;
                        db.SaveChanges();
                    }
                }
            }
            db.Dispose();
        }
        
    }
}