using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using ChuPiao.AutoPrint.Machine.Models;
using ChuPiao.Common.Enums;
using ChuPiao.Common.Models;

namespace ChuPiao.AutoPrint.Machine
{
    public class NumberGenerator
    {
        private static long BaseNumber = long.Parse(DateTime.Now.ToString("yyMMddHHmmssffffff"));
        private static Random RandomObject = new Random();

        /// <summary>
        /// 返回唯一的票号
        /// </summary>
        /// <returns></returns>
        public static string GetUniqueTicketCode()
        {
            return string.Format("20{0}{1}", DateTime.Now.ToString("yyMMddHHmmssffffff"), GetRandomNumber(6));
        }
        /// <summary>
        /// 返回唯一的票号
        /// </summary>
        /// <returns></returns>
        public static string GetOnlyTicketCode()
        {
            return string.Format("20{0}", Interlocked.Increment(ref BaseNumber));
        }
        /// <summary>
        /// 返回指定位数的随机数
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static string GetRandomNumber(int number)
        {
            int min = 1;
            int max = 10;
            if (number > 1)
            {
                for (int i = 1; i < number; i++)
                {
                    min *= 10;
                }
                max = min * 10;
            }
            return RandomObject.Next(min, max).ToString();
        }
        /// <summary>
        /// 返回指定位数的随机数
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static string GetRandomLetterOrNumber(int number)
        {
            string[] arr = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,0,1,2,3,4,5,6,7".Split(',');
            string result = "";
            for (int i = 0; i < number; i++)
            {
                int position = RandomObject.Next(0, arr.Length);
                result += arr[position];
            }
            return result;
        }
    }
    /// <summary>
    /// 模拟生成票
    /// </summary>
    public class TicketSimulator
    {
        /// <summary>
        /// 模拟生成票
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="decodePrintData"></param>
        public static void Build(L_LotTicketEntity entity, DecodePrintData decodePrintData)
        {
            switch (entity.LotId)
            {
                case 911:
                case 951:
                    BuildJc(entity,decodePrintData);
                    break;
                case 901:
                    BuildBd(entity, decodePrintData);
                    break;
                default:
                    BuildCg(entity);
                    break;
            }
            
        }

        private static void BuildCg(L_LotTicketEntity entity)
        {
            //票号、随机码、密码
            entity.L_TicketCode = NumberGenerator.GetUniqueTicketCode();
            entity.L_Password = NumberGenerator.GetRandomNumber(8);
            entity.L_RandomCode = NumberGenerator.GetRandomLetterOrNumber(6);
            entity.L_SucTime = DateTime.Now;
            entity.L_Status = (int)TicketStatus.Suc;
            entity.L_LimitType = 0;
            entity.L_NotifyStatus = (int)NotifyStatus.NotifyAble;
        }

        private static void BuildBd(L_LotTicketEntity entity, DecodePrintData decodePrintData)
        {
            //票号、随机码、密码
            string ticketcode = NumberGenerator.GetOnlyTicketCode() + NumberGenerator.GetRandomNumber(4);
            entity.L_TicketCode = string.Format("{0}-{1}-{2}-{3}",ticketcode.Substring(0,6),ticketcode.Substring(6,6),ticketcode.Substring(12,6),ticketcode.Substring(18,6));
            entity.L_Password = NumberGenerator.GetRandomLetterOrNumber(13);
            entity.L_RandomCode = "";
            entity.L_SucTime = DateTime.Now;
            entity.L_Status = (int)TicketStatus.Suc;
            entity.L_LimitType = 0;
            entity.L_NotifyStatus = (int)NotifyStatus.NotifyAble;

            decodePrintData.L_PrintTicketEntity.P_TicketCode = entity.L_TicketCode;
            decodePrintData.L_PrintTicketEntity.P_RandomCode = entity.L_RandomCode;
            decodePrintData.L_PrintTicketEntity.P_Password = entity.L_Password;
            decodePrintData.L_PrintTicketEntity.P_SucTime = entity.L_SucTime;
            decodePrintData.L_PrintTicketEntity.P_SaleAddress = entity.L_SaleAddress = entity.L_MacNumber;
            decodePrintData.DecodeSuccess = true;
        }
        private static void BuildJc(L_LotTicketEntity entity, DecodePrintData decodePrintData)
        {
            CalculateTicketCode(entity);
            if (entity.LotId == 911)
            {
                    //4001→[1-3]/4010→[3-1,0-1,0-0]/4011→[1-0]
                    string[] arr = entity.L_Code.Split('/');
                    CalculateMostPayAndRate(entity, arr);

                entity.L_SucTime = DateTime.Now;
                entity.L_Status = (int)TicketStatus.Suc;
                entity.L_LimitType = 0;
                entity.L_NotifyStatus = (int)NotifyStatus.NotifyAble;
            }
            else
            {

                    //4001→[1-3]/4010→[3-1,0-1,0-0]/4011→[1-0]
                    string[] arr = entity.L_Code.Split('/');
                    CalculateMostPayAndRate(entity, arr);
                    if (entity.L_PlayId == (int)Playtype.JlRFSF)
                    {
                        entity.L_CodeReference = CalculateRangScore(arr);
                    }
                    else if (entity.L_PlayId == (int)Playtype.JlDXF)
                    {
                        entity.L_CodeReference = CalculatePretotalScore(arr);
                    }

                entity.L_SucTime = DateTime.Now;
                entity.L_Status = (int)TicketStatus.Suc;
                entity.L_LimitType = 0;
                entity.L_NotifyStatus = (int)NotifyStatus.NotifyAble;
            }

            decodePrintData.L_PrintTicketEntity.P_TicketCode = entity.L_TicketCode;
            decodePrintData.L_PrintTicketEntity.P_RandomCode = entity.L_RandomCode;
            decodePrintData.L_PrintTicketEntity.P_Password = entity.L_Password;
            decodePrintData.L_PrintTicketEntity.P_SucTime = entity.L_SucTime;
            decodePrintData.L_PrintTicketEntity.P_SaleAddress = entity.L_SaleAddress = entity.L_MacNumber;
            decodePrintData.L_PrintTicketEntity.L_CodeRate = entity.L_CodeRate;
            decodePrintData.L_PrintTicketEntity.L_MaxGetMoney = entity.L_MaxGetMoney;
            decodePrintData.L_PrintTicketEntity.L_CodeReference = entity.L_CodeReference;

            decodePrintData.DecodeSuccess = true;
        }
        private static void CalculateTicketCode(L_LotTicketEntity entity)
        {
            //票号、随机码、密码
            entity.L_TicketCode = NumberGenerator.GetOnlyTicketCode();
            entity.L_Password = NumberGenerator.GetRandomNumber(8);
            entity.L_RandomCode = NumberGenerator.GetRandomNumber(8);
        }
        private static Random _random = new Random();
        /// <summary>
        /// 计算固赔的最大获奖金额和赔率
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        protected static void CalculateMostPayAndRate(L_LotTicketEntity entity, string[] arr)
        {
            //计算最高可能赔付金额
            decimal tmppaymoney = 1;
            List<string> peilvs = new List<string>();
            foreach (string s in arr)
            {
                string[] arr2 = s.Split('[');
                string[] arr3 = arr2[1].Replace("]", "").Split(',');
                List<string> results = new List<string>();
                decimal maxTmprate = 0;
                foreach (string s1 in arr3)
                {
                    decimal tmprate = (decimal)_random.NextDouble() * 10;
                    if (tmprate < 1)
                    {
                        tmprate = 1 + tmprate;
                    }
                    if (tmprate > maxTmprate)
                    {
                        maxTmprate = tmprate;
                    }
                    results.Add(s1 + "#" + tmprate.ToString("0.00"));
                }
                tmppaymoney *= decimal.Parse(maxTmprate.ToString("0.00"));
                peilvs.Add(arr2[0] + "[" + string.Join(",", results.ToArray()) + "]");
            }
            entity.L_CodeRate = string.Join("/", peilvs.ToArray());
            tmppaymoney *= 2;
            tmppaymoney = MoneyDropTail(tmppaymoney);
            tmppaymoney *= entity.L_Mutiple;
            entity.L_MaxGetMoney = tmppaymoney;
        }
        private static decimal MoneyDropTail(decimal money)
        {
            //string moneyStr = money.ToString();
            //StringBuilder sb = new StringBuilder();
            //int count = 0;
            //foreach (char ch in moneyStr)
            //{
            //    if (ch != '.' && count == 0)
            //    {
            //        sb.Append(ch);
            //    }
            //    else
            //    {
            //        if (count <= 3)
            //        {
            //            sb.Append(ch);
            //        }
            //        else
            //        {
            //            break;
            //        }
            //        count++;
            //    }
            //}
            //money = Decimal.Parse(sb.ToString());
            //money = Math.Round(money, 2, MidpointRounding.ToEven);
            //return money; 

            if (money > 1000000)
            {
                return 1000000;
            }
            money = ((int)(money * 1000)) / 1000.0M;
            money = Math.Round(money, 2, MidpointRounding.ToEven);
            return money; 
        }

        /// <summary>
        /// 计算预设让分
        /// </summary>
        /// <param name="splitCode"></param>
        /// <returns></returns>
        private static string CalculateRangScore(string[] splitCode)
        {
            List<string> shuiweis = new List<string>();
            foreach (string s in splitCode)
            {
                string[] arr = s.Split('→');
                List<string> results = new List<string>();
                string tmpStr = string.Concat("主", _random.Next(0, 100) > 50 ? "+" : "-",
                                              _random.Next(1, 50) + 0.5);
                results.Add(tmpStr);
                tmpStr = string.Concat("主", _random.Next(0, 100) > 50 ? "+" : "-",
                                              _random.Next(1, 50) + 0.5);
                results.Add(tmpStr);
                shuiweis.Add(arr[0] + "→" + "[" + string.Join(",", results.ToArray()) + "]");
            }
            return string.Join("/", shuiweis.ToArray());
        }
        /// <summary>
        /// 计算预设总分
        /// </summary>
        /// <param name="splitCode"></param>
        /// <returns></returns>
        private static string CalculatePretotalScore(string[] splitCode)
        {
            List<string> shuiweis = new List<string>();
            foreach (string s in splitCode)
            {
                string[] changci = s.Split('→');
                string[] arr = changci[1].Replace("[", "").Replace("]", "").Split(',');
                List<string> results = new List<string>();
                string tmpStr = string.Concat(_random.Next(100, 200) + 0.5);
                results.Add(tmpStr);
                tmpStr = string.Concat(_random.Next(100, 200) + 0.5);
                results.Add(tmpStr);
                shuiweis.Add(changci[0] + "→" + "[" + string.Join(",", results.ToArray()) + "]");
            }
            return string.Join("/", shuiweis.ToArray());
        }
    }
}
