using RFrameGenerate.BLL;
using RFrameGenerate.DAL.Enums;
using RFramework;
using RFramework.SQLServer;
using RFramework.SQLQuery;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;

namespace jiouosdptask.BLL
{
    /// <summary>
    /// 开奖处理
    /// </summary>
    public class LotteryOpen
    {
        static Timer timeLottery;
        static object lottery = new object();
        public static void Start()
        {
            LPs = new List<LotteryPeriod>();

            timeLottery = new Timer();
            timeLottery.Elapsed += timeLotter_Elapsed;
            timeLottery.Enabled = true;
            timeLottery.Interval = 1000 * 60 * 10;
            timeLottery.Start();


            LotteryOpen.InitPeriod();
        }

        public static void Stop()
        {
            timeLottery.Stop();
        }

        static List<LotteryPeriod> LPs;
        static void timeLotter_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (lottery)
            {
                for (int i = LPs.Count - 1; i >= 0; i--)
                {
                    if (LPs[i].IsLotter == true)
                    {
                        LPs.RemoveAt(i);
                    }
                }
            }
        }

        public static void AddPeriodLotter(Guid periodGuid)
        {
            lock (lottery)
            {
                if (LPs.Exists(b => b.PeriodGuid == periodGuid) != true)
                    LPs.Add(new LotteryPeriod(periodGuid));
            }
        }

        public static double GetPeriodLotter(Guid periodGuid)
        {
            lock (lottery)
            {
                var lot = LPs.Where(a => a.PeriodGuid == periodGuid).FirstOrDefault();
                if (lot != null)
                    return lot.GetTimeSpan().TotalSeconds;
                return 0;
            }
        }

        public static void InitPeriod()
        {
            lock (lottery)
            {
                using (var query = Factory.CreateT_CR_ProductCrowdPeriods())
                {
                    var list = query.GetList(a => a.RemainTime == 0 && a.OpenDate.SqlIsNull(), false, null, OrderMethods.Default, RFramework.SQLServer.Enums.LockType.Default, false);

                    list.ForEach(a =>
                    {
                        if (LPs.Exists(b => b.PeriodGuid == a.ProductCrowdPeriodGuid) != true)
                            LPs.Add(new LotteryPeriod(a.ProductCrowdPeriodGuid));
                    });
                }
            }
        }
    }

    public class LotteryPeriod
    {
        Timer time;
        public TimeSpan ts;
        public TimeSpan _ts;
        public LotteryPeriod(Guid periodGuid)
        {
            this.PeriodGuid = periodGuid;

            this.IsLotter = false;

            //10:00-22:00（72期）10分钟一期，22:00-02:00（48期）5分钟一期
            DateTime dt = DateTime.Now;
            if (new DateTime(dt.Year, dt.Month, dt.Day, 10, 0, 0) <= dt && dt < new DateTime(dt.Year, dt.Month, dt.Day, 22, 0, 0))
                _ts = ts = new TimeSpan(0, 10 + 4, 0);
            else if ((new DateTime(dt.Year, dt.Month, dt.Day, 22, 0, 0) <= dt && dt <= new DateTime(dt.Year, dt.Month, dt.Day, 23, 59, 59))
                || (new DateTime(dt.Year, dt.Month, dt.Day, 23, 59, 59) < dt && dt < new DateTime(dt.Year, dt.Month, dt.Day, 2, 0, 0)))
                _ts = ts = new TimeSpan(0, 5 + 4, 0);
            else
                _ts = ts = (new DateTime(dt.Year, dt.Month, dt.Day, 10, 0 + 4, 0) - dt);
            time = new Timer();
            time.Elapsed += time_Elapsed;
            time.Enabled = true;
            time.Interval = 1000;
            time.Start();
        }

        public TimeSpan GetTimeSpan()
        {
            return ts.Add(new TimeSpan(0, 0, 30));
        }

        void time_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (ts.TotalSeconds <= 6)
            {//开奖
                string luckynum = string.Empty;
                Log.Write("开奖成功" + PeriodGuid);
                try
                {
                    time.Stop();
                    using (var tran = new SqlRTransaction())
                    {
                        var queryPeriod = Factory.CreateT_CR_ProductCrowdPeriods(tran);
                        var period = queryPeriod.GetFirstData(a => a.ProductCrowdPeriodGuid == PeriodGuid, false, null, OrderMethods.DESC, RFramework.SQLServer.Enums.LockType.Default, false);

                        var Lott = Factory.CreateT_CR_LotteryResult(tran).GetFirstData(a => a.AwardsPeriod == period.PeriodNum, false, null, OrderMethods.DESC, RFramework.SQLServer.Enums.LockType.Default, false);

                        if (Lott != null)
                        {

                            luckynum = (((period.NumberA.Value + Lott.AwardsNumber) % period.TotalTime) + (CrowdLuckyNumberManage.begin + 1)).ToString();

                            var queryParDe = Factory.CreateT_CR_CrowdParticipateDetails(tran);
                            var parDetail = queryParDe.GetFirstData(a => a.LuckyNum == luckynum && a.ProductCrowdPeriodGuid == PeriodGuid, false, null, OrderMethods.DESC, RFramework.SQLServer.Enums.LockType.Default, false);

                            var queryPar = Factory.CreateT_CR_CrowdParticipate(tran);
                            var par = queryPar.GetFirstData(a => a.CrowdParticipateGuid == parDetail.CrowdParticipateGuid, false, null, OrderMethods.DESC, RFramework.SQLServer.Enums.LockType.Default, false);

                            var queryWin = Factory.CreateT_CR_CrowdWinning(tran);
                            if (queryWin.IsExist(a => a.CrowdParticipateGuid == par.CrowdParticipateGuid, isFilterMerchant: false) != true)
                            {
                                var reciever = Factory.CreateT_BAS_RecieverAddress(tran).GetFirstData(a => a.MemberGuid == par.MemberGuid && a.IsDefualt == true, isFilterMerchant: false);
                                string RecieverAddressGuid;
                                if (reciever != null)
                                    RecieverAddressGuid = reciever.RecieverAddressGuid.ToString();
                                else
                                    RecieverAddressGuid = "NULL";

                                string sql = string.Format("INSERT INTO [dbo].[T_CR_CrowdWinning]([CrowdWinningGuid],[MerchantGuid],[MemberGuid],[MemberNickName],[BuyTime],[AllLuckyNum],[MemberImg],[CrowdPeriods],[ProductCrowdPeriodGuid],[CrowdParticipateGuid],[DeliveryTime],[LogisticrGuid],[LotteryResultGuid],[RecieverAddressGuid],[LuckyNum],[SCreateDate],[SUpdateUserName],[SCreateUserName],[SUpdateDate],[SMerchantGuid])VALUES('{0}','{1}','{2}',{3},'{4}','{5}',{6},'{7}','{8}','{9}',{10},{11},'{12}','{13}','{14}','{15}',{16},'{17}',{18},'{19}')",
                                    Guid.NewGuid(), par.MerchantGuid, par.MemberGuid, "NULL", par.JoinTime, par.AllLuckyNum, "NULL", period.CrowdPeriods, PeriodGuid, par.CrowdParticipateGuid, "NULL", "NULL", Lott.LotteryResultGuid, RecieverAddressGuid, luckynum, DateTime.Now, "NULL", "开奖处理", "NULL", par.MerchantGuid);
                                var result = SqlHelper.ExecuteNonQuery(sql, tran);
                                if (result > 0)
                                {
                                    queryPeriod.Update(a => new object[] { a.OpenDate == DateTime.Now, a.Formula == string.Format("(({0} + {1}) % {2}) + {3}={4}", period.NumberA.Value, Lott.AwardsNumber, period.TotalTime, CrowdLuckyNumberManage.begin, luckynum) }, b => b.ProductCrowdPeriodGuid == PeriodGuid, false);
                                    queryPar.Update(a => new object[] { a.CrowdState == DictionaryConst.CrowdState.DaiFa }, b => b.CrowdParticipateGuid == par.CrowdParticipateGuid, false);
                                }
                            }
                            IsLotter = true;
                            time.Dispose();
                        }
                        else
                        {
                            if (ts <= new TimeSpan(0, 0, 0))
                                ts = new TimeSpan(_ts.Ticks);
                            time.Start();
                            Log.Write(PeriodGuid + "彩票还没有开奖");
                        }

                    }
                }
                catch (Exception ex)
                {
                    if (ts <= new TimeSpan(0, 0, 0))
                        ts = new TimeSpan(_ts.Ticks);
                    time.Start();

                    Log.Write(PeriodGuid + "开奖失败:" + ex.Message);
                }
            }
            else
            {
                ts = ts.Add(new TimeSpan(0, 0, -1));
            }
        }

        public Guid PeriodGuid { get; set; }
        public bool IsLotter { get; set; }
    }
}
