using System;
using System.Collections.Generic;
using Library;
using LitJson;
using System.Linq;
using MySystem.Models.Main;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
using System.Text;
using System.Threading;

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

        public void Start()
        {
            Thread th = new Thread(Listen);
            th.IsBackground = true;
            th.Start();
        }

        public void Listen()
        {
            bool op = true;
            while (op)
            {
                string content = RedisDbconn.Instance.RPop<string>("WeChatPayBackHd");
                if (!string.IsNullOrEmpty(content))
                {
                    try
                    {
                        dosomething(content);
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Instance.WriteLog(DateTime.Now.ToString() + ":" + ex.ToString(), "微信支付回调异常");
                    }
                }
                else
                {
                    Thread.Sleep(2000);
                }
            }
        }

        public void dosomething(string content)
        {
            LogHelper.Instance.WriteLog("\n\n" + DateTime.Now.ToString() + "\n" + content, "微信支付回调监控");
            JsonData jsonObj = JsonMapper.ToObject(content);
            if (jsonObj.Count > 0)
            {
                LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "json通过", "微信支付回调监控");
                string OrderNo = jsonObj["outOrderNo"].ToString();
                string HdOrderNo = jsonObj["orderNo"].ToString();
                string TradeNo = "";
                if (content.Contains("\"payChannelOrderNo\""))
                {
                    TradeNo = jsonObj["payChannelOrderNo"].ToString();
                }
                LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "OrderNo:" + OrderNo, "微信支付回调监控");
                LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "HdOrderNo:" + HdOrderNo, "微信支付回调监控");
                LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "TradeNo:" + TradeNo, "微信支付回调监控");
                WebCMSEntities db = new WebCMSEntities();
                ConsumerOrders order = db.ConsumerOrders.FirstOrDefault(m => m.OrderNo == OrderNo && m.Status == 0);
                if (order != null)
                {
                    LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "找到订单", "微信支付回调监控");
                    order.Status = 1;
                    order.UpdateDate = DateTime.Now;
                    order.PayMoney = order.PayMoney;
                    order.MaxDivi = order.MaxDivi;
                    order.SeoTitle = HdOrderNo;
                    order.SeoKeyword = TradeNo;
                    LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "赋值", "微信支付回调监控");
                    MerchantInfo merchant = db.MerchantInfo.FirstOrDefault(m => m.Id == order.MerchantId) ?? new MerchantInfo();
                    MerchantAddInfo addinfo = db.MerchantAddInfo.FirstOrDefault(m => m.Id == order.MerchantId) ?? new MerchantAddInfo();
                    if (addinfo.Status == 1 && order.PayMode == 2)
                    {
                        addinfo.Status = 2;
                        merchant.Status = 2;
                        addinfo.WeChatRemark = "";
                        if (merchant.Latitude == 0)
                        {
                            //签约成功调用腾讯地图接口获取地址
                            RedisDbconn.Instance.AddList("GetTencentAddressInfoQueueHd", "{\"MerChantId\":\"" + merchant.Id + "\",\"Address\":\"" + merchant.Areas + merchant.Address + "\"}");
                        }
                    }
                    else if (addinfo.QueryCount == 1 && order.PayMode == 1)
                    {
                        addinfo.QueryCount = 2;
                        merchant.QueryCount = 2;
                        addinfo.AlipayRemark = "";
                        if (merchant.Latitude == 0)
                        {
                            //签约成功调用腾讯地图接口获取地址
                            RedisDbconn.Instance.AddList("GetTencentAddressInfoQueueHd", "{\"MerChantId\":\"" + merchant.Id + "\",\"Address\":\"" + merchant.Areas + merchant.Address + "\"}");
                        }
                    }
                    order.UserId = merchant.UserId;
                    LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "创客:" + merchant.UserId, "微信支付回调监控");
                    ConsumerOrders check = db.ConsumerOrders.FirstOrDefault(m => m.Id < order.Id && m.Status > 0 && m.PayMode == order.PayMode && m.MerchantId == order.MerchantId);
                    if (check != null)
                    {
                        order.QueryCount = check.QueryCount + 1;
                    }
                    else
                    {
                        order.QueryCount = 1;
                    }
                    db.SaveChanges();
                    LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "检测商户订单数:" + order.QueryCount, "微信支付回调监控");

                    Models.Main1.WebCMSEntities db1 = new Models.Main1.WebCMSEntities();
                    var machines = db1.PosMachines.Select(m => new { m.SeoDescription, m.DeviceKind, m.BrandId, m.Detail, m.BindMerchantId }).Where(m => m.DeviceKind == "2" && m.BindMerchantId == order.MerchantId);
                    foreach (var machine in machines)
                    {
                        if (!string.IsNullOrEmpty(addinfo.AliMerchantId) && machine.BrandId == 1)
                        {
                            AliIotFunction.Instance.IotTradeVoice(machine.SeoDescription, addinfo.AliMerchantId, order.PayMoney.ToString("f2"), "OTHER");
                        }
                        else if (machine.BrandId == 2)
                        {
                            TianYuVoiceHelper.Instance.doSomething(DateTime.Now.ToString("yyyyMMddHHmmssfff"), machine.Detail, order.PayMoney.ToString("f2"));
                        }
                        else if (machine.BrandId == 3)
                        {
                            MqLinksHelper.Instance.doSomething(machine.Detail, order.PayMoney.ToString("f2"));
                        }
                    }
                    db1.Dispose();
                    LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "执行完毕", "微信支付回调监控");

                    //发送订单到客小爽MQ
                    OrderMessageHelper.SendOrderMsg(order);

                    //给商户单独推送订单消息
                    string orderData = "{\"order_no\":\"" + order.OrderNo + "\",\"order_status\":\"" + order.Status + "\",\"order_time\":\"" + order.UpdateDate.Value.ToString("yyyy-MM-dd HH:mm:ss") + "\"}";
                    RedisDbconn.Instance.AddList("OrderPushQueue", orderData);
                }
                else
                {
                    LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "没找到订单", "微信支付回调监控");
                    ConsumerOrders checkorder = db.ConsumerOrders.FirstOrDefault(m => m.OrderNo == OrderNo && m.Status == 2);
                    if (checkorder != null)
                    {
                        LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "找到订单状态为2", "微信支付回调监控");
                    }
                    else
                    {
                        RedisDbconn.Instance.AddList("WeChatPayBackHdDead", content);
                    }
                }
                db.Dispose();
                LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "结束", "微信支付回调监控");
            }
        }

        //分账队列
        public void StartProfitShare()
        {
            Thread th = new Thread(StartProfitShareListen);
            th.IsBackground = true;
            th.Start();
        }

        public void StartProfitShareListen()
        {
            bool op = true;
            while (op)
            {
                try
                {
                    WebCMSEntities db = new WebCMSEntities();
                    DateTime checkDate = DateTime.Now.AddMinutes(-2);
                    var list = db.ConsumerOrders.Select(m => new { m.Id, m.SettleAmount, m.Status, m.IsAct, m.PayMode }).Where(m => m.Status == 1 && m.IsAct == 1 && m.SettleAmount > 0).OrderBy(m => m.Id).Take(10).ToList();
                    foreach (var sub in list)
                    {
                        ConsumerOrders order = db.ConsumerOrders.FirstOrDefault(m => m.Id == sub.Id);
                        if (order != null)
                        {
                            int Status = 2;
                            MerchantInfo merchant = db.MerchantInfo.FirstOrDefault(m => m.Id == order.MerchantId) ?? new MerchantInfo();
                            MerchantParamSet set = Newtonsoft.Json.JsonConvert.DeserializeObject<MerchantParamSet>(order.SeoDescription);
                            if (order.IsAct == 1 && order.PayMoney >= set.MinPayMoney)
                            {
                                MerchantAddInfo merchantAdd = db.MerchantAddInfo.FirstOrDefault(m => m.Id == order.MerchantId) ?? new MerchantAddInfo();
                                //发起分账
                                decimal fee = order.PayMoney;
                                if (fee >= 1)
                                {
                                    string applyNo = "FZ" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + function.get_Random(8); //批次号
                                    string mchtNo = merchantAdd.OutMchtNo; //慧掌柜商户号
                                    string orderNo = order.SeoTitle; //交易订单号（好哒平台订单号，G开头）
                                    string acctNo = AppConfig.Haoda.AcctNo; //账户号，分账接收方账户号
                                    string sacctNo = merchantAdd.MchtNo; //账户号，收款商户号
                                    string acctType = "0"; //账户类型（0：商户收款账户（大B），1：分账接收方账户（小B））

                                    decimal settleAmount = (decimal)order.SettleAmount / 100M;
                                    decimal divideAmt = (1 - 0.0038M) * order.PayMoney;
                                    divideAmt = decimal.Parse(divideAmt.ToString("f2"));
                                    decimal hdfee = 0.0038M * order.PayMoney * (1 - set.GetPercent / 100 - 0.01M);
                                    hdfee = decimal.Parse(hdfee.ToString("f2"));
                                    decimal servicefee = 0.01M * order.PayMoney - hdfee;
                                    servicefee = decimal.Parse(servicefee.ToString("f2"));
                                    decimal amount = order.PayMoney * (1 - 0.0038M) - servicefee;
                                    amount = decimal.Parse(amount.ToString("f2"));
                                    decimal otherAmt = settleAmount - servicefee - amount;
                                    if (otherAmt != 0)
                                    {
                                        amount += otherAmt;
                                    }

                                    amount = amount * 100; //金额（分）
                                    servicefee = servicefee * 100;
                                    string seviceAmount = servicefee.ToString("f0"); //服务费
                                    string amountAmount = amount.ToString("f0");
                                    string result = HaoDaHelper.Instance.OrderDivideAccounts(OrderDivideAccountsUtil.AddValue(applyNo, mchtNo, orderNo, acctNo, sacctNo, acctType, amountAmount, seviceAmount), merchantAdd.BrandId);
                                    order.DivideLog = "请求分账日志：" + result;
                                    order.TradePayNo = applyNo;
                                    if (result.Contains("\"resultCode\":\"0\"") && (result.Contains("分账金额不足") || result.Contains("不存在")))
                                    {
                                        Status = 1;
                                    }

                                    //开始监听分账状态
                                    // Dictionary<string, object> req = new Dictionary<string, object>();
                                    // req.Add("ApplyNo", applyNo);
                                    // req.Add("OrderNo", order.OrderNo);
                                    // req.Add("MchtNo", mchtNo);
                                    // RedisDbconn.Instance.AddList("ProfitShareHdQueue", Newtonsoft.Json.JsonConvert.SerializeObject(req));
                                }
                                else
                                {
                                    RedisDbconn.Instance.AddList("ConsumerOrdersHd:Divi:" + order.PayMode + ":List", order.Id.ToString());
                                }
                            }
                            order.Status = Status;
                            if (Status == 2)
                            {
                                order.DivideFlag = 1;
                                order.DivideDate = DateTime.Now;
                            }
                        }
                    }
                    db.SaveChanges();
                    db.Dispose();
                }
                catch (Exception ex)
                {
                    LogHelper.Instance.WriteLog(DateTime.Now.ToString() + ":" + ex.ToString(), "好哒分账队列异常");
                }
                Thread.Sleep(2000);
            }
        }








        //触发分账接口
        public void StartDivi()
        {
            Thread th = new Thread(ListenDivi);
            th.IsBackground = true;
            th.Start();
        }

        public void ListenDivi()
        {
            bool op = true;
            while (op)
            {
                string content = RedisDbconn.Instance.RPop<string>("AddHdDiviQueue");
                if (!string.IsNullOrEmpty(content))
                {
                    try
                    {
                        int id = int.Parse(function.CheckInt(content));
                        WebCMSEntities db = new WebCMSEntities();
                        ConsumerOrders order = db.ConsumerOrders.FirstOrDefault(m => m.Id == id);
                        if (order != null)
                        {
                            MerchantInfo merchant = db.MerchantInfo.FirstOrDefault(m => m.Id == order.MerchantId) ?? new MerchantInfo();
                            MerchantParamSet set = Newtonsoft.Json.JsonConvert.DeserializeObject<MerchantParamSet>(order.SeoDescription);
                            if (order.IsAct == 1 && order.PayMoney >= set.MinPayMoney)
                            {
                                MerchantAddInfo merchantAdd = db.MerchantAddInfo.FirstOrDefault(m => m.Id == order.MerchantId) ?? new MerchantAddInfo();
                                //发起分账
                                decimal fee = order.PayMoney;
                                if (fee >= 1)
                                {
                                    string applyNo = "FZ" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + function.get_Random(8); //批次号
                                    string mchtNo = merchantAdd.OutMchtNo; //慧掌柜商户号
                                    string orderNo = order.SeoTitle; //交易订单号（好哒平台订单号，G开头）
                                    string acctNo = AppConfig.Haoda.AcctNo; //账户号，分账接收方账户号
                                    string sacctNo = merchantAdd.MchtNo; //账户号，收款商户号
                                    string acctType = "0"; //账户类型（0：商户收款账户（大B），1：分账接收方账户（小B））

                                    decimal settleAmount = (decimal)order.SettleAmount / 100M;
                                    decimal divideAmt = (1 - 0.0038M) * order.PayMoney;
                                    divideAmt = decimal.Parse(divideAmt.ToString("f2"));
                                    decimal hdfee = 0.0038M * order.PayMoney * (1 - set.GetPercent / 100 - 0.01M);
                                    hdfee = decimal.Parse(hdfee.ToString("f2"));
                                    decimal servicefee = 0.01M * order.PayMoney - hdfee;
                                    servicefee = decimal.Parse(servicefee.ToString("f2"));
                                    decimal amount = order.PayMoney * (1 - 0.0038M) - servicefee;
                                    amount = decimal.Parse(amount.ToString("f2"));
                                    decimal otherAmt = settleAmount - servicefee - amount;
                                    if (otherAmt != 0)
                                    {
                                        amount += otherAmt;
                                    }

                                    amount = amount * 100; //金额（分）
                                    servicefee = servicefee * 100;
                                    string seviceAmount = servicefee.ToString("f0"); //服务费
                                    string amountAmount = amount.ToString("f0");
                                    string result = HaoDaHelper.Instance.OrderDivideAccounts(OrderDivideAccountsUtil.AddValue(applyNo, mchtNo, orderNo, acctNo, sacctNo, acctType, amountAmount, seviceAmount));
                                    order.DivideLog = "请求分账日志：" + result;

                                    //开始监听分账状态
                                    // Dictionary<string, object> req = new Dictionary<string, object>();
                                    // req.Add("ApplyNo", applyNo);
                                    // req.Add("OrderNo", order.OrderNo);
                                    // req.Add("MchtNo", mchtNo);
                                    // RedisDbconn.Instance.AddList("ProfitShareHdQueue", Newtonsoft.Json.JsonConvert.SerializeObject(req));
                                }
                            }
                        }
                        db.Dispose();
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Instance.WriteLog(DateTime.Now.ToString() + ":" + ex.ToString(), "补分账异常");
                    }
                }
                else
                {
                    Thread.Sleep(2000);
                }
            }
        }

        //监听支付结算订单
        public void StartSettleOrder()
        {
            Thread th = new Thread(SettleOrderListen);
            th.IsBackground = true;
            th.Start();
        }

        public void SettleOrderListen()
        {
            bool op = true;
            while (op)
            {
                string content = RedisDbconn.Instance.RPop<string>("PartOrderQueue");
                if (!string.IsNullOrEmpty(content))
                {
                    try
                    {
                        //{"id":137403,"mchtNo":"1494637","tradeMchtNo":"030500107115593","channelMchtNo":"030500107115593","orderNo":"G2231123C02179895853","channelOrderNo":"50231123B00032642694","txSubCode":31,"paymentType":2,"status":0,"partStatus":0,"partAmount":0,"payAmount":1000,"payServiceFee":4,"settleAmount":996,"totalPerkAmount":0,"payTime":"2023-11-23 23:36:05","algoDate":"2023-11-23 00:00:00","bizDate":"2023-11-23 00:00:00","storeNo":"21627867","deviceSn":" ","cupsNo":"ylzf","cardType":0,"notPartAmount":996,"realAmount":996}
                        LogHelper.Instance.WriteLog(DateTime.Now.ToString() + "\n" + content, "监听支付结算订单");
                        if (content.Contains("\"settleAmount\"") && content.Contains("\"txSubCode\":31,"))
                        {
                            LogHelper.Instance.WriteLog("符合条件", "监听支付结算订单");
                            JsonData jsonObj = JsonMapper.ToObject(content);
                            string orderNo = jsonObj["orderNo"].ToString();
                            int settleAmount = int.Parse(function.CheckInt(jsonObj["settleAmount"].ToString()));
                            LogHelper.Instance.WriteLog("orderNo:" + orderNo, "监听支付结算订单");
                            LogHelper.Instance.WriteLog("settleAmount:" + settleAmount, "监听支付结算订单");
                            WebCMSEntities db = new WebCMSEntities();
                            ConsumerOrders order = db.ConsumerOrders.FirstOrDefault(m => m.SeoTitle == orderNo);
                            if (order != null)
                            {
                                order.SettleAmount = settleAmount;
                                db.SaveChanges();
                                LogHelper.Instance.WriteLog("finish", "监听支付结算订单");
                            }
                            else
                            {
                                Thread.Sleep(2000);
                                RedisDbconn.Instance.AddList("PartOrderQueue", content);
                                LogHelper.Instance.WriteLog("again", "监听支付结算订单");
                            }
                            db.Dispose();
                        }
                        LogHelper.Instance.WriteLog("\n\n", "监听支付结算订单");
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Instance.WriteLog(DateTime.Now.ToString() + ":" + ex.ToString(), "监听支付结算订单异常");
                    }
                }
                else
                {
                    Thread.Sleep(2000);
                }
            }
        }
    }
}