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

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

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

    // 每月1号重置仓库额度
    // 固定额度=上月出货额度与保底额度之间的最高值
    // 已用额度=仓库中机具占用额度+小分仓机具占用额度+申请补货订单占用额度-小分仓中带“授”标记机具占用额度
    // 可用额度=重置后的固定额度+被担保额度+临时额度-已用额度
    private void DoWorks()
    {
        while (true)
        {
            WebCMSEntities db = new WebCMSEntities();
            try
            {
                if(DateTime.Now.Day == 1 && DateTime.Now.Hour > 0 && DateTime.Now.Hour < 3)
                {
                    string check = function.ReadInstance("/StoreApply/" + DateTime.Now.ToString("yyyyMM") + ".txt");
                    if(string.IsNullOrEmpty(check))
                    {
                        function.WritePage("/StoreApply/", DateTime.Now.ToString("yyyyMM") + ".txt", DateTime.Now.ToString());
                        DoSomething(db);
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Instance.WriteLog(DateTime.Now.ToString() + "\n" + ex.ToString(), "计算分仓申请机具额度异常");
            }
            db.Dispose();
            LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "\n\n", "计算分仓申请机具额度日志");
            Thread.Sleep(60000);
        }
    }

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

    private void ResetStoreReserveDo()
    {
        while (true)
        {
            WebCMSEntities db = new WebCMSEntities();
            try
            {
                string data = RedisDbconn.Instance.RPop<string>("ResetStoreReserveQueue");
                if(!string.IsNullOrEmpty(data))
                {
                    int UserId = int.Parse(data);
                    if(UserId > 0) DoSomething(db, UserId);
                }
                else
                {
                    Thread.Sleep(10000);
                }
            }
            catch(Exception ex)
            {
                LogHelper.Instance.WriteLog(DateTime.Now.ToString() + "\r\n" + ex.ToString(), "重置分仓额度异常");
            }
            db.Dispose();
        }
    }

    public void DoSomething(WebCMSEntities db, int UId = 0)
    {
        string connstr = Library.ConfigurationManager.AppSettings["SqlConnStr"].ToString();
        Dictionary<int, decimal> dataDic = new Dictionary<int, decimal>();
        string pre = DateTime.Now.AddMonths(-2).ToString("yyyy-MM") + "-01 00:00:00";
        string start = DateTime.Now.AddMonths(-1).ToString("yyyy-MM") + "-01 00:00:00";
        string end = DateTime.Parse(start).AddMonths(1).ToString("yyyy-MM-dd HH:mm:ss");
        string condition = "";
        string usercondition = "";
        if(UId > 0)
        {
            condition = " and StoreId in (select Id from StoreHouse where UserId=" + UId + ")";
            usercondition = " and UserId=" + UId;
        }
        //上月出货额度
        DataTable dt = CustomerSqlConn.dtable("select StoreId,count(Id) from StoreStockChange where Id>=528358 and CreateDate>='" + start + "' and CreateDate<'" + end + "' and BrandId in (1,2,4,6,7,8) and TransType in (10,11,2) and StoreId>0" + condition + " group by StoreId", connstr);
        foreach(DataRow dr in dt.Rows)
        {
            int StoreId = int.Parse(function.CheckInt(dr["StoreId"].ToString()));
            int Count = int.Parse(function.CheckInt(dr[1].ToString()));
            decimal AmountMore = Count * 200;
            StoreHouse store = db.StoreHouse.FirstOrDefault(m => m.Id == StoreId) ?? new StoreHouse();
            if(!dataDic.ContainsKey(store.UserId))
            {
                dataDic.Add(store.UserId, AmountMore);
            }
            else
            {
                dataDic[store.UserId] += AmountMore;
            }
        }
        dt = CustomerSqlConn.dtable("select StoreId,count(Id) from StoreStockChange where Id>=528358 and CreateDate>='" + start + "' and CreateDate<'" + end + "' and BrandId in (3,5,9) and TransType in (10,11,2) and StoreId>0" + condition + " group by StoreId", connstr);
        foreach(DataRow dr in dt.Rows)
        {
            int StoreId = int.Parse(function.CheckInt(dr["StoreId"].ToString()));
            int Count = int.Parse(function.CheckInt(dr[1].ToString()));
            decimal AmountMore = Count * 300;
            StoreHouse store = db.StoreHouse.FirstOrDefault(m => m.Id == StoreId) ?? new StoreHouse();
            if(!dataDic.ContainsKey(store.UserId))
            {
                dataDic.Add(store.UserId, AmountMore);
            }
            else
            {
                dataDic[store.UserId] += AmountMore;
            }
        }
        //上月没出货的创库
        string ids = "0";
        foreach(int UserId in dataDic.Keys)
        {
            ids += "," + UserId;
        }
        DataTable dts = CustomerSqlConn.dtable("select distinct UserId from StoreHouse where UserId not in (" + ids + ")" + usercondition + " and Status>-1", connstr);
        foreach(DataRow dr in dts.Rows)
        {
            int UserId = int.Parse(function.CheckInt(dr[0].ToString()));
            if(!dataDic.ContainsKey(UserId))
            {
                dataDic.Add(UserId, 0);
            }
        }
        foreach(int UserId in dataDic.Keys)
        {
            decimal Amount = dataDic[UserId];
            //上月出货额度与保底额度之间取较高值，保底额度为押金的两倍                            
            UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId);
            if (account == null)
            {
                account = db.UserAccount.Add(new UserAccount()
                {
                    Id = UserId,
                    UserId = UserId,
                }).Entity;
                db.SaveChanges();
            }
            decimal StoreDeposit = account.StoreDeposit;
            if(Amount < StoreDeposit * 2)
            {
                Amount = StoreDeposit * 2;
            }
            //被担保额度
            decimal PromissAmount = 0;
            dt = CustomerSqlConn.dtable("select PromissAmount from StoreHouseAmountPromiss where ToUserId=" + UserId + " and Status=1", connstr);
            foreach(DataRow dr in dt.Rows)
            {
                PromissAmount += decimal.Parse(function.CheckNum(dr["PromissAmount"].ToString()));
            }
            decimal AmountMore = 0;
            //仓库中机具占用额度+小分仓机具占用额度
            DataTable dtmore = CustomerSqlConn.dtable("select count(Id)*200 from PosMachinesTwo pos where StoreId in (select Id from StoreHouse where UserId=" + UserId + " and Sort=0) and BuyUserId=0 and BrandId in (1,2,4,6,7,8) and `Status`>-1", connstr);
            if(dtmore.Rows.Count > 0)
            {
                AmountMore += decimal.Parse(function.CheckNum(dtmore.Rows[0][0].ToString()));
            }
            dtmore = CustomerSqlConn.dtable("select count(Id)*300 from PosMachinesTwo pos where StoreId in (select Id from StoreHouse where UserId=" + UserId + " and Sort=0) and BuyUserId=0 and BrandId in (3,5,9) and `Status`>-1", connstr);
            if(dtmore.Rows.Count > 0)
            {
                AmountMore += decimal.Parse(function.CheckNum(dtmore.Rows[0][0].ToString()));
            }
            //除开小分仓中带“授”标记机具占用额度
            dtmore = CustomerSqlConn.dtable("select count(Id)*200 from PreSendStockDetail pos where FromStoreId in (select Id from StoreHouse where UserId=" + UserId + " and Sort=0) and BrandId in (1,2,4,6,7,8) and AuthFlag=1 and ApplyFlag=0 and `Status`>-1 and `Status`<2", connstr);
            if(dtmore.Rows.Count > 0)
            {
                AmountMore -= decimal.Parse(function.CheckNum(dtmore.Rows[0][0].ToString()));
            }
            dtmore = CustomerSqlConn.dtable("select count(Id)*300 from PreSendStockDetail pos where FromStoreId in (select Id from StoreHouse where UserId=" + UserId + " and Sort=0) and BrandId in (3,5,9) and AuthFlag=1 and ApplyFlag=0 and `Status`>-1 and `Status`<2", connstr);
            if(dtmore.Rows.Count > 0)
            {
                AmountMore -= decimal.Parse(function.CheckNum(dtmore.Rows[0][0].ToString()));
            }
            //申请补货订单占用额度
            dt = CustomerSqlConn.dtable("select UseAmount from StoreMachineApply where UserId=" + UserId + " and Status=0", connstr);
            foreach(DataRow dr in dt.Rows)
            {
                AmountMore += decimal.Parse(function.CheckNum(dr["UseAmount"].ToString()));
            }
            account.FixedAmount = Amount;
            account.ValidAmount = Amount + PromissAmount + account.TempAmount + account.TempAmountForBalance - AmountMore;
            LogHelper.Instance.WriteLog("UserId:" + UserId + ";FixedAmount:" + account.FixedAmount + ";AmountMore:" + AmountMore + ";ValidAmount:" + account.ValidAmount, "计算分仓申请机具额度日志");
        }
        db.SaveChanges();
    }

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

    private void StartEverTimeDo()
    {
        while (true)
        {
            WebCMSEntities db = new WebCMSEntities();
            try
            {
                string data = RedisDbconn.Instance.RPop<string>("StoreApplyQueue");
                if(!string.IsNullOrEmpty(data))
                {
                    LogHelper.Instance.WriteLog("data:" + data, "分仓向总仓申请机具日志");
                    JsonData jsonObj = JsonMapper.ToObject(data);
                    if(jsonObj["Kind"].ToString() == "1") // 购买临时额度
                    {
                        int OrderId = int.Parse(jsonObj["Data"]["OrderId"].ToString());
                        Orders order = db.Orders.FirstOrDefault(m => m.Id == OrderId);
                        if(order != null)
                        {
                            decimal TotalPrice = order.TotalPrice * 2;
                            AddAmount2(db, 1, order.UserId, TotalPrice, order.PayMode, 1, order.Id);
                        }
                    }
                    else if(jsonObj["Kind"].ToString() == "2") // 增减分仓临时额度
                    {
                        int UserId = int.Parse(jsonObj["Data"]["UserId"].ToString());
                        decimal Amount = decimal.Parse(jsonObj["Data"]["Amount"].ToString());
                        int OperateType = int.Parse(jsonObj["Data"]["OperateType"].ToString());
                        AddAmount(db, 2, UserId, Amount, OperateType);
                    }
                    else if(jsonObj["Kind"].ToString() == "3") // 调低额度返回余额
                    {
                        int UserId = int.Parse(jsonObj["Data"]["UserId"].ToString());
                        decimal Amount = decimal.Parse(jsonObj["Data"]["Amount"].ToString());
                        int PayMode = int.Parse(jsonObj["Data"]["PayMode"].ToString());
                        AddAmount2(db, 3, UserId, Amount, PayMode, 0);
                        if(PayMode != 1)
                        {
                            decimal BalanceAmount = Amount / 2;
                            UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId);
                            if (account == null)
                            {
                                account = db.UserAccount.Add(new UserAccount()
                                {
                                    Id = UserId,
                                    UserId = UserId,
                                }).Entity;
                                db.SaveChanges();
                            }
                            decimal BeforeTotalAmount = account.TotalAmount; //变更前总金额
                            decimal BeforeFreezeAmount = account.FreezeAmount; //变更前冻结金额
                            decimal BeforeBalanceAmount = account.BalanceAmount; //变更前余额
                            account.BalanceAmount += BalanceAmount;
                            decimal AfterTotalAmount = account.TotalAmount; //变更后总金额
                            decimal AfterFreezeAmount = account.FreezeAmount; //变更后冻结金额
                            decimal AfterBalanceAmount = account.BalanceAmount; //变更后余额
                            UserAccountRecord userAccountRecord = db.UserAccountRecord.Add(new UserAccountRecord()
                            {
                                CreateDate = DateTime.Now,
                                UpdateDate = DateTime.Now,
                                UserId = UserId, //创客
                                ChangeType = 119, //变动类型
                                ChangeAmount = BalanceAmount, //变更金额
                                BeforeTotalAmount = BeforeTotalAmount, //变更前总金额
                                AfterTotalAmount = AfterTotalAmount, //变更后总金额
                                BeforeFreezeAmount = BeforeFreezeAmount, //变更前冻结金额
                                AfterFreezeAmount = AfterFreezeAmount, //变更后冻结金额
                                BeforeBalanceAmount = BeforeBalanceAmount, //变更前余额
                                AfterBalanceAmount = AfterBalanceAmount, //变更后余额
                            }).Entity;
                        }
                    }
                    else if(jsonObj["Kind"].ToString() == "4") // 仓库发货，预发机申请
                    {
                        int StoreId = int.Parse(jsonObj["Data"]["StoreId"].ToString());
                        string SnIds = jsonObj["Data"]["SnIds"].ToString();
                        StoreHouse store = db.StoreHouse.FirstOrDefault(m => m.Id == StoreId);
                        if(store != null)
                        {
                            decimal Amount = 0;
                            string[] SnIdList = SnIds.Split(',');
                            foreach(string SnIdString in SnIdList)
                            {
                                int SnId = int.Parse(SnIdString);
                                PreSendStockDetail prepos = db.PreSendStockDetail.FirstOrDefault(m => m.SnId == SnId && m.Status == 1 && m.ApplyFlag == 1) ?? new PreSendStockDetail();
                                if(prepos.AuthFlag == 0)
                                {
                                    PosMachinesTwo pos = db.PosMachinesTwo.FirstOrDefault(m => m.Id == SnId) ?? new PosMachinesTwo();
                                    if(pos.BrandId == 1 || pos.BrandId == 2 || pos.BrandId == 4 || pos.BrandId == 6 || pos.BrandId == 7 || pos.BrandId == 8 || pos.BrandId == 10)
                                    {
                                        Amount += 200;
                                    }
                                    else if(pos.BrandId == 3 || pos.BrandId == 5 || pos.BrandId == 9 || pos.BrandId == 11)
                                    {
                                        Amount += 300;
                                    }
                                }
                            }
                            if(Amount > 0)
                            {
                                AddAmount(db, 4, store.UserId, Amount, 1);
                            }
                        }
                    }
                    else if(jsonObj["Kind"].ToString() == "5") // 后台仓库调拨
                    {
                        int StoreId = int.Parse(jsonObj["Data"]["StoreId"].ToString());
                        int BrandId = int.Parse(jsonObj["Data"]["BrandId"].ToString());
                        string OpStorrString = jsonObj["Data"]["OpStoreNum"].ToString();
                        int OpType = OpStorrString.StartsWith("-") ? 0 : 1;
                        int OpStoreNum = int.Parse(OpStorrString.Replace("-", ""));
                        StoreHouse store = db.StoreHouse.FirstOrDefault(m => m.Id == StoreId);
                        if(store != null)
                        {
                            decimal Amount = 0;
                            if(BrandId == 1 || BrandId == 2 || BrandId == 4 || BrandId == 6 || BrandId == 7 || BrandId == 8 || BrandId == 10)
                            {
                                Amount += 200 * OpStoreNum;
                            }
                            else if(BrandId == 3 || BrandId == 5 || BrandId == 9 || BrandId == 11)
                            {
                                Amount += 300 * OpStoreNum;
                            }
                            if(Amount > 0)
                            {
                                AddAmount(db, 5, store.UserId, Amount, OpType);
                            }
                        }
                    }
                    db.SaveChanges();
                }
                else
                {
                    Thread.Sleep(5000);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Instance.WriteLog(DateTime.Now.ToString() + "\n" + ex.ToString(), "分仓向总仓申请机具线程异常");
            }
            db.Dispose();
        }
    }

    public void AddAmount(WebCMSEntities db, int Kind, int UserId, decimal Amount, int OperateType = 1, int OrderId = 0)
    {
        UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId);
        if (account == null)
        {
            account = db.UserAccount.Add(new UserAccount()
            {
                Id = UserId,
                UserId = UserId,
            }).Entity;
            db.SaveChanges();
        }
        decimal BeforeTotalAmount = account.ValidAmount; //变更前总金额
        if(OperateType == 1)
        {
            account.ValidAmount += Amount;
        }
        else
        {
            account.ValidAmount -= Amount;
        }
        decimal AfterTotalAmount = account.ValidAmount; //变更后总金额
        StoreHouseAmountRecord record = db.StoreHouseAmountRecord.Add(new StoreHouseAmountRecord()
        {
            CreateDate = DateTime.Now,
            UpdateDate = DateTime.Now,
            OperateType = OperateType,
            AmountType = 1,
            AfterAmount = AfterTotalAmount,
            BeforeAmount = BeforeTotalAmount,
            UseAmount = Amount,
            UserId = UserId,
            QueryCount = OrderId,
            Sort = Kind,
        }).Entity;
        db.SaveChanges();
    }

    public void AddAmount2(WebCMSEntities db, int Kind, int UserId, decimal Amount, int PayMode, int OperateType = 1, int OrderId = 0)
    {
        UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId);
        if (account == null)
        {
            account = db.UserAccount.Add(new UserAccount()
            {
                Id = UserId,
                UserId = UserId,
            }).Entity;
            db.SaveChanges();
        }
        decimal BeforeTotalAmount = account.ValidAmount; //变更前总金额
        if(OperateType == 1)
        {
            if(PayMode == 3)
            {
                account.TempAmountForBalance += Amount;
            }
            else
            {
                account.TempAmount += Amount;
            }
            account.ValidAmount += Amount;
        }
        else
        {
            if(PayMode == 3)
            {
                account.TempAmountForBalance -= Amount;
            }
            else
            {
                account.TempAmount -= Amount;
            }
            account.ValidAmount -= Amount;
        }
        decimal AfterTotalAmount = account.ValidAmount; //变更后总金额
        StoreHouseAmountRecord record = db.StoreHouseAmountRecord.Add(new StoreHouseAmountRecord()
        {
            CreateDate = DateTime.Now,
            UpdateDate = DateTime.Now,
            OperateType = OperateType,
            AmountType = 1,
            AfterAmount = AfterTotalAmount,
            BeforeAmount = BeforeTotalAmount,
            UseAmount = Amount,
            UserId = UserId,
            QueryCount = OrderId,
            Sort = Kind,
            PayMode = PayMode,
        }).Entity;
        db.SaveChanges();
    }

    private List<int> SpecialUsers10000()
    {
        List<int> ids = new List<int>();
        ids.Add(13185);
        ids.Add(514);
        ids.Add(24302);
        ids.Add(548);
        ids.Add(37887);
        ids.Add(33002);
        ids.Add(730);
        ids.Add(40950);
        ids.Add(72099);
        ids.Add(6898);
        ids.Add(46284);
        ids.Add(127884);
        ids.Add(3596);
        ids.Add(32630);
        ids.Add(11211);
        return ids;
    }

    private List<int> SpecialUsers0()
    {
        List<int> ids = new List<int>();
        ids.Add(21135);
        ids.Add(598);
        ids.Add(109913);
        ids.Add(609);
        ids.Add(588);
        ids.Add(12107);
        ids.Add(7641);
        ids.Add(4317);
        ids.Add(560);
        ids.Add(120998);
        ids.Add(3905);
        ids.Add(959);
        ids.Add(2502);
        ids.Add(1001);
        ids.Add(68868);
        ids.Add(11718);
        ids.Add(15493);
        ids.Add(459);
        ids.Add(97952);
        ids.Add(10719);
        ids.Add(16453);
        ids.Add(1337);
        ids.Add(110198);
        ids.Add(582);
        ids.Add(89);
        ids.Add(9319);
        ids.Add(128525);
        ids.Add(1109);
        ids.Add(28538);
        ids.Add(2927);
        ids.Add(584);
        ids.Add(6659);
        return ids;
    }
}