using System;
using System.Collections.Generic;
using System.Net.Mime;
using System.Threading;
using ChuPiao.AutoPrint.Machine.Models;
using ChuPiao.AutoPrint.Machine.Printer;
using ChuPiao.Common.Enums;
using ChuPiao.Common.Models;
using log4net;

namespace ChuPiao.AutoPrint.Machine
{
    public abstract class BaseLotMachine:ILotMachine
    {
        private L_LotTicketEntity _lastSucTicket = null;

        /// <summary>
        /// 上一张成功票
        /// </summary>
        public L_LotTicketEntity LastSucTicket
        {
            get { return _lastSucTicket; }
            set { _lastSucTicket = value; }

        }

        private L_LotTicketEntity _currentTicket=null;

        /// <summary>
        /// 当前票
        /// </summary>
        public L_LotTicketEntity CurrentTicket
        {
            get { return _currentTicket; }
            set { _currentTicket = value; }
        }


        #region Implementation of ILotMachine

        private ILog _log;

        private M_MachineEntity _machineInfo;

        private IVirtualKeyboard _virtualKeyboard;


        private IVirtualPrinter _virtualPrinter;
        private bool _isPrintedTest = false;
        private M_MachineModeConfigEntity _macCurrentMode;
        private IPrinterClient _printerClient;

        private R_MachineReportEntity _lastMachineReport;

        private bool _lastEncashSuc=false;

        /// <summary>
        /// 当前所在的投注模式
        /// </summary>
        public M_MachineModeConfigEntity MacCurrentMode
        {
            get { return _macCurrentMode; }
            set { _macCurrentMode = value; }
        }

        private string _macCurrentExpect;
        /// <summary>
        /// 当前期
        /// </summary>
        public string MacCurrentExpect
        {
            get { return _macCurrentExpect; }
            set { _macCurrentExpect = value; }
        }

        /// <summary>
        /// 日志记录器
        /// </summary>
        public ILog Log
        {
            get { return _log; }
            set { _log = value; }
        }

        /// <summary>
        /// 彩票机相关信息
        /// </summary>
        public M_MachineEntity MachineInfo
        {
            get { return _machineInfo; }
            set { _machineInfo = value; }
        }

        /// <summary>
        /// 模拟键盘（键盘线）
        /// </summary>
        public IVirtualKeyboard VirtualKeyboard
        {
            get { return _virtualKeyboard; }
            set { _virtualKeyboard = value; }
        }


        /// <summary>
        /// 模拟打印机（打印模块）
        /// </summary>
        public IVirtualPrinter VirtualPrinter
        {
            get { return _virtualPrinter; }
            set { _virtualPrinter = value; }
        }

        /// <summary>
        /// 彩票打印机
        /// </summary>
        public IPrinterClient PrinterClient
        {
            get { return _printerClient; }
            set { _printerClient=value; }
        }

        /// <summary>
        /// 是否已打印测试票
        /// </summary>
        public bool IsPrintedTest
        {
            get { return _isPrintedTest; }
            set { _isPrintedTest=value; }
        }

        /// <summary>
        /// 玩法映射
        /// </summary>
        public abstract Dictionary<int, M_LotPlayModeMapEntity> LotPlayMap { get; }

        /// <summary>
        /// 最近一次机器报表
        /// </summary>
        public R_MachineReportEntity LastMachineReport
        {
            get { return _lastMachineReport; }
            set { _lastMachineReport = value; }
        }

        /// <summary>
        /// 最后一次兑奖是否成功
        /// </summary>
        public bool LastEncashSuc
        {
            get { return _lastEncashSuc; }
            set { _lastEncashSuc = value; }
        }

        /// <summary>
        /// 彩票机充值
        /// </summary>
        public abstract void Recharge(int money);

        /// <summary>
        /// 彩票机初始化
        /// </summary>
        public abstract void Initialize();

        /// <summary>
        /// 启动驱动
        /// </summary>
        public abstract void StartDriver();

        /// <summary>
        /// 停止驱动
        /// </summary>
        public abstract void StopDriver();

        /// <summary>
        /// 重启驱动
        /// </summary>
        public abstract void ReStartDriver();

        /// <summary>
        /// 打印指定的票
        /// </summary>
        public abstract void Print(L_LotTicketEntity ticketEntity, DecodePrintData decodePrintData);

        /// <summary>
        /// 测试电子票解析
        /// </summary>
        /// <param name="ticketEntity"></param>
        /// <param name="decodePrintData"></param>
        public abstract void TestDecodeTicket(L_LotTicketEntity ticketEntity, DecodePrintData decodePrintData);

        /// <summary>
        /// 重新获取数据
        /// </summary>
        /// <param name="ticketEntity"></param>
        /// <param name="decodePrintData"></param>
        public abstract void ReGetdata(L_LotTicketEntity ticketEntity, DecodePrintData decodePrintData);

        /// <summary>
        /// 获取缓冲区票
        /// </summary>
        /// <returns></returns>
        public abstract CaptureDataInfo GetCacheTicket();

        /// <summary>
        /// 获取最后一张票
        /// </summary>
        /// <returns></returns>
        public abstract CaptureDataInfo GetLastTicket();

        /// <summary>
        /// 强行停止当前票
        /// </summary>
        public void ForceStop()
        {
            VirtualPrinter.ForceStop();
        }

        /// <summary>
        /// 兑奖指定的票
        /// </summary>
        /// <param name="ticketEntity"></param>
        public abstract void Encash(L_LotTicketEntity ticketEntity);

        /// <summary>
        /// 打印缴款报表
        /// </summary>
        /// <param name="isPaperOut">是否出纸</param>
        /// <param name="decodePrintData"></param>
        public abstract void PrintPayMoneyReport(DecodeMachinePayMoneyReport decodePrintData, bool isPaperOut);

        /// <summary>
        /// 打印机器报表
        /// </summary>
        /// <returns></returns>
        public abstract void PrintReport(DateTime startTime, DateTime endTime, DecodeMachineReport decodePrintData, bool isPaperOut);

        /// <summary>
        /// 打印竟彩机器报表
        /// </summary>
        /// <returns></returns>
        public abstract void PrintJcReport(DateTime startTime, DateTime endTime, DecodeMachineReport decodePrintData, bool isPaperOut);

        /// <summary>
        /// 打印当天报表
        /// </summary>
        /// <param name="decodePrintData"></param>
        public abstract void PrintCurrentDayReport(DecodeMachineReport decodePrintData, bool isPaperOut);

        /// <summary>
        /// 打印机器玩法报表
        /// </summary>
        /// <returns></returns>
        public abstract void PrintPlayReport(M_PlayTypeEntity playTypeEntity, DateTime startTime, DateTime endTime, DecodeMachinePlayReport decodePrintData, bool isPaperOut);

        /// <summary>
        /// 查看机器中奖金额
        /// </summary>
        /// <param name="ticketEntity"></param>
        public abstract void ViewPrizeMoney(L_LotTicketEntity ticketEntity);

        /// <summary>
        /// 登录彩票机
        /// </summary>
        public abstract void Login();

        /// <summary>
        /// 关闭彩票机
        /// </summary>
        public abstract void Shutdown();

        /// <summary>
        /// 打印测试票
        /// </summary>
        public abstract CaptureDataInfo PrintTestTicket(bool isPaperOut);

        /// <summary>
        /// 打印对阵信息
        /// </summary>
        public abstract CaptureDataInfo PrintMatch(int lotId);

        /// <summary>
        /// 打印足彩对阵信息
        /// </summary>
        /// <param name="lotId">足彩彩种id</param>
        /// <param name="index">1-当前期；2-下一期；3-下下期</param>
        /// <returns></returns>
        public abstract CaptureDataInfo PrintZcMatch(int lotId, int index);

        /// <summary>
        /// 打印开奖报表
        /// </summary>
        public abstract CaptureDataInfo PrintOpenCodeReport(int lotId);

        /// <summary>
        /// 清楚彩票机合计金额
        /// </summary>
        /// <returns>是否成功</returns>
        public abstract void ClearMahineMoney();

        /// <summary>
        /// 清除彩票机错误
        /// </summary>
        /// <param name="errorType"></param>
        public abstract void ClearError(int errorType);

        /// <summary>
        /// 清除彩票机弹窗“奖期已更新”（竟彩）
        /// </summary>
        public abstract void ClearExpectUpdate();

        /// <summary>
        /// 刷新机器额度
        /// </summary>
        /// <returns></returns>
        public abstract void RefreshMahineMoney();

        /// <summary>
        /// 刷新广播信息
        /// </summary>
        /// <returns></returns>
        public abstract void RefreshMahineBroadcast();

        /// <summary>
        /// 清空接收数据缓存
        /// </summary>
        public void ClearBuffer()
        {
            try
            {
                VirtualPrinter.ClearBuffer();
                Log.Debug("清空接收数据缓存");
            }
            catch (Exception exception)
            {
                Log.Info(string.Concat("清空接收数据缓存异常。错误信息：", exception.Message));
            }
        }

        /// <summary>
        /// 发送键码
        /// </summary>
        /// <param name="keycodeInfoList"></param>
        public void SendKeys(List<KeycodeInfo> keycodeInfoList)
        {
            try
            {
                //VirtualPrinter.ClearBuffer();
                VirtualKeyboard.Input(keycodeInfoList);
            }
            catch (Exception exception)
            {
                Log.Info(string.Concat("发送键码异常。错误信息：",exception.Message));
            }
            
        }

        /// <summary>
        /// 计算所有键码耗时
        /// </summary>
        /// <param name="keycodeInfoList"></param>
        public int SendKeysTime(List<KeycodeInfo> keycodeInfoList)
        {
            int time = 0;
            foreach(KeycodeInfo keycode in keycodeInfoList)
            {
                time += keycode.SendInterval;
            }
            return time;
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <returns></returns>
        public CaptureDataInfo GetData()
        {
            CaptureDataInfo captureDataInfo = new CaptureDataInfo(new byte[] { });
            try
            {
                captureDataInfo=VirtualPrinter.Output();
            }
            catch (Exception exception)
            {
                Log.Info(string.Concat("获取数据异常。错误信息：", exception.Message));
            }
            return captureDataInfo;
        }

        /// <summary>
        /// 切换当前玩法
        /// </summary>
        /// <param name="ticketEntity"></param>
        public abstract void SetCurrentLotPlayMode(L_LotTicketEntity ticketEntity);

        /// <summary>
        /// 返回顶级界面
        /// </summary>
        public abstract void ReturnTopGui();

        /// <summary>
        /// 进入销售主界面（竟彩）
        /// </summary>
        public abstract void EnterSaleGui();

        /// <summary>
        /// 出票中
        /// </summary>
        public event EventHandler<TicketEventArgs> Printing;
        /// <summary>
        /// 出票完成
        /// </summary>
        public event EventHandler<TicketEventArgs> Printed;
        /// <summary>
        /// 兑奖中
        /// </summary>
        public event EventHandler<TicketEventArgs> Encashing;
        /// <summary>
        /// 兑奖完成
        /// </summary>
        public event EventHandler<TicketEventArgs> Encashed;

        public virtual void OnPrinting(L_LotTicketEntity ticketEntity)
        {
            EventHandler<TicketEventArgs> handler = Printing;
            if (handler != null)
            {
                handler(this, new TicketEventArgs(ticketEntity));
            }
        }
        public virtual void OnPrinted(L_LotTicketEntity ticketEntity)
        {
            EventHandler<TicketEventArgs> handler = Printed;
            if (handler != null)
            {
                handler(this, new TicketEventArgs(ticketEntity));
            }
        }

        public virtual void OnEncashing(L_LotTicketEntity ticketEntity)
        {
            EventHandler<TicketEventArgs> handler = Encashing;
            if (handler != null)
            {
                handler(this, new TicketEventArgs(ticketEntity));
            }
        }
        public virtual void OnEncashed(L_LotTicketEntity ticketEntity)
        {
            EventHandler<TicketEventArgs> handler = Encashed;
            if (handler != null)
            {
                handler(this, new TicketEventArgs(ticketEntity));
            }
        }
        //public virtual void OnStatusChanged(MachineStatusEnum machineStatus)
        //{
        //    EventHandler<MachineStatusArgs> handler = StatusChanged;
        //    if (handler != null)
        //    {
        //        handler(this, new MachineStatusArgs(machineStatus));
        //    }
        //}

        #endregion

        private List<int> _fuShiModeList = null;
        protected List<int> FuShiModeList
        {
            get
            {
                if (_fuShiModeList == null)
                {
                    _fuShiModeList = new List<int>();
                    _fuShiModeList.AddRange(new int[] { 6010102, 6011102, 6020102, 6030102, 7010102, 7010103, 7011102, 7011103, 7012102, 7020102, 7020103, 7020104, 7020105, 7020106, 7021103, 7021202, 7021204, 7021205, 7022202, 7022204, 7022205, 7025202, 7040102, 7050102 });

                }
                return _fuShiModeList;
            }
        }

        private List<int> _fuShiPlayList = null;
        protected  List<int> FuShiPlayList
        {
            get
            {
                if (_fuShiPlayList == null)
                {
                    _fuShiPlayList=new List<int>();
                    _fuShiPlayList.AddRange(new int[] { 70502, 70402, 70302, 70202,70203, 70212, 70222, 70232, 70206, 70204, 70214, 70224, 70205, 70215, 70225, 70102, 70103, 70112, 70113, 70122, 60302, 60202, 60102, 60112 });
                }
                return _fuShiPlayList;
            }
        }

        protected void Wait(int wait)
        {
            Log.Info(string.Concat("等待 ", wait, " 毫秒"));
            while (wait > 0)
            {
                wait -= 100;
                Thread.Sleep(100);
                if (MachineInfo.M_Status != (int)MachineStatusEnum.Printing)
                {
                    break;
                }
            }
        }

        protected void Wait2(int wait)
        {
            Log.Info(string.Concat("等待", wait, "毫秒"));
            Thread.Sleep(wait);
            //while (wait > 0)
            //{
            //    wait -= 100;
            //    Thread.Sleep(100);
            //    if (MachineInfo.M_Status == (int)MachineStatusEnum.Stopping)
            //    {
            //        break;
            //    }
            //}
            
        }



    }
}
