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)
        {
            JsonData jsonObj = JsonMapper.ToObject(content);
            if (jsonObj.Count > 0)
            {
                string OrderNo = jsonObj["outOrderNo"].ToString();
                string TradeNo = jsonObj["orderNo"].ToString();
                WebCMSEntities db = new WebCMSEntities();
                ConsumerOrders order = db.ConsumerOrders.FirstOrDefault(m => m.OrderNo == OrderNo && m.Status == 0);
                if (order != null)
                {
                    order.Status = 1;
                    order.UpdateDate = DateTime.Now;
                    order.PayMoney = order.PayMoney;
                    order.MaxDivi = order.MaxDivi;
                    order.SeoTitle = TradeNo;
                    MerchantInfo merchant = db.MerchantInfo.FirstOrDefault(m => m.Id == order.MerchantId) ?? new MerchantInfo();
                    order.UserId = 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();

                    Models.Main1.WebCMSEntities db1 = new Models.Main1.WebCMSEntities();
                    Models.Main1.PosMachines machine = db1.PosMachines.FirstOrDefault(m => m.PosSn == order.SnNo);
                    if(machine != null)
                    {
                        MerchantAddInfo addinfo = db.MerchantAddInfo.FirstOrDefault(m => m.Id == order.MerchantId) ?? new MerchantAddInfo();
                        if(!string.IsNullOrEmpty(addinfo.AliMerchantId))
                        {
                            AliIotFunction.Instance.IotTradeVoice(machine.SeoDescription, addinfo.AliMerchantId, order.PayMoney.ToString("f2"), "OTHER");
                        }
                    }
                    db1.Dispose();
                }
                db.Dispose();
            }
        }

        //分账队列
        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.CreateDate, m.Status, m.IsAct, m.PayMode }).Where(m => m.Status == 1 && m.IsAct == 1 && m.CreateDate < checkDate).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)
                        {
                            order.Status = 2;
                            MerchantInfo merchant = db.MerchantInfo.FirstOrDefault(m => m.Id == order.MerchantId) ?? new MerchantInfo();
                            MerchantParamSet set = db.MerchantParamSet.FirstOrDefault(m => m.Id == order.MerchantId) ?? new MerchantParamSet();
                            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 amount = fee * (1M - 0.0038M) * 100 - fee; //金额（分）手续费
                                    string seviceAmount = fee.ToString("f0"); //服务费
                                    HaoDaHelper.Instance.OrderDivideAccounts(OrderDivideAccountsUtil.AddValue(applyNo, mchtNo, orderNo, acctNo, sacctNo, acctType, amount.ToString("f0"), seviceAmount));

                                    //开始监听分账状态
                                    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:2:List", order.Id.ToString());
                                }
                            }
                        }
                    }
                    db.SaveChanges();
                    db.Dispose();
                }
                catch (Exception ex)
                {
                    LogHelper.Instance.WriteLog(DateTime.Now.ToString() + ":" + ex.ToString(), "好哒分账队列异常");
                }
                Thread.Sleep(2000);
            }
        }
    }
}