using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using ChuPiao.AutoPrint.Configuration;
using ChuPiao.AutoPrint.Desktop.StatusBar;
using ChuPiao.AutoPrint.Machine;
using ChuPiao.AutoPrint.Machine.Models;
using ChuPiao.AutoPrint.Services;
using ChuPiao.AutoPrint.Services.AutoPrint;
using ChuPiao.Common.Core.Utils;
using ChuPiao.Common.Enums;
using ChuPiao.Common.Models;
using ChuPiao.Common.Utils;
using ChuPiao.Common.Communication.GtdJson.Packs;
using ChuPiao.Common.Communication.GtdJson;
using ChuPiao.AutoPrint.Services.TicketFile;
using System.Configuration;

namespace ChuPiao.AutoPrint.Desktop.AutoPrint
{
    
    public partial class ErrorDialog : Form
    {
        public ErrorDialog(AutoPrintService service,L_LotTicketEntity ticket, DecodePrintData decodePrintData,string message)
        {
            InitializeComponent();
            _service = service;
            _ticket = ticket;
            _decodePrintData = decodePrintData;
            _message = message;
        }
        private ErrorProcessEnum _result;
        public ErrorProcessEnum Result
        {
            get
            {
                return _result;
            }
            set
            {
                _result = value;
            }
        }

        private AutoPrintService _service;
        private L_LotTicketEntity _ticket;
        private DecodePrintData _decodePrintData;
        private string _message;
        

        private void ErrorDialog_Load(object sender, EventArgs e)
        {
           

            //string path = @"E:\work\电子票\22选5\单式\00003050470000018242.prn";
            //byte[] arr = File.ReadAllBytes(path);

            if(_decodePrintData!=null && _decodePrintData.InputData!=null && _decodePrintData.InputData.CaptureDataBytes.Length>0)
            {
                byte[] arr = _decodePrintData.InputData.CaptureDataBytes;
                using (MemoryStream ms = new MemoryStream())
                {
                    ms.Write(_decodePrintData.InputData.CaptureDataBytes, 0, arr.Length);
                    ms.Position = 0;
                    this.richTextBoxTicket.LoadFile(ms, RichTextBoxStreamType.PlainText);
                }
                
            }
            this.richTextBoxErrorMsg.Text = _message;
            if(_ticket!=null)
            {
                this.lblCode.Text = _ticket.L_Code;
                this.lblTicketCode.Text = _decodePrintData==null?"":_decodePrintData.L_PrintTicketEntity.P_TicketCode;
                this.lblTicketSn.Text = _ticket.L_TicketSn;
                this.lblMutiple.Text = _ticket.L_Mutiple.ToString();
                this.lblMoney.Text = _ticket.L_Money.ToString("0");
                this.lblOrderSn.Text = _ticket.L_OrderSn;
                this.lblEndTime.Text = _ticket.L_EndTime.ToString("yyyy-MM-dd HH:mm:ss");
                string codetype = "";
                if (_ticket.LotId == (int)Lottype.Jz || _ticket.LotId == (int)Lottype.Jl || _ticket.LotId == (int)Lottype.Bd)
                {
                    JcCodeTypeEnum codeTypeEnum = (JcCodeTypeEnum)_ticket.L_CodeType;
                    codetype = EnumDescription.GetFieldText(codeTypeEnum);
                }
                this.lblCurrentTicketName.Text = string.Concat(LotPlayTypeHashTable.LotTypeHashTable[_ticket.LotId], LotPlayTypeHashTable.PlayTypeHashTable[_ticket.L_PlayId], codetype);
                this.lblExpect.Text = _ticket.L_Expect;
                //if (_ticket.LotId == (int)Lottype.Ps || _ticket.LotId == (int)Lottype.Dl || _ticket.LotId == (int)Lottype.Hd || _ticket.LotId == (int)Lottype.Jd || _ticket.LotId == (int)Lottype.Xs || _ticket.LotId == (int)Lottype.Jz || _ticket.LotId == (int)Lottype.Jl || _ticket.LotId == (int)Lottype.Jm)
                //{
                //    //只有排列三、多乐彩、竟足、竟篮存在限号
                //    btnLimit.Enabled = true;
                //}
                //else
                //{
                //    btnLimit.Enabled = false;
                //}
                if (_ticket.LotId == (int)Lottype.Ps || _ticket.LotId == (int)Lottype.Dl || _ticket.LotId == (int)Lottype.Hd || _ticket.LotId == (int)Lottype.Jd || _ticket.LotId == (int)Lottype.Xs || _ticket.LotId == (int)Lottype.Jz || _ticket.LotId == (int)Lottype.Jl || _ticket.LotId == (int)Lottype.Jm)
                {
                    //只有竟彩有场次停售
                    btnJcStopSale.Enabled = true;
                }
                else
                {
                    btnJcStopSale.Enabled = false;
                }

                //让分或总分已改变
                //if (_ticket.LotId == (int)Lottype.Jl)
                if (_ticket.L_PlayId == (int)Playtype.JlRFSF || _ticket.L_PlayId == (int)Playtype.JlDXF|| 
                      (
                          _ticket.L_PlayId == (int)Playtype.JlHHGG && 
                          (
                              _ticket.L_Code.Contains(Convert.ToString((int)Playtype.JlRFSF)) || _ticket.L_Code.Contains(Convert.ToString((int)Playtype.JlDXF))
                          )
                       )
                    )
                {
                    button2.Enabled = true;
                }
                else
                {
                    button2.Enabled = false;
                }
            }

           
            
        }

        

        private void clickJLConditionChanged()
        {
            button2.PerformClick();
        }

        private void btnAbort_Click(object sender, EventArgs e)
        {
            if (DialogResult.OK != MessageBox.Show("如果彩票机实际已出票，点终止将重复出票导致错票，确认终止出票么？", "确认", MessageBoxButtons.OKCancel))
            {
                this.DialogResult = DialogResult.None;
                return;
            }

            _service.Stop();
            _service.OnPrinted(_ticket);
            _service.Wait4Job.Set();
            Result = ErrorProcessEnum.Abort;
            _service.Result = Result;
            this.DialogResult = DialogResult.OK;
            StopWarn();
        }

        private void btnRetry_Click(object sender, EventArgs e)
        {
            if (DialogResult.OK != MessageBox.Show("如果彩票机实际已出票，点重试将重复出票导致错票，确认重试出票么？", "确认", MessageBoxButtons.OKCancel))
            {
                this.DialogResult = DialogResult.None;
                return;
            }

            try
            {
                _service.UpdateMachineStatus(MachineStatusEnum.Printing);
                _service.RePrint(_ticket);
                _service.Wait4Job.Set();
                Result = ErrorProcessEnum.Ignore;
                _service.Result = Result;
                this.DialogResult = DialogResult.OK;
                StopWarn();
            }
            catch (Exception ex)
            {
                Logger.Log.Error("重试失败！");
            }
        }

        private void ErrorDialog_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (DialogResult == DialogResult.Cancel)
            {
                _service.Stop();
                _service.Wait4Job.Set();
            }
            //else
            //{
            //    new RedisClient().Publish(_service.LotMachine.MachineInfo.M_Number + " 已处理！");
            //}
        }

        private void btnPrint_Click(object sender, EventArgs e)
        {
            try
            {
                if (_decodePrintData != null && _decodePrintData.InputData != null && _decodePrintData.InputData.CaptureDataBytes != null && _decodePrintData.InputData.CaptureDataBytes.Length > 0)
                {
                    LotMachineService.PrintETicket(_service.LotMachine.MachineInfo.M_Number, _decodePrintData.InputData.CaptureDataBytes);
                    //LotMachineService.PrinterClient.AddBytes(_decodePrintData.InputData.CaptureDataBytes);
                    //ChuPiao.Common.Communication.CpdJson.Packs.P12014PrintTicketFile reqPack = new ChuPiao.Common.Communication.CpdJson.Packs.P12014PrintTicketFile();
                    //reqPack.MacNumber = _service.LotMachine.MachineInfo.M_Number;
                    //reqPack.PrnText =
                    //    HexStringUtil.ByteToString(_decodePrintData.InputData.CaptureDataBytes);
                    //ChuPiao.Common.Communication.CpdJson.PackRetBase packRetBase = ChuPiao.Common.Communication.CpdJson.PackManager.Instance.Transaction(_service.LotMachine.MachineInfo.M_Number, reqPack);
                    //if (packRetBase == null)
                    //{
                    //    throw new Exception(string.Concat("执行命令失败。机器号：", _service.LotMachine.MachineInfo.M_Number));
                    //}
                    //if (packRetBase.ReturnCode != 0)
                    //{
                    //    throw new Exception(string.Concat("彩票机返回错误编码：", packRetBase.ReturnCode, " 错误信息：", packRetBase.ReturnMessage));
                    //}
                }
            }
            catch (Exception exception)
            {
                MessageService.ShowError(string.Concat("打印电子票异常。错误信息：",exception.Message));
            }
        }

        private void btnIgnore_Click(object sender, EventArgs e)
        {
            if (DialogResult.OK != MessageBox.Show("如果彩票机实际已出票，点取消将导致错票，确定要取消？", "确认", MessageBoxButtons.OKCancel))
            {
                this.DialogResult = DialogResult.None;
                return;
            }
            Logger.Log.Info("开始通知取消...");
            try
            {
                //通知票号
                A10002NotifyTicket pack = new A10002NotifyTicket();
                pack.AgentId = _service.LotMachine.MachineInfo.M_Number;
                pack.Salt = _service.LotMachine.MachineInfo.M_Salt;
                _ticket.L_Status = 100;
                _ticket.L_LimitType = 0;
                _ticket.L_SucTime = DateTime.Now;
                pack.Ticket = _ticket;
                A10002NotifyTicketRet packRet = PackManager.Instance.Send(pack) as A10002NotifyTicketRet;
                if (packRet.Code <= 0)
                {
                    throw new Exception("取消失败，" + packRet.Code.ToString() + " " + packRet.Message);
                }
                else
                {
                    MessageBox.Show("取消成功！");
                }

                _service.Stop();
                _service.OnPrinted(_ticket);
                _service.Wait4Job.Set();
                Result = ErrorProcessEnum.Abort;
                _service.Result = Result;
                this.DialogResult = DialogResult.OK;
                StopWarn();
            }
            catch (Exception ex)
            {
                Logger.Log.Error("取消失败！" + ex.ToString());
                MessageBox.Show("取消失败，请重试！");
            }
        }
       

        private void btnReGetdata_Click(object sender, EventArgs e)
        {
            Logger.Log.Info("开始二次获取数据...");
            try
            {
                DecodePrintData decodePrintData = new DecodePrintData();
                _service.ReGetdata(_ticket,decodePrintData);

                if (decodePrintData.DecodeSuccess)
                {
                    _service.LotMachine.Log.Info(string.Concat("二次获取数据解析成功"));

                    //string ticketFilePath = FileService.GetErrorTicketFilePath(_service.LotMachine.MachineInfo.M_Number, _ticket.L_TicketCode); ;
                    //File.WriteAllText(ticketFilePath, decodePrintData.L_PrintTicketEntity.P_PrnText);
                    //_service.LotMachine.Log.Info(string.Concat("保存电子票文件：", ticketFilePath));
                    //if (_service.LotMachine.MachineInfo.M_AllowPaperout)
                    //{
                    //    LotMachineService.PrintETicket(_service.LotMachine.MachineInfo.M_Number, ticketFilePath, true);
                    //}

                    //MessageBox.Show("二次获取数据成功，请点击“重新通知”进行票号通知！");
                    button1.PerformClick();
                }
                else
                {
                    MessageBox.Show("二次获取数据失败，请点击【重新获取】，重试几次！");
                }
            }
            catch (Exception ex)
            {
                //_service.Wait4Job.Set();
                _service.Stop();
                _service.LotMachine.Log.Warn("处理错票失败：" + ex.Message + "\r\n" + ex.StackTrace);
                MessageBox.Show("二次获取数据异常，请通知技术！");
            }
            
        }

        private void StopWarn()
        {
            bool hasError = false;
            foreach (KeyValuePair<string, ILotMachine> keyValuePair in LotMachineService.LotMachineList)
            {
                if(keyValuePair.Value.MachineInfo.M_Status==(int)MachineStatusEnum.Error)
                {
                    hasError = true;
                    break;
                }
            }
            if(!hasError)
            {
                StatusBarService.StopWarnButton();
            }
        }

        private void btnJcStopSale_Click(object sender, EventArgs e)
        {
            if (DialogResult.OK != MessageBox.Show("彩票机弹窗提示限号或停售，竞彩官网确定场次停售，要撤单是么？", "确认", MessageBoxButtons.OKCancel))
            {
                this.DialogResult = DialogResult.None;
                return;
            }

            Logger.Log.Info("开始通知撤单...");
            try
            {
                //通知票号
                A10002NotifyTicket pack = new A10002NotifyTicket();
                pack.AgentId = _service.LotMachine.MachineInfo.M_Number;
                pack.Salt = _service.LotMachine.MachineInfo.M_Salt;
                _ticket.L_Status = -300;
                _ticket.L_LimitType = -300;
                _ticket.L_SucTime = DateTime.Now;
                pack.Ticket = _ticket;
                A10002NotifyTicketRet packRet = PackManager.Instance.Send(pack) as A10002NotifyTicketRet;
                if (packRet.Code <= 0)
                {
                    throw new Exception("撤单失败，" + packRet.Code.ToString() + " " + packRet.Message);
                }
                else
                {
                    MessageBox.Show("撤单成功！");
                }

                _service.Stop();
                _service.OnPrinted(_ticket);
                _service.Wait4Job.Set();
                Result = ErrorProcessEnum.Abort;
                _service.Result = Result;
                this.DialogResult = DialogResult.OK;
                StopWarn();
            }
            catch (Exception ex)
            {
                Logger.Log.Error("撤单失败！" + ex.ToString());
                MessageBox.Show("撤单失败，请重试！");
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //if (DialogResult.OK != MessageBox.Show("票已经出了，只是通知失败，要重新通知是么？", "确认", MessageBoxButtons.OKCancel))
            //{
            //    return;
            //}
            Logger.Log.Info("开始重新通知票号...");
            try
            {
                A10002NotifyTicket pack = new A10002NotifyTicket();
                pack.AgentId = _service.LotMachine.MachineInfo.M_Number;
                pack.Salt = _service.LotMachine.MachineInfo.M_Salt;
                pack.Ticket = _ticket;
                A10002NotifyTicketRet packRet = PackManager.Instance.Send(pack) as A10002NotifyTicketRet;
                if (packRet.Code <= 0)
                {
                    throw new Exception("票号通知失败，" + packRet.Code.ToString() + " " + packRet.Message);
                }
                
                MessageBox.Show("票号通知成功！");

                //删除last目录下最后一个文件
                _service.LotMachine.VirtualPrinter.DeleteLastFile();

                _service.TotalMoney += _ticket.L_Money;
                _service.TotalTicket += 1;

                _service.Stop();
                _service.OnPrinted(_ticket);
                _service.Wait4Job.Set();
                Result = ErrorProcessEnum.Abort;
                _service.Result = Result;
                this.DialogResult = DialogResult.OK;
                StopWarn();
            }
            catch (Exception ex)
            {
                Logger.Log.Error("票号通知失败！"+ex.ToString());
                MessageBox.Show("票号通知失败，请点击【重新通知】，重试几次！");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                //取消票
                A10002NotifyTicket pack = new A10002NotifyTicket();
                pack.AgentId = _service.LotMachine.MachineInfo.M_Number;
                pack.Salt = _service.LotMachine.MachineInfo.M_Salt;
                _ticket.L_Status = 100;
                _ticket.L_LimitType = 0;
                _ticket.L_SucTime = DateTime.Now;
                pack.Ticket = _ticket;
                A10002NotifyTicketRet packRet = PackManager.Instance.Send(pack) as A10002NotifyTicketRet;
                if (packRet.Code <= 0)
                {
                    throw new Exception("篮球报错【条件已改变】，取消票失败，" + packRet.Code.ToString() + " " + packRet.Message);
                }
                else
                {
                    Logger.Log.Info("篮球报错【条件已改变】，取消票成功！");
                }


                _service.ClearError((int)MachineErrorType.JlConditionChange);
                Logger.Log.Info("篮球报错【条件已改变】，彩票机恢复出票");

                _service.UpdateMachineStatus(MachineStatusEnum.Printing);
                //_service.RePrint(_ticket);
                _service.Wait4Job.Set();
                Result = ErrorProcessEnum.Ignore;
                _service.Result = Result;
                this.DialogResult = DialogResult.OK;
                StopWarn();
                Logger.Log.Info("篮球报错【条件已改变】，软件恢复出票");
            }
            catch (Exception ex)
            {
                Logger.Log.Error("篮球报错【条件已改变】，处理失败："+ex.ToString());
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (DialogResult.OK != MessageBox.Show("彩票机界面现在是大额票确认弹窗，是么？", "确认", MessageBoxButtons.OKCancel))
            {
                this.DialogResult = DialogResult.None;
                return;
            }

            //开线程处理大额票确认弹窗
            new Thread(BigTicketAlertThread).Start();
        }

        delegate void uiDelegate(); // 新增委托代理
        private void BigTicketAlertThread()
        {
            List<KeycodeInfo> keycodeList = new List<KeycodeInfo>();
            keycodeList.Add(new KeycodeInfo("enter", 300));                     //事实证明，这个大额票确认弹窗点不掉，只能默认等5分钟自动消失
            _service.LotMachine.VirtualKeyboard.Input(keycodeList);

            Thread.Sleep(3000);

            this.BeginInvoke(new uiDelegate(clickReGetData));
        }

        private void clickReGetData()
        {
            btnReGetdata.PerformClick();
        }
    }
}