using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using ChuPiao.AutoPrint.Machine.Models;
using ChuPiao.Common.Core.Utils;
using ChuPiao.Common.Enums;
using ChuPiao.Common.Models;

namespace ChuPiao.AutoPrint.Machine.TjJingCaiV1.MacLotPlayMode
{
    /// <summary>
    /// 竟彩名次冠军
    /// </summary>
    public class MacLotPlayModeJmGjService : MacLotPlayModeService
    {
        public MacLotPlayModeJmGjService()
        {
            PlayFullName = "竞彩名次-冠军";
        }
        #region Overrides of MacLotPlayModeService

        /// <summary>
        /// 机器投注模式配置信息
        /// </summary>
        /// <summary>
        /// 获得投注需要发送的键码列表
        /// </summary>
        /// <param name="ticketEntity"></param>
        /// <param name="machineEntity"></param>
        /// <returns></returns>
        public override List<KeycodeInfo> GetSendKeycodeList(L_LotTicketEntity ticketEntity, M_MachineEntity machineEntity)
        {
            List<KeycodeInfo> keycodeList = new List<KeycodeInfo>();
            M_MachineModeConfigEntity machineModeConfig = machineEntity.MachineModeConfigs[ticketEntity.MacModeId];

            //初始化，每次都需要进入玩法的投注内容输入界面
            keycodeList.AddRange(GetInitKeycodeList(machineModeConfig));

            //赛事编号
            //01->[01,02,03]  01代表赛事编号，中括号内为投注内容
            string[] tmpArr = ticketEntity.L_Code.Split(MatchCodeSplitStr.ToCharArray());
            string seasonnum = tmpArr[0];
            string codes = tmpArr[1].Replace("[", "").Replace("]", "");
            for (int i = 0; i < seasonnum.Length; i++)
            {
                keycodeList.Add(new KeycodeInfo(seasonnum.Substring(i, 1), machineModeConfig.C_SendKeyInterval));
            }

            keycodeList.Add(new KeycodeInfo("wait", machineModeConfig.C_PrintConfirmKeyInterval));
            //投注号码
            string[] codeArr = codes.Split(',');
            foreach (string s in codeArr)
            {
                for (int i = 0; i < s.Length; i++)
                {
                    keycodeList.Add(new KeycodeInfo(s.Substring(i, 1), machineModeConfig.C_SendKeyInterval));
                }
            }
            //投注号码确认
            keycodeList.Add(new KeycodeInfo(ResultEnterKey, machineModeConfig.C_SendKeyInterval));

            //倍投)
            if (ticketEntity.L_Mutiple > 1)
            {
                keycodeList.AddRange(GetMultipleKeycodeList(ticketEntity.L_Mutiple, machineModeConfig));
            }
            //打印确认
            keycodeList.Add(new KeycodeInfo(machineModeConfig.C_PrintConfirmKey, machineModeConfig.C_PrintConfirmKeyInterval));

            //是否输入密码
            keycodeList.AddRange(GetPasswordKeycodeList(ticketEntity, machineEntity, machineModeConfig));

            return keycodeList;
        }

        /// <summary>
        /// 电子票解析
        /// </summary>
        /// <param name="machineEntity"></param>
        /// <param name="decodePrintData"></param>
        /// <param name="ticketEntity"></param>
        /*public override void DecodeData(L_LotTicketEntity ticketEntity, M_MachineEntity machineEntity, DecodePrintData decodePrintData)
        {
            M_MachineModeConfigEntity machineModeConfig = machineEntity.MachineModeConfigs[ticketEntity.MacModeId];

            //抓取的返回
            decodePrintData.L_PrintTicketEntity.P_PrnText = TicketTextUtil.CompressAndEncrypt(decodePrintData.InputData.CaptureDataBytes);

            string input = decodePrintData.InputData.CaptureDataString;
            string strTemp;
            //票号、密码、期号解析
            bool suc = DecodeHeadJc(ticketEntity, machineEntity, decodePrintData);
            if (!suc)
            {
                decodePrintData.ErrorMessage = string.Format("头部解析错误：{0}", decodePrintData.ErrorMessage);
                decodePrintData.DecodeSuccess = false;
                return;
            }

            //金额
            Regex regex = new Regex(RegexMoney);
            Match match = regex.Match(input);
            if (!match.Success)
            {
                decodePrintData.ErrorMessage += "没有找到金额";
                decodePrintData.DecodeSuccess = false;
                return;
            }
            string money = Regex.Replace(match.Value, @"\D", "");
            decodePrintData.L_PrintTicketEntity.P_Money = decimal.Parse(money);
            if (decimal.Parse(money) != ticketEntity.L_Money)
            {
                decodePrintData.ErrorMessage += string.Format("金额不匹配，软件金额：{0} 电子票金额：{1}", ticketEntity.L_Money,
                                                              money);
                decodePrintData.DecodeSuccess = false;
                return;
            }
            //出票时间
            try
            {
                regex = new Regex(RegexSucTime);
                match = regex.Match(input);
                decodePrintData.L_PrintTicketEntity.P_SucTime = DateTime.Parse(match.Value);
            }
            catch (Exception exception)
            {
                decodePrintData.ErrorMessage += string.Concat("获取出票时间不正确。错误信息：", exception.Message);
                decodePrintData.DecodeSuccess = false;
                return;
            }

            #region 投注号码及赔率
            List<string> dCodeList = new List<string>();
            List<string> dRateList = new List<string>();
            //金额
            int startposition = input.IndexOf(decodePrintData.L_PrintTicketEntity.P_TicketCode) + 60;
            int endposition = input.IndexOf("*", startposition);
            if (endposition < 1)
            {
                endposition = input.IndexOf("倍数", startposition);
            }

            strTemp = input.Substring(startposition, endposition - startposition);//包含投注内容的字符串

            strTemp = Regex.Replace(strTemp,"\n","");

            //regex = new Regex(@"\(\d{2}\s[^\)]*\)\@\d{1,}\.\d{1,}元");//(39 英格兰-乌克兰)@1000元
            //特别注意赔率可能为整数
            regex = new Regex(@"\(\d{2}\s[^\)]*\)\@\d{1,}(\.\d{1,}){0,1}元");//(01 西班牙)@2.000元+(02 德国)@2.200元

            MatchCollection matchCollection = regex.Matches(strTemp);
            foreach (Match matchCode in matchCollection)
            {
                strTemp = matchCode.Value;
                int position = strTemp.IndexOf("@");
                string code = strTemp.Substring(1, 2);
                string rateStr = strTemp.Substring(position).Replace("@", "").Replace("元", "").Replace(",", "");

                if (machineModeConfig.C_IsCheckCode)
                {
                    decimal rate = 0;
                    bool result = decimal.TryParse(rateStr, out rate);
                    if (!result)
                    {
                        decodePrintData.ErrorMessage += string.Concat("解析赔率失败：", strTemp);
                        decodePrintData.DecodeSuccess = false;
                        return;
                    }
                }
                dCodeList.Add(code);
                dRateList.Add(string.Format("{0}#{1}", code, rateStr));//赔率格式：01#2.000,02#2.200
            }

            //赛事编号
            string seasonnum = ticketEntity.L_Code.Split(MatchCodeSplitStr.ToCharArray())[0];
            if (machineModeConfig.C_IsCheckCode)
            {
                //检测投注内容是否一致
                string tmpGetCode = string.Format("{0}→[{1}]", seasonnum, string.Join(SplitStr, dCodeList.ToArray()));
                if (ticketEntity.L_Code != tmpGetCode)
                {
                    decodePrintData.ErrorMessage += string.Format("投注号码不正确,软件的号码是：{0},电子票的号码是：{1}", ticketEntity.L_Code, tmpGetCode);
                    decodePrintData.DecodeSuccess = false;
                    return;
                }
            }
            //赔率
            decodePrintData.L_PrintTicketEntity.L_CodeRate = string.Format("{0}→[{1}]", seasonnum, string.Join(SplitStr, dRateList.ToArray()));

            //投注内容
            decodePrintData.L_PrintTicketEntity.P_Code = ticketEntity.L_Code;
            #endregion

            decodePrintData.DecodeSuccess = true;
        }
        */
        public override void DecodeData(L_LotTicketEntity ticketEntity, M_MachineEntity machineEntity, DecodePrintData decodePrintData)
        {
            M_MachineModeConfigEntity machineModeConfig = machineEntity.MachineModeConfigs[ticketEntity.MacModeId];

            //抓取的返回
            decodePrintData.L_PrintTicketEntity.P_PrnText = TicketTextUtil.CompressAndEncrypt(decodePrintData.InputData.CaptureDataBytes);

            string prnText = decodePrintData.InputData.CaptureDataString;
            try
            {
                if (prnText.Length < 1)
                {
                    throw new Exception("电子票的长度为0");
                }
                string[] prntextArr = prnText.Split('\n');
                int startLine = -1;// 起始行：中国体育彩票
                for (int k = 0; k < prntextArr.Length; k++)
                {
                    if (prntextArr[k].Contains("中国体育彩票"))
                    {
                        startLine = k;
                        break;
                    }
                }
                if (startLine < 0)
                {
                    throw new Exception("没有找到中国体育彩票字样");
                }
                int playCodetypeLine = startLine + 1;// 起始行的下一行为玩法和号码类型：竞彩名次-冠军   单场固定
                if (playCodetypeLine >= prntextArr.Length)
                {
                    throw new Exception("玩法和号码类型解析失败");
                }
                if (prntextArr[playCodetypeLine].IndexOf(PlayFullName, System.StringComparison.Ordinal) < 0)
                {
                    throw new Exception("玩法不匹配");
                }
                string codetype = DecodeUtil.CodeTypeToString(ticketEntity.L_CodeType);
                if (prntextArr[playCodetypeLine].IndexOf(codetype, System.StringComparison.Ordinal) < 0)
                {
                    throw new Exception("号码类型不匹配");
                }
                // 玩法和号码类型的下一行为票号：20360571303672965633 B53BA5CC 00631957
                int ticketCodeLine = playCodetypeLine + 1;
                if (ticketCodeLine >= prntextArr.Length)
                {
                    throw new Exception("票号解析失败");
                }
                const string regexTicketCode = "([0-9]{20})\\s{1,}([a-zA-Z0-9\\*\\>\\<]{8})\\s{1,}([0-9]{8})";
                Match mTicketCode = new Regex(regexTicketCode).Match(prntextArr[ticketCodeLine]);
                if (!mTicketCode.Success)
                {
                    throw new Exception("没有找到票号");
                }
                if (mTicketCode.Groups.Count != 4)
                {
                    throw new Exception("票号正则匹配失败");
                }
                string ticketCode = mTicketCode.Groups[1].Value;
                string randomCode = mTicketCode.Groups[2].Value;
                string password = mTicketCode.Groups[3].Value;
                decodePrintData.L_PrintTicketEntity.P_TicketCode = ticketCode;
                decodePrintData.L_PrintTicketEntity.P_RandomCode = randomCode;
                decodePrintData.L_PrintTicketEntity.P_Password = password;

                // 以下处理投注内容
                int i = ticketCodeLine;
                i++;// ─────────────────────
                i++;// 01	2012欧洲杯
                Regex regexSeason = new Regex(@"\d{2}");
                Match matchSeason = regexSeason.Match(prntextArr[i]);
                if (!matchSeason.Success)
                {
                    throw new Exception("赛事编号正则匹配失败");
                }
                //赛事编号
                string seasonnum = matchSeason.Value;
                i++;//(01 西班牙)@1.850元+(02 德国)@2.050元
                int betContentStartLine = i;// 投注内容起始行
                int betContentEndLine = i;// 投注内容结束行
                string betContent = "";
                while (i < prntextArr.Length)
                {
                    if (prntextArr[i].Contains("选项固定奖金额") || prntextArr[i].Contains("*  *  *"))
                    {
                        break;
                    }
                    betContent += prntextArr[i];
                    betContentEndLine = i;
                    i++;
                }
                // 场次编号、主客队、投注号码
                int betContentLineCount = betContentEndLine - betContentStartLine + 1;
                if (betContentLineCount < 1)
                {
                    throw new Exception("投注内容不完整，少于1行");
                }
                // 解析投注内容
                List<string> dCodeList = new List<string>();
                List<string> dRateList = new List<string>();
                //特别注意赔率可能为整数
                Regex regex = new Regex(@"\(\d{2}\s[^\)]*\)\@\d{1,}(\.\d{1,}){0,1}元");//(01 西班牙)@2.000元+(02 德国)@2.200元
                MatchCollection matchCollection = regex.Matches(betContent);
                foreach (Match matchCode in matchCollection)
                {
                    string strTemp = matchCode.Value;
                    int position = strTemp.IndexOf("@");
                    string code = strTemp.Substring(1, 2);
                    string rateStr = strTemp.Substring(position).Replace("@", "").Replace("元", "").Replace(",", "");

                    if (machineModeConfig.C_IsCheckCode)
                    {
                        decimal rate = 0;
                        bool result = decimal.TryParse(rateStr, out rate);
                        if (!result)
                        {
                            throw new Exception(string.Concat("解析赔率失败：", strTemp));
                        }
                    }
                    dCodeList.Add(code);
                    dRateList.Add(string.Format("{0}#{1}", code, rateStr));//赔率格式：01#2.000,02#2.200
                }

                if (machineModeConfig.C_IsCheckCode)
                {
                    //检测投注内容是否一致
                    string tmpGetCode = string.Format("{0}→[{1}]", seasonnum, string.Join(SplitStr, dCodeList.ToArray()));
                    if (ticketEntity.L_Code != tmpGetCode)
                    {
                        throw new Exception(string.Format("投注号码不正确,软件的号码是：{0},电子票的号码是：{1}", ticketEntity.L_Code, tmpGetCode));
                    }
                }

                // 本票最高可能固定奖金
                //if (ticketEntity.L_RateType == (int)JcRateType.Fixed)
                //{
                //    int maxGetMoneyLine = -1;
                //    while (i < prntextArr.Length)
                //    {
                //        if (prntextArr[i].Contains("本票最高可能固定奖金"))
                //        {
                //            maxGetMoneyLine = i;
                //            break;
                //        }
                //        i++;
                //    }
                //    if (maxGetMoneyLine < 0)
                //    {
                //        throw new Exception("没有找到本票最高可能固定奖金字样");
                //    }
                //    Match mMaxGetMoney = new Regex("本票最高可能固定奖金:[\\d,]{1,}(\\.\\d{1,2})?元").Match(prntextArr[maxGetMoneyLine]);
                //    if (!mMaxGetMoney.Success)
                //    {
                //        throw new Exception("本票最高可能固定奖金正则匹配失败");
                //    }
                //    try
                //    {
                //        string sMaxGetMoney = mMaxGetMoney.Value.Replace("本票最高可能固定奖金:", "").Replace("元", "").Replace(",", "");
                //        ticketEntity.L_MaxGetMoney = decimal.Parse(sMaxGetMoney);
                //    }
                //    catch (Exception ex)
                //    {
                //        throw new Exception("本票最高可能固定奖金错误：" + ex.Message);
                //    }
                //}
                int multipleLine = -1;
                while (i < prntextArr.Length)
                {
                    if (prntextArr[i].Contains("倍数"))
                    {
                        multipleLine = i;
                        break;
                    }
                    i++;
                }
                if (multipleLine < 0)
                {
                    throw new Exception("没有找到倍数字样");
                }
                // 倍数:1 合计: 2元 2012-02-16 17:53:36
                const string regexMultipleMoneyTime = "倍数[:|：]\\s{0,}(\\d{1,2})\\s{1,}合计[:|：]\\s{0,}(\\d{1,})元\\s{1,}(\\d{4}-\\d{2}-\\d{2}\\s{1,}\\d{2}:\\d{2}:\\d{2})";
                Match mMultipleMoneyTime = new Regex(regexMultipleMoneyTime).Match(prntextArr[multipleLine]);
                if (!mMultipleMoneyTime.Success)
                {
                    throw new Exception("没有找到倍数金额出票时间");
                }
                if (mMultipleMoneyTime.Groups.Count != 4)
                {
                    throw new Exception("倍数金额出票时间正则匹配失败");
                }
                int multiple = int.Parse(mMultipleMoneyTime.Groups[1].Value);
                decimal money = decimal.Parse(mMultipleMoneyTime.Groups[2].Value);

                string strSucTime = Regex.Replace(mMultipleMoneyTime.Groups[3].Value, "\\s{1,}", " ");// 日期和时间之间可能有多个空格
                DateTime suctime;
                try
                {
                    suctime = DateTime.Parse(strSucTime);//"yyyy-MM-dd HH:mm:ss"
                }
                catch (Exception e)
                {
                    throw new Exception("出票时间解析失败：" + e.Message);
                }
                // 出票时间
                decodePrintData.L_PrintTicketEntity.P_SucTime = suctime;
                if (multiple != ticketEntity.L_Mutiple)
                {
                    throw new Exception("倍数不匹配，软件：" + ticketEntity.L_Mutiple + " 电子票：" + multiple);
                }
                if (money != ticketEntity.L_Money)
                {
                    throw new Exception("金额不匹配，软件：" + ticketEntity.L_Money + " 电子票：" + money);
                }
                int saleAddressLine = multipleLine + 1;// 倍数的下一行为中心机器号：201415901 宜春市中山南路
                if (saleAddressLine >= prntextArr.Length)
                {
                    throw new Exception("销售网点编号解析失败");
                }
                Match mZxNumber = new Regex("\\d{9}").Match(prntextArr[saleAddressLine]);
                if (!mZxNumber.Success)
                {
                    throw new Exception("销售网点编号正则匹配失败");
                }
                // 销售网点编号 去掉头部2位及尾部2位，中间5位数字为中心机器号
                string saleaddress = mZxNumber.Value.Substring(2, 5);
                decodePrintData.L_PrintTicketEntity.P_SaleAddress = saleaddress;



                //赔率
                decodePrintData.L_PrintTicketEntity.L_CodeRate = string.Format("{0}→[{1}]", seasonnum, string.Join(SplitStr, dRateList.ToArray()));

                //投注内容
                decodePrintData.L_PrintTicketEntity.P_Code = ticketEntity.L_Code;
                decodePrintData.DecodeSuccess = true;
            }
            catch (Exception ex)
            {
                decodePrintData.ErrorMessage = ex.Message;
                decodePrintData.DecodeSuccess = false;
            }

        }
        #endregion
    }
}
