using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using ChuPiao.Common.Utils;
using System.Threading;

namespace ChuPiao.AutoPrint.Services.OpenCode
{
    [Serializable]
    public class ExpectEntity
    {
        public string Expect;
        public string Opencode;
        public DateTime StartTime;   //开期时间
        public DateTime EndTime;   //截期时间
        public DateTime OpenTime;   //开奖时间
        public int Status;   //0-未出票 200-待抓开奖 300-开奖成功
    }

    public static class ExpectTaskService
    {
        private static string configPath = Path.Combine(Application.StartupPath, "configs/expectlist.xml");
        private static int expectCount = 40;
        private static string startTimeStr = "08:35:29";
        private static int intervalMin = 20;
        private static SortedDictionary<string, ExpectEntity> waitOpenDic = new SortedDictionary<string, ExpectEntity>();
        private static List<ExpectEntity> expectList = new List<ExpectEntity>();
        private static Thread workThread;
        private static object lockObj = new object();
        private static DateTime initTime=DateTime.Now;
        public static DateTime NearlyOpenTime = DateTime.Now;

        public static void setNotifySuc(string expect)
        {
            lock (lockObj)
            {
                waitOpenDic.Remove(expect);
                LoggingService.Info(string.Format("第 {0} 期 抓取到开奖号码并上传成功，还有 {1} 期待抓取", expect, waitOpenDic.Count));
            }

            for (int i = 0; i < expectList.Count; i++)
            { 
                ExpectEntity entity=expectList[i];
                if (entity.Expect!=expect)
                {
                    continue;
                }
                else
                {
                    entity.Status = 300;
                    saveMachineList();
                    break;
                }
            }
        }

        public static List<string> getWaitOpenExpectList()
        {
            return new List<string>(waitOpenDic.Keys);
        }

        public static bool hasWaitOpenExpect()
        {
            return waitOpenDic.Count > 0;
        }

        public static void initExpect()
        {
            DateTime now = DateTime.Now;
            if (File.Exists(configPath))
            {
                expectList = XMLHelper.XmlFileDeserialize<List<ExpectEntity>>(configPath);
                if (expectList[expectList.Count - 1].StartTime.ToString("yyyyMMdd") != now.ToString("yyyyMMdd"))   //只抓当天的期
                {
                    expectList.Clear();
                }
            }
            
            if (expectList.Count == 0)
            {
                DateTime startTime = DateTime.Parse(string.Format("{0:yyyy-MM-dd} {1}",now,startTimeStr));
                for (int i = 1; i <= expectCount; i++)
                {
                    ExpectEntity entity = new ExpectEntity();
                    entity.Expect = string.Format("{0}{1}", now.ToString("yyyyMMdd").Substring(2, 6), i < 10 ? string.Format("0{0}",i.ToString()) : i.ToString());
                    entity.StartTime = startTime.AddMinutes(intervalMin * (i - 1));
                    entity.EndTime = startTime.AddMinutes(intervalMin * i);
                    entity.OpenTime = entity.EndTime.AddMinutes(1);
                    entity.Status = 0;
                    entity.Opencode = "";
                    expectList.Add(entity);
                }
                saveMachineList();
            }

            bool isNeedSave = false;
            for (int i = 0; i < expectList.Count; i++)
            {
                ExpectEntity expect = expectList[i];
                if (expect.Status == 300)
                {
                    continue;
                }
                else if (expect.Status == 200)
                {
                    if (expect.OpenTime > NearlyOpenTime)
                    {
                        NearlyOpenTime = expect.OpenTime;
                    }
                    waitOpenDic.Add(expect.Expect, expect);
                    LoggingService.Info(string.Format("第 {0} 期 需要抓取开奖号码，共 {1} 期待抓取", expect.Expect, waitOpenDic.Count));
                }
                else
                {
                    if (DateTime.Now >= expect.OpenTime)
                    {
                        expect.Status = 200;
                        isNeedSave = true;
                        if (expect.OpenTime > NearlyOpenTime)
                        {
                            NearlyOpenTime = expect.OpenTime;
                        }
                        waitOpenDic.Add(expect.Expect, expect);
                        LoggingService.Info(string.Format("第 {0} 期 需要抓取开奖号码，共 {1} 期待抓取", expect.Expect, waitOpenDic.Count));
                    }
                    else
                    {
                        break;
                    }
                }
            }
            if (isNeedSave)
            {
                saveMachineList();
            }

            workThread = new Thread(run);
            workThread.Start();
        }

        public static void Stop()
        {
            if (workThread != null)
            {
                workThread.Abort();
            }
        }

        private static void run()
        {
            try
            {
                while (true)
                {
                    DateTime now = DateTime.Now;
                    //新的一天
                    if (expectList[expectList.Count - 1].StartTime.ToString("yyyyMMdd") != now.ToString("yyyyMMdd"))   //只抓当天的期
                    {
                        expectList.Clear();
                        lock (lockObj)
                        {
                            waitOpenDic.Clear();
                        }

                        DateTime startTime = DateTime.Parse(string.Format("{0:yyyy-MM-dd} {1}", now, startTimeStr));
                        for (int i = 1; i <= expectCount; i++)
                        {
                            ExpectEntity entity = new ExpectEntity();
                            entity.Expect = string.Format("{0}{1}", now.ToString("yyyyMMdd").Substring(2, 6), i < 10 ? string.Format("0{0}", i.ToString()) : i.ToString());
                            entity.StartTime = startTime.AddMinutes(intervalMin * (i - 1));
                            entity.EndTime = startTime.AddMinutes(intervalMin * i);
                            entity.OpenTime = entity.EndTime.AddMinutes(1);
                            entity.Status = 0;
                            entity.Opencode = "";
                            expectList.Add(entity);
                        }
                        saveMachineList();
                    }

                    //判断等待开奖的期
                    bool isNeedSave = false;
                    for (int i = 0; i < expectList.Count; i++)
                    {
                        ExpectEntity expect = expectList[i];
                        if (expect.Status == 0)
                        {
                            if (DateTime.Now >= expect.OpenTime)
                            {
                                expect.Status = 200;
                                isNeedSave = true;
                                lock (lockObj)
                                {
                                    if (!waitOpenDic.ContainsKey(expect.Expect))
                                    {
                                        if (expect.OpenTime > NearlyOpenTime)
                                        {
                                            NearlyOpenTime = expect.OpenTime;
                                        }
                                        waitOpenDic.Add(expect.Expect, expect);
                                        LoggingService.Info(string.Format("第 {0} 期 需要抓取开奖号码，共 {1} 期待抓取", expect.Expect, waitOpenDic.Count));
                                    }
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    if (isNeedSave)
                    {
                        saveMachineList();
                    }

                    //获取开奖的期超过多久没获取到需要告警，客户端并不知道服务端是否有开奖号码，所以无法告警，告警应该放到服务端
                    //if (DateTime.Now.Subtract(initTime).TotalSeconds > 2 * 60)   //
                    //{
                    //    List<ExpectEntity> list = new List<ExpectEntity>(waitOpenDic.Values);
                    //    ExpectEntity expect = list[list.Count - 1];
                    //    if (DateTime.Now.Subtract(expect.OpenTime).TotalSeconds > 2 * 60)
                    //    {
                    //        Logger.Log.Warn(string.Format("第 {0} 期（开奖时间{1:HH:mm:ss}超过2分钟没有获取到开奖号码！）"));
                    //    }

                    //}

                    Thread.Sleep(10 * 1000);
                }

            }
            catch (ThreadAbortException ex)
            { 
            }
        }

        private static void saveMachineList()
        {
            XMLHelper.XmlFileSerialize(expectList, configPath);
        }


    }
}
