using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using ChuPiao.AutoPrint.Machine;
using ChuPiao.AutoPrint.Machine.Models;
using ChuPiao.Common.Core.Net;
using ChuPiao.Common.Enums;
using ChuPiao.Common.Models;
using ChuPiao.Common.Utils;
using log4net;
using ChuPiao.Common.Communication.GtdJson.Packs;
using ChuPiao.Common.Communication.GtdJson;
using System.Net;

namespace ChuPiao.AutoPrint.Services.OpenCode
{
    /// <summary>
    /// 开奖号码抓取服务
    /// </summary>
    public class DlOpenCodeSnapService : IOpenCodeSnapService
    {
        private DateTime _lastSnapOpenCodeSucTime=DateTime.MinValue;
        private ILotMachine _lotMachine;
        private int _lotid;

        public DlOpenCodeSnapService(ILotMachine lotMachine, int lotId)
        {
            _lotMachine = lotMachine;
            _lotid = lotId;
        }

        private int _snapOpenCodeInterval = 10;
        /// <summary>
        /// 抓取开奖号码时间间隔(秒)
        /// </summary>
        public int SnapOpenCodeInterval
        {
            get
            {
                //if (_snapOpenCodeInterval < 0)
                //{
                //    try
                //    {
                //        _snapOpenCodeInterval = int.Parse(ConfigurationManager.AppSettings["SnapOpenCodeInterval"]);
                //    }
                //    catch (Exception ex)
                //    {
                //        _lotMachine.Log.Info(string.Concat("读取SnapOpenCodeInterval配置异常", ex.Message));
                //        _snapOpenCodeInterval = 5;
                //    }
                //}
                return _snapOpenCodeInterval;
            }
        }

        /// <summary>
        /// 判断是否可以抓取开奖结果报表
        /// </summary>
        /// <returns></returns>
        public bool AllowSnap()
        {
            //抓取间隔判断
            TimeSpan timeSpan = DateTime.Now.Subtract(_lastSnapOpenCodeSucTime);
            if (timeSpan.TotalSeconds < SnapOpenCodeInterval)
            {
                return false;
            }

            if (_lotMachine.MachineInfo.AllowSnapOpenCode_force)
                return true;

            if (!ExpectTaskService.hasWaitOpenExpect())
            {
                return false;
            }



            //Database database = DBSetting.Instance.GetDataBase("dldb");
            //SqlConnection conn = null;
            //try
            //{
            //    conn = new SqlConnection(database.ConnectionString);
            //    conn.Open();
            //    //距离官方开奖前5秒开始抓取
            //    string sql = string.Format("select count(e_id) from dl_expect with(nolock) where e_status=200 and e_opentime<'{0}'", DateTime.Now.AddSeconds(15).ToString("yyyy-MM-dd HH:mm:ss"));
            //    object obj = SqlHelper.ExecuteScalar(conn, CommandType.Text, sql);
            //    if (obj != DBNull.Value)
            //    {
            //        int waitOpenNum = Convert.ToInt32(obj);
            //        if (waitOpenNum < 1)
            //        {
            //            _lotMachine.Log.Info("没有需要抓取开奖号码的期号");
            //            return false;
            //        }
            //    }
            //}
            //finally
            //{
            //    if (conn != null)
            //    {
            //        conn.Close();
            //    }
            //}
            return true;
        }

        /// <summary>
        /// 多乐彩开奖号码
        /// </summary>
        /// <returns></returns>
        public bool SnapOpenCode()
        {
            bool result = true;

            //TimeSpan timeSpan = DateTime.Now.Subtract(ExpectTaskService.NearlyOpenTime);
            //if (timeSpan.TotalSeconds > 120)    //超过2分钟，就机器抓
            //{
            //    try
            //    {
            //        _lotMachine.Log.Info("开始从【彩票机】抓取多乐彩开奖号码……");
            //        CaptureDataInfo captureData = _lotMachine.PrintOpenCodeReport(_lotid);
            //        _lastSnapOpenCodeSucTime = DateTime.Now;
            //        if (captureData.CaptureDataBytes.Length == 0)
            //        {
            //            _lotMachine.Log.Info("抓取多乐彩开奖号码电子票长度为0");
            //            return true;
            //        }

            //        OpenCodeResult openCodeResult = DecodeDlData(captureData);
            //        if (openCodeResult.DecodeSuccess)
            //        {
            //            if (openCodeResult.OpenCodeList.Count == 0)
            //            {
            //                _lotMachine.Log.Info("抓取多乐彩开奖号码个数为0");
            //                return true;
            //            }

            //            //更新数据库
            //            UpdateMachineOpenCodeToLotteryDb(openCodeResult, _lotMachine.Log);

            //        }
            //        else
            //        {
            //            _lotMachine.Log.Warn(string.Concat("解析多乐彩开奖号码失败。错误信息：", openCodeResult.ErrorMessage));
            //            result = false;
            //        }
            //    }
            //    catch (Exception exception)
            //    {
            //        _lotMachine.Log.Info(string.Concat("抓取多乐彩开奖号码异常。错误信息：", exception));
            //        result = false;
            //    }
            //}
            //else  //从源抓
            //{
                try
                {
                    _lotMachine.Log.Info("开始从【源】抓取多乐彩开奖号码……");
                    _lastSnapOpenCodeSucTime = DateTime.Now;

                    OpenCodeResult openCodeResult = captureOpencodeFromUrl();
                    if (openCodeResult.OpenCodeList.Count == 0)
                    {
                        _lotMachine.Log.Info("抓取多乐彩开奖号码个数为0");
                        return true;
                    }

                    //更新数据库
                    UpdateMachineOpenCodeToLotteryDb(openCodeResult, _lotMachine.Log);

                }
                catch (Exception exception)
                {
                    _lotMachine.Log.Info(string.Concat("抓取多乐彩开奖号码异常。错误信息：", exception));
                    result = false;
                }
            //}

            
            return result;
        }

        public OpenCodeResult captureOpencodeFromUrl()
        {
            OpenCodeResult result = new OpenCodeResult();

            Byte[] pageData = new WebClient().DownloadData("https://hb11x5.icaile.com/chart/?top=-1");
            string pageHtml = Encoding.UTF8.GetString(pageData);

            Regex re = new Regex(@"<td class=""rline period"">(\d{6})-(\d{2})</td>[\S\s]{0,}?>(\d{2})</td>[\S\s]{0,}?>(\d{2})</td>[\S\s]{0,}?>(\d{2})</td>[\S\s]{0,}?>(\d{2})</td>[\S\s]{0,}?>(\d{2})</td>");
            MatchCollection matches = re.Matches(pageHtml);
            foreach (Match match in matches)
            {
                string opencode_e = string.Format("{0},{1},{2},{3},{4}", match.Groups[3].Value, match.Groups[4].Value, match.Groups[5].Value, match.Groups[6].Value, match.Groups[7].Value);//电子票开奖号码
                string expect_e = string.Format("{0}{1}", match.Groups[1].Value, match.Groups[2].Value);//电子票期号
                result.OpenCodeList.Add(new OpenCodeEntity(expect_e, opencode_e));
            }

            return result;
        }

        public OpenCodeResult DecodeDlData(CaptureDataInfo captureData)
        {
            OpenCodeResult result = new OpenCodeResult();
            result.CaptureData = captureData;

            /*
@c3\n
c4\0(F\0\0?(F\0\0?3M\0!\0a\0L\0\0W\0E\0KJrL\0\0W\0M!a3开  奖  结  果  报  表\n
\n
M\0!\0a\0玩法名称: 江西多乐彩\r\n
报表日期: 2013-09-03\r\n
查询时间: 2013-09-03 22:01:07\r\n
起止奖期: 090301 - 090378\r\n
奖期   开奖结果    奖期   开奖结果   \r\n
378 08+03+11+02+07 339 09+11+06+07+05\r\n
377 05+01+07+10+06 338 11+07+02+08+03\r\n
376 02+09+08+10+06 337 01+06+08+11+04\r\n
375 06+07+03+05+09 336 10+01+07+03+08\r\n
374 05+09+11+02+08 335 03+02+10+09+07\r\n
373 09+04+01+02+03 334 11+10+09+03+06\r\n
372 09+01+05+03+06 333 03+09+11+07+01\r\n
371 03+11+01+06+09 332 03+08+05+07+01\r\n
370 03+10+05+09+02 331 06+01+09+04+11\r\n
369 02+01+05+07+06 330 01+03+07+02+09\r\n
368 03+05+07+04+10 329 03+08+02+05+11\r\n
367 08+03+02+01+09 328 11+03+04+06+02\r\n
366 08+03+07+09+01 327 10+07+11+02+01\r\n
365 11+01+09+02+03 326 10+06+02+07+01\r\n
364 02+05+11+04+07 325 03+08+09+07+10\r\n
363 06+11+09+07+01 324 04+01+08+11+02\r\n
362 06+05+03+02+07 323 05+07+11+10+09\r\n
361 07+04+01+05+02 322 10+05+08+01+06\r\n
360 10+04+05+08+07 321 04+10+03+11+09\r\n
359 08+03+11+01+04 320 01+09+11+10+07\r\n
358 07+02+06+11+01 319 11+01+07+06+09\r\n
357 09+03+06+05+02 318 03+07+02+09+01\r\n
356 09+03+10+04+01 317 05+03+10+01+11\r\n
355 06+09+04+05+10 316 01+09+02+03+11\r\n
354 09+08+01+02+07 315 07+02+04+06+05\r\n
353 10+02+04+05+03 314 04+07+03+02+09\r\n
352 02+04+01+07+08 313 03+07+09+04+05\r\n
351 11+08+09+06+10 312 04+05+10+06+03\r\n
350 10+07+03+02+04 311 02+07+05+08+03\r\n
349 05+01+02+08+04 310 06+01+10+08+07\r\n
348 05+01+02+10+04 309 03+10+08+05+07\r\n
347 02+03+10+04+07 308 09+01+03+02+10\r\n
346 03+04+06+11+02 307 09+10+06+08+02\r\n
345 11+01+05+09+10 306 02+08+10+11+07\r\n
344 07+02+11+01+09 305 02+06+04+09+11\r\n
343 01+02+08+04+05 304 04+10+01+03+07\r\n
342 10+05+03+06+04 303 03+09+05+07+02\r\n
341 07+03+09+08+06 302 08+03+02+01+07\r\n
340 09+04+10+05+07 301 06+10+07+04+05\r\n
\n
3 \n
 \n
 \n
 \n
 \fV
             */

            string input = captureData.CaptureDataString;
            //彩种
            Regex regex = new Regex(@"玩法名称[:|：]\s{0,}(.*)");
            Match match = regex.Match(input);
            if (!match.Success)
            {
                result.ErrorMessage = "没有找到彩种信息";
                result.DecodeSuccess = false;
                return result;
            }
            if (match.Groups.Count != 2)
            {
                result.ErrorMessage = string.Format("解析彩种错误，字符串：{0}", match.Value);
                result.DecodeSuccess = false;
                return result;
            }
            result.LotName = match.Groups[1].Value;
            if (result.LotName.IndexOf("江西多乐彩") < 0 && result.LotName.IndexOf("湖北11选5") < 0)
            {
                result.ErrorMessage = "彩种错误";
                result.DecodeSuccess = false;
                return result;
            }
            //报表日期
            regex = new Regex(@"报表日期[:|：]\s{0,}\d{4}-\d{2}-\d{2}");
            match = regex.Match(input);
            if (!match.Success)
            {
                result.ErrorMessage += "没有找到报表日期";
                result.DecodeSuccess = false;
                return result;
            }
            string strTemp = match.Value;
            strTemp = Regex.Replace(strTemp, @"报表日期[:|：]\s{0,}", "");
            strTemp = strTemp.Trim();
            DateTime reportdate;
            bool sucReportDate = DateTime.TryParse(strTemp, out reportdate);
            if (sucReportDate)
            {
                result.ReportDate = reportdate;
            }
            //查询时间
            regex = new Regex(@"查询时间[:|：]\s{0,}\d{4}-\d{2}-\d{2}\s{1,}\d{2}:\d{2}:\d{2}");
            match = regex.Match(input);
            if (!match.Success)
            {
                result.ErrorMessage += "没有找到查询时间";
                result.DecodeSuccess = false;
                return result;
            }
            strTemp = match.Value;
            strTemp = Regex.Replace(strTemp, @"查询时间[:|：]\s{0,}", "");
            strTemp = strTemp.Trim();
            strTemp = Regex.Replace(strTemp, @"\s+", " ");
            DateTime querytime;
            bool sucQueryTime = DateTime.TryParse(strTemp, out querytime);
            if (sucQueryTime)
            {
                result.QueryTime = querytime;
            }
            //起止奖期
            //regex = new Regex(@"起止奖期[:|：]\s{0,}\d{6}\s{0,}-\s{0,}\d{6}");
            regex = new Regex(@"起止奖期[:|：]\s{0,}\d{6,8}\s{0,}-\s{0,}\d{6,8}");
            match = regex.Match(input);
            if (!match.Success)
            {
                result.ErrorMessage += "没有找到起止奖期";
                result.DecodeSuccess = false;
                return result;
            }
            strTemp = match.Value;
            strTemp = Regex.Replace(strTemp, @"起止奖期[:|：]\s{0,}", "");
            string[] arr = strTemp.Split('-');
            if(arr.Length!=2)
            {
                result.ErrorMessage += "起止奖期解析错误";
                result.DecodeSuccess = false;
                return result;
            }
            string expectPrefix = DateTime.Now.ToString("yy");
            string beginExpect = arr[0].Trim().Length == 6 ? expectPrefix + arr[0].Trim() : arr[0].Trim();
            string endExpect = arr[1].Trim().Length == 6 ? expectPrefix + arr[1].Trim() : arr[1].Trim();
            if (beginExpect.Length != 8 || endExpect.Length != 8)
            {
                result.ErrorMessage += "起止奖期长度错误";
                result.DecodeSuccess = false;
                return result;
            }
            result.BeginExpect = beginExpect;
            result.EndExpect = endExpect;
            //开奖结果
            string[] inputLines = input.Split('\n');
            int beginLineNum = -1;
            for (int i = 0; i < inputLines.Length; i++)
            {
                string line = inputLines[i];
                if(!string.IsNullOrEmpty(line) && line.IndexOf("奖期")>=0 && line.IndexOf("开奖结果")>=0)
                {
                    beginLineNum = i+1;//下一行即为开奖结果列表
                    break;
                }
            }
            if(beginLineNum<0)
            {
                result.ErrorMessage += "开奖结果起始行未找到";
                result.DecodeSuccess = false;
                return result;
            }
            
            for (int i = beginLineNum; i < inputLines.Length; i++)
            {
                string line = inputLines[i];
                if (line.Length < 18)//340 09+04+10+05+07
                {
                    break;
                }
                regex = new Regex(@"\d{3}\s{1,}\d\d\+\d\d\+\d\d\+\d\d\+\d\d");
                MatchCollection machCollection = regex.Matches(line);
                if (machCollection.Count < 1)
                {
                    result.ErrorMessage = "没有找到开奖结果";
                    result.DecodeSuccess = false;
                    return result;
                }
                foreach (Match match1 in machCollection)
                {
                    string opencodestr = match1.Value.Trim();
                    string expectsuffix_e = opencodestr.Substring(0, 3).Trim();//电子票期号后缀
                    string opencode_e = opencodestr.Substring(4).Trim().Replace("+", ",");//电子票开奖号码
                    string expect_e = DateTime.Now.ToString("yyyyMMdd").Substring(2, 5) + expectsuffix_e;//电子票期号
                    result.OpenCodeList.Add(new OpenCodeEntity(expect_e,opencode_e));
                }
            }
            
            result.DecodeSuccess = true;
            return result;
        }



        /// <summary>
        /// 更新彩票机对阵到数据库
        /// </summary>
        public void UpdateMachineOpenCodeToLotteryDb(OpenCodeResult openCodeResult, ILog log)
        {
            try
            {
                List<string> waitOpenExpectList = ExpectTaskService.getWaitOpenExpectList();
                foreach (OpenCodeEntity entity in openCodeResult.OpenCodeList)
                {
                    if (!waitOpenExpectList.Contains(entity.Expect))
                    {
                        continue;
                    }

                    A10008UploadOpenCode pack = new A10008UploadOpenCode();
                    pack.AgentId = _lotMachine.MachineInfo.M_Number;
                    pack.Salt = _lotMachine.MachineInfo.M_Salt;
                    pack.LotId = _lotid;
                    pack.Expect = entity.Expect;
                    pack.OpenCode = entity.OpenCode;
                    A10008UploadOpenCodeRet packRet = PackManager.Instance.Send(pack) as A10008UploadOpenCodeRet;
                    if (packRet.Code <= 0)
                    {
                        _lotMachine.Log.Warn(_lotMachine.MachineInfo.M_Number + " 上传开奖号码失败：" + packRet.Code.ToString() + "" + packRet.Message);
                    }
                    else
                    {
                        ExpectTaskService.setNotifySuc(pack.Expect);
                        _lotMachine.Log.Info(_lotMachine.MachineInfo.M_Number + " 上传开奖号码成功：" + pack.Expect + "---" + pack.OpenCode);
                    }
                }

            }
            catch (Exception exception1)
            {
                _lotMachine.Log.Warn(string.Concat("上传开奖号码异常。错误信息：", exception1));
            }



            //L_ExpectService expectService = new L_ExpectService();
            //Database database = DBSetting.Instance.GetDataBase("dldb");
            //SqlConnection conn = null;
            //try
            //{
            //    conn = new SqlConnection(database.ConnectionString);
            //    conn.Open();
            //    string expectPrefix = DateTime.Now.ToString("yyMMdd");
            //    if (!openCodeResult.BeginExpect.StartsWith(expectPrefix) || !openCodeResult.EndExpect.StartsWith(expectPrefix))
            //    {
            //        log.Warn(string.Concat("起止奖期 ", openCodeResult.BeginExpect,"-",openCodeResult.EndExpect, " 非当天期号，不允许添加，请检查机器开奖号码及获取开奖是否有异常"));
            //        return;
            //    }
            //    foreach (OpenCodeEntity openCodeEntity in openCodeResult.OpenCodeList)
            //    {
            //        L_ExpectEntity expectEntity = expectService.GetExpect(lotId, openCodeEntity.Expect);
            //        if (expectEntity != null)
            //        {
            //            DateTime opentime = expectEntity.E_OpenTime.AddMinutes(-1);
            //            if (DateTime.Now < opentime)
            //            {
            //                log.Warn(string.Concat("期号 ", expectEntity.E_Expect, "开奖时间为：", opentime, " 当前时间", DateTime.Now, " 还没到开奖时间 不允许添加，请检查机器开奖号码及获取开奖是否有异常"));
            //                continue;
            //            }
            //            if (expectEntity.E_OpenCode == openCodeEntity.OpenCode)
            //            {
            //                log.Info(string.Concat("期号 ", openCodeEntity.Expect, " 开奖号码 ", openCodeEntity.OpenCode, " 数据库已存在"));
            //            }
            //            else
            //            {
            //                if(!string.IsNullOrEmpty(expectEntity.E_OpenCode))
            //                {
            //                    log.Warn(string.Concat("期号 ", openCodeEntity.Expect, " 开奖号码不一致，数据库：", expectEntity.E_OpenCode," 彩票机：", openCodeEntity.OpenCode, "，请检查核对"));
            //                }
            //            }

            //            if (expectEntity.E_Status == (int)ExpectStatus.WaitOpen || expectEntity.E_OpenCode != openCodeEntity.OpenCode)
            //            {
            //                expectEntity.E_OpenCode = openCodeEntity.OpenCode;
            //                expectEntity.E_GetOpenCodeTime = openCodeResult.QueryTime;
            //                expectEntity.E_Status = (int)ExpectStatus.WaitSetPrize;
            //                expectService.UpdateOpenCodeInformationAndStatus(expectEntity);
            //                Dl_ExpectDao dlExpectDao = new Dl_ExpectDao();
            //                dlExpectDao.UpdateUploadStatus(expectEntity.E_Expect, NotifyStatus.NotifyAble);
            //                log.Info(string.Concat("期号 ", openCodeEntity.Expect, " 开奖号码 ", openCodeEntity.OpenCode, " 更新到数据库"));
            //            }
            //        }
                    
            //    }
            //}
            //finally
            //{
            //    if (conn != null)
            //    {
            //        conn.Close();
            //    }
            //}
        }


       
    }
}
