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

public class PosExpiredHelper
{
    public readonly static PosExpiredHelper Instance = new PosExpiredHelper();
    private PosExpiredHelper()
    {
    }

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

    private void DoWorks()
    {
        while (true)
        {
            try
            {
                string content = RedisDbconn.Instance.RPop<string>("PosExpiredRingQueue");
                if(!string.IsNullOrEmpty(content))
                {
                    WebCMSEntities db = new WebCMSEntities();
                    DoSomething(db);
                    db.Dispose();
                }
            }
            catch (Exception ex)
            {
                Utils.WriteLog(DateTime.Now.ToString() + "\n" + ex.ToString(), "过期机具提醒异常");
            }
            Utils.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "\n\n", "过期机具提醒日志");
            Thread.Sleep(60000);
        }
    }

    public void DoSomething(WebCMSEntities db)
    {
        DateTime now = DateTime.Now;
        List<int> BuyUserIds = db.PosMachinesTwo.Select(m => new { m.BuyUserId, m.RecycEndDate, m.Status, m.BindingState }).Where(m => m.RecycEndDate < now && m.Status > -1 && m.BindingState == 0).ToList().Select(m => m.BuyUserId).ToList();
        foreach(int BuyUserId in BuyUserIds)
        {
            RedisDbconn.Instance.AddList("MsgPersonalQueue", Newtonsoft.Json.JsonConvert.SerializeObject(new MsgPersonal()
            {
                UserId = Convert.ToInt32(BuyUserId), //创客
                Title = "机具循环过期提醒", //标题
                Content = "尊敬的创客您好<br />您的部分机具循环已过期，请在五日内完成激活或联系在线客服回寄该机具。", //内容
                Summary = "尊敬的创客您好，您的部分机具循环已过期，请在五日内完成激活或联系在线客服回寄该机具。",
                CreateDate = DateTime.Now,
            }));
        }
    }





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

    private void DoPay()
    {
        while (true)
        {
            try
            {
                string content = RedisDbconn.Instance.RPop<string>("PosExpiredPayQueue");
                if(!string.IsNullOrEmpty(content))
                {
                    WebCMSEntities db = new WebCMSEntities();
                    using (var tran = db.Database.BeginTransaction())
                    {
                        try
                        {
                            GoPay(db, int.Parse(content));
                            tran.Commit();
                        }
                        catch(Exception ex)
                        {
                            tran.Rollback();
                            Utils.WriteLog(DateTime.Now.ToString() + "\n" + ex.ToString(), "过期机具扣费异常");
                        }
                    }
                    db.Dispose();
                }
                else
                {
                    Thread.Sleep(60000);
                }
            }
            catch (Exception ex)
            {
                Utils.WriteLog(DateTime.Now.ToString() + "\n" + ex.ToString(), "过期机具扣费异常");
            }
            Utils.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "\n\n", "过期机具扣费日志");
        }
    }

    public void GoPay(WebCMSEntities db, int UserId)
    {
        UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId) ?? new UserAccount();
        decimal BalanceAmount = account.BalanceAmount;
        List<int> BrandIdList = new List<int>();
        BrandIdList.Add(3);
        BrandIdList.Add(5);
        BrandIdList.Add(9);
        BrandIdList.Add(11);
        DateTime now = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 00:00:00").AddDays(-60);
        Dictionary<int, decimal> UserList = new Dictionary<int, decimal>();
        var PosList = db.PosMachinesTwo.Select(m => new { m.Id, m.BuyUserId, m.RecycEndDate, m.Status, m.BindingState, m.BrandId, m.ScanQrTrade }).Where(m => m.BuyUserId == UserId && m.RecycEndDate < now && m.Status > -1 && m.BindingState == 0 && m.ScanQrTrade < 999).OrderBy(m => m.Id).ToList();
        if(PosList.Count > 0)
        {
            foreach(var Pos in PosList)
            {
                decimal PayMoney = 200;
                if(BrandIdList.Contains(Pos.BrandId))
                {
                    PayMoney = 300;
                }
                PayMoney -= Pos.ScanQrTrade;
                if(BalanceAmount > 0)
                {
                    if(BalanceAmount > PayMoney)
                    {
                        if(UserList.ContainsKey(Pos.BuyUserId))
                        {
                            UserList[Pos.BuyUserId] += PayMoney;
                        }
                        else
                        {
                            UserList.Add(Pos.BuyUserId, PayMoney);
                        }
                        BalanceAmount -= PayMoney;
                    }
                    else
                    {
                        PayMoney = BalanceAmount;
                        if(UserList.ContainsKey(Pos.BuyUserId))
                        {
                            UserList[Pos.BuyUserId] += PayMoney;
                        }
                        else
                        {
                            UserList.Add(Pos.BuyUserId, PayMoney);
                        }
                        BalanceAmount = 0;
                    }
                    PosMachinesTwo EditPos = db.PosMachinesTwo.FirstOrDefault(m => m.Id == Pos.Id);
                    if(EditPos != null)
                    {
                        EditPos.ScanQrTrade += PayMoney;
                        if(BrandIdList.Contains(Pos.BrandId) && EditPos.ScanQrTrade >= 300)
                        {
                            EditPos.ScanQrTrade = 999;
                        }
                        else if(!BrandIdList.Contains(Pos.BrandId) && EditPos.ScanQrTrade >= 200)
                        {
                            EditPos.ScanQrTrade = 999;
                        }
                    }
                }
            }
            db.SaveChanges();
        }
        foreach(int UsrId in UserList.Keys)
        {
            AlipayPayBack2Service.Instance.ChangeAccount(db, new Orders(), UsrId, -UserList[UsrId], 124, "扣机具货款");
        }
    }
}