using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Threading;
using System.Reflection;
using SPC.Kiosk.Base;
using SPC.Kiosk.Common;
using SPC.Kiosk.Popup.Model;
using SPC.Kiosk.Payments;
using System.Windows;
using System.Threading.Tasks;
using System.Threading;

namespace SPC.Kiosk.Popup.ViewModel
{
    /// <summary>
    /// OkCashBagCertify.xaml에 대한 ViewModel
    /// </summary>
    public class VmOkCashBagCertify : PopupViewModelBase
    {


        #region [ Members ]

        private List<M_Language> headerText;
        /// <summary>
        /// Top Header Text
        /// </summary>
        public List<M_Language> HeaderText
        {
            get { return headerText; }
            set { headerText = value; PropertyChange("HeaderText"); }
        }
        private List<M_Language> scanGuidText;
        /// <summary>
        /// Second Sub Header Text
        /// </summary>
        public List<M_Language> ScanGuidText
        {
            get { return scanGuidText; }
            set { scanGuidText = value; PropertyChange("ScanGuidText"); }
        }
        private string processingGIF;
        /// <summary>
        /// Processing GIF
        /// </summary>
        public string ProcessingGIF
        {
            get { return processingGIF; }
            set { processingGIF = value; PropertyChange("ProcessingGIF"); }
        }
        private List<M_Language> infoGuid1Text;
        /// <summary>
        /// Bootom first infomation text
        /// </summary>
        public List<M_Language> InfoGuid1Text
        {
            get { return infoGuid1Text; }
            set { infoGuid1Text = value; PropertyChange("InfoGuid1Text"); }
        }
        private List<M_Language> infoGuid2Text;
        /// <summary>
        /// Bottom second infomation text
        /// </summary>
        public List<M_Language> InfoGuid2Text
        {
            get { return infoGuid2Text; }
            set { infoGuid2Text = value; PropertyChange("InfoGuid2Text"); }
        }
        public bool certifyStartVisible = false;
        /// <summary>
        /// 인증 시작 화면 Visible
        /// </summary>
        public bool CertifyStartVisible
        {
            get { return certifyStartVisible; }
            set { certifyStartVisible = value; PropertyChange("CertifyStartVisible"); }
        }
        public bool certifyProcessingVisible = false;
        /// <summary>
        /// 인증 진행 화면 Visible
        /// </summary>
        public bool CertifyProcessingVisible
        {
            get { return certifyProcessingVisible; }
            set { certifyProcessingVisible = value; PropertyChange("CertifyProcessingVisible"); }
        }
        public bool processingErrorVisible = false;
        /// <summary>
        /// 인증 오류 화면 Visible
        /// </summary>
        public bool ProcessingErrorVisible
        {
            get { return processingErrorVisible; }
            set { processingErrorVisible = value; PropertyChange("ProcessingErrorVisible"); }
        }
        public bool certifySuccessVisible = false;
        /// <summary>
        /// 인증 완료 화면 Visible
        /// </summary>
        public bool CertifySuccessVisible
        {
            get { return certifySuccessVisible; }
            set { certifySuccessVisible = value; PropertyChange("CertifySuccessVisible"); }
        }

        private bool showPhoneInput = false;
        /// <summary>
        /// Show Phone Input
        /// </summary>
        public bool ShowPhoneInput
        {
            get { return showPhoneInput; }
            set { showPhoneInput = value; PropertyChange("ShowPhoneInput"); }
        }
        private List<M_Language> processingMessageText;
        /// <summary>
        /// Number Pad Input Guide Text
        /// </summary>
        public List<M_Language> ProcessingMessageText
        {
            get { return processingMessageText; }
            set { processingMessageText = value; PropertyChange("ProcessingMessageText"); }
        }
        private List<M_Language> processingGuide;
        /// <summary>
        /// Processing Guide Text
        /// </summary>
        public List<M_Language> ProcessingGuide
        {
            get { return processingGuide; }
            set { processingGuide = value; PropertyChange("ProcessingGuide"); }
        }
        private string errorImage;
        /// <summary>
        /// Error Icon
        /// </summary>
        public string ErrorImage
        {
            get { return errorImage; }
            set { errorImage = value; PropertyChange("ErrorImage"); }
        }
        private List<M_Language> errorGuide;
        /// <summary>
        /// Error Guide Text
        /// </summary>
        public List<M_Language> ErrorGuide
        {
            get { return errorGuide; }
            set { errorGuide = value; PropertyChange("ErrorGuide"); }
        }

        private List<M_Language> numPadGuidText;
        /// <summary>
        /// Number Pad Input Guide Text
        /// </summary>
        public List<M_Language> NumPadGuidText
        {
            get { return numPadGuidText; }
            set { numPadGuidText = value; PropertyChange("NumPadGuidText"); }
        }
        private List<M_Language> numPadCancelText;
        /// <summary>
        /// Number Pad Cancel Button Text
        /// </summary>
        public List<M_Language> NumPadCancelText
        {
            get { return numPadCancelText; }
            set { numPadCancelText = value; PropertyChange("NumPadCancelText"); }
        }
        private List<M_Language> errorText;
        /// <summary>
        /// Process Error Text
        /// </summary>
        public List<M_Language> ErrorText
        {
            get { return errorText; }
            set { errorText = value; PropertyChange("ErrorText"); }
        }
        private bool isErrorBlink = false;
        /// <summary>
        /// Is Error Text Blink
        /// </summary>
        public bool IsErrorBlink
        {
            get { return isErrorBlink; }
            set { isErrorBlink = value; PropertyChange("IsErrorBlink"); }
        }
        private string formatedBarCode;
        /// <summary>
        /// Read Barcode Formated Text
        /// </summary>
        public string FormatedBarCode
        {
            get { return formatedBarCode; }
            set { formatedBarCode = value; PropertyChange("FormatedBarCode"); }
        }
        private string readBarCode;
        /// <summary>
        /// Read Barcode
        /// </summary>
        public string ReadBarCode
        {
            get { return readBarCode; }
            set { readBarCode = value; PropertyChange("ReadBarCode"); }
        }
        private string inputNumbers = string.Empty;
        /// <summary>
        /// Number Pad Input Number
        /// </summary>
        public string InputNumbers
        {
            get { return inputNumbers; }
            set { inputNumbers = value; PropertyChange("InputNumbers"); }
        }
        private string memberPointsText = string.Empty;
        /// <summary>
        /// Number Pad Input Number
        /// </summary>
        public string MemberPointsText
        {
            get { return memberPointsText; }
            set { memberPointsText = value; PropertyChange("MemberPointsText"); }
        }
        
        private double cancelButtonWidth = 650d;
        /// <summary>
        /// Cancel Button Width
        /// </summary>
        public double CancelButtonWidth
        {
            get { return cancelButtonWidth; }
            set { cancelButtonWidth = value; PropertyChange("CancelButtonWidth"); }
        }
        private List<M_Language> cancelButtonText;
        /// <summary>
        /// Cancel Button Text
        /// </summary>
        public List<M_Language> CancelButtonText
        {
            get { return cancelButtonText; }
            set { cancelButtonText = value; PropertyChange("CancelButtonText"); }
        }
        private List<M_Language> okButtonText;
        /// <summary>
        /// Ok Button Text
        /// </summary>
        public List<M_Language> OkButtonText
        {
            get { return okButtonText; }
            set { okButtonText = value; PropertyChange("OkButtonText"); }
        }
        public bool oKButtonEnabled = false;
        /// <summary>
        /// OK Button enabled
        /// </summary>
        public bool OKButtonEnabled
        {
            get { return oKButtonEnabled; }
            set { oKButtonEnabled = value; PropertyChange("OKButtonEnabled"); }
        }
        private double okButtonWidth = 650d;
        /// <summary>
        /// OK Button Width
        /// </summary>
        public double OKButtonWidth
        {
            get { return okButtonWidth; }
            set { okButtonWidth = value; PropertyChange("OKButtonWidth"); }
        }
        public int numPadMaxLength;
        /// <summary>
        /// Number Pad Input Maxlength
        /// </summary>
        public int NumPadMaxLength
        {
            get { return numPadMaxLength; }
            set { numPadMaxLength = value; PropertyChange("NumPadMaxLength"); }
        }

        private List<M_Language> memberPointsHeaderText;
        /// <summary>
        /// Cancel Button Text
        /// </summary>
        public List<M_Language> MemberPointsHeaderText
        {
            get { return memberPointsHeaderText; }
            set { memberPointsHeaderText = value; PropertyChange("MemberPointsHeaderText"); }
        }
                
        private CertifyWindowType certifyWindow = CertifyWindowType.CertifyStart;
        /// <summary>
        /// Current  View Window
        /// </summary>
        public CertifyWindowType CertifyWindow
        {
            get { return certifyWindow; }
            set { certifyWindow = value; PropertyChange("CertifyWindow"); }
        }
        private double popupWidth = 1300;
        /// <summary>
        /// Popup Whidth (For Calculate OK Button Width)
        /// </summary>
        public double PopupWidth
        {
            get { return popupWidth; }
            set { popupWidth = value; PropertyChange("PopupWidth"); }
        }
        /// <summary>
        /// OK CashBag 인증 정보
        /// </summary>
        public M_OkCashBagReturn OkCashBagReturn { get; set; }
        /// <summary>
        /// OK Click Command
        /// </summary>
        public ICommand OkCommand { get; protected set; }
        /// <summary>
        /// Cancel Click Command
        /// </summary>
        public ICommand CancelCommand { get; protected set; }
        private bool MemberProcessStart = false;
        private posOkCashBag posOkCashBag = null;
        private Task ProcessTask = null;
        private CancellationTokenSource TokenSource;
        private string certifyKey = string.Empty;

        /// <summary>
        /// 바코드스캔 Image
        /// </summary>
        public string BarcodeScanImage { get; set; } = ResourceManager.GetNximagePathAdd("img_gif_barcode.gif", CommonValue.PBdesignImagesPath);

        #endregion

        #region [ Ctor ]
        /// <summary>
        /// Ctor
        /// </summary>
        public VmOkCashBagCertify()
        {
            OkCommand = new Command(OkCommandHandler);
            CancelCommand = new Command(CancelCommandHandler);
            this.PropertyChanged += VmHappyPointCertify_PropertyChanged;
            HeaderText = new List<M_Language>
                                        {
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.ko,
                                                LanguageData = "OK 캐시백 회원인증"
                                            },
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.en,
                                                LanguageData = "enOK 캐시백 회원인증"
                                            },
                                        };
            ProcessingMessageText = Languages.GetMessages("LBL0087");
            ProcessingGuide = Languages.GetMessages("LBL0140");
            ErrorImage = ResourceManager.GetNximagePathAdd("ic_alert_error.png", CommonValue.PBdesignImagesPath);
            ErrorGuide = Languages.GetMessages("LBL0140");
            ErrorText = new List<M_Language>();
            NumPadMaxLength = 11;
            NumPadGuidText = Languages.GetMessages("MobileNumberMessage");
            NumPadCancelText = Languages.GetMessages("CommonClear");
            ProcessingGIF = ResourceManager.GetNximagePathAdd("ic_alert_ing2.gif", CommonValue.PBdesignImagesPath);
            ShowLanguageType = CommonValue.CommonLanguageType;
            posOkCashBag = new posOkCashBag();
            CertifyWindow = CertifyWindowType.CertifyStart;
        }


        ~VmOkCashBagCertify()
        {
            this.PropertyChanged -= VmHappyPointCertify_PropertyChanged;
            if (ProcessTask != null)
            {
                ProcessTask.Dispose();
                ProcessTask = null;
            }
            if (posOkCashBag != null)
            {
                CashBagRemoveEvents();
                posOkCashBag.Dispose();
                posOkCashBag = null;
            }
        }
        #endregion Ctor

        #region [ Method ]


        private void InitError()
        {
            LastAccessTime = DateTime.Now;
            ErrorText = new List<M_Language>();
            IsErrorBlink = false;
        }
        private void CashBagCreateEvents()
        {
            if (posOkCashBag != null)
            {
                posOkCashBag.ReadStart += PosOkCashBag_ReadStart;
                posOkCashBag.ReadEnd += PosOkCashBag_ReadEnd;
                posOkCashBag.ErrorEvent += PosOkCashBag_ErrorEvent;
                posOkCashBag.ErrorMessageEvent += PosOkCashBag_ErrorMessageEvent;
            }
        }
        private void CashBagRemoveEvents()
        {
            if (posOkCashBag != null)
            {
                posOkCashBag.ReadStart -= PosOkCashBag_ReadStart;
                posOkCashBag.ReadEnd -= PosOkCashBag_ReadEnd;
                posOkCashBag.ErrorEvent -= PosOkCashBag_ErrorEvent;
                posOkCashBag.ErrorMessageEvent -= PosOkCashBag_ErrorMessageEvent;
            }
        }
        private void DoOkCashBagCertify()
        {
            if (posOkCashBag != null)
            {
                this.CashBagCreateEvents();
                var processTask = new Task(() => posOkCashBag.StartCertifyProcessing(certifyKey));
                TokenSource = new CancellationTokenSource();
                processTask.Start();
                processTask.Wait();
                if (posOkCashBag.ProcessOK)
                {
                    CertifyWindow = CertifyWindowType.CertifySuccess;
                }
                else
                {
                    CertifyWindow = CertifyWindowType.ProcessingError;
                }
                CashBagRemoveEvents();
                TokenSource.Dispose();
                processTask = null;
                TokenSource = null;
            }

        }
        private void DoBarCodeOkCashBagCertify()
        {
            InputNumbers = string.Empty;
            FormatedBarCode = ReadBarCode.GetEncriptCardNo();
            certifyKey = ReadBarCode;
            CertifyWindow = CertifyWindowType.CertifyProcessing;
        }
        #endregion Method

        #region [ Event Handlers ]
        private void PosOkCashBag_ErrorMessageEvent(string ErrorString)
        {
            ErrorText = new List<M_Language>
            {
                new M_Language
                {
                    Type = SupportLanguageType.ko,
                    LanguageData = ErrorString.Replace("\n"," ").Replace("\r","")
                },
            };
            IsErrorBlink = true;
            CertifyWindow = CertifyWindowType.ProcessingError;
        }

        private void PosOkCashBag_ErrorEvent(posOkCashBag.ErrorCode _errorCode)
        {
            //TODO: 공통에 에러 메세지 등록 필요
            //ErrorText = Languages.GetMessages(_errorCode.ToString());

            ErrorText = new List<M_Language>
            {
                new M_Language
                {
                    Type = SupportLanguageType.ko,
                    LanguageData = _errorCode.ToString()
                },
            };
            IsErrorBlink = true;
            CertifyWindow = CertifyWindowType.ProcessingError;
        }

        private void PosOkCashBag_ReadStart(object sender)
        {
            MemberProcessStart = true;
            TimerEnabled = false;
        }

        private void PosOkCashBag_ReadEnd(object sender)
        {
            if (sender is posHappyPoint getPosposHappyPoint)
            {
                if (getPosposHappyPoint.ProcessOK)
                {
                    OkCashBagReturn = new M_OkCashBagReturn
                    {
                        MemberName = getPosposHappyPoint.MemberName,
                        MemberCode = getPosposHappyPoint.CertifyKey,
                        MemberPoint = getPosposHappyPoint.MemberPoint,
                        NeedPassword = getPosposHappyPoint.NeedPassword,
                        ReservePoint = getPosposHappyPoint.CanReservePoint,
                    };
                    ReturnValue = new M_PopupReturn
                    {
                        OKAnswer = true,
                        TimeOut = false,
                        ReturnLanguage = ShowLanguageType,
                        PopupArgs = OkCashBagReturn
                    };
                    MemberPointsText = string.Format("{0} Points", OkCashBagReturn.MemberPoint.ToString("#,##0"));
                    CertifyWindow = CertifyWindowType.CertifySuccess;
                }
            }
            TimerEnabled = true;
            MemberProcessStart = false;

        }
        private void CancelCommandHandler(object obj)
        {
            TimerEnabled = false;
            ReturnValue = new M_PopupReturn
            {
                OKAnswer = false,
                TimeOut = false,
                ReturnLanguage = ShowLanguageType,
                PopupArgs = null
            };
            CanWindowClose = true;
        }

        private void OkCommandHandler(object obj)
        {
            switch (CertifyWindow)
            {
                case CertifyWindowType.CertifyStart:
                    certifyKey = InputNumbers;
                    CertifyWindow = CertifyWindowType.CertifyProcessing;
                    break;
                case CertifyWindowType.ProcessingError:
                    CertifyWindow = CertifyWindowType.CertifyStart;
                    break;
                case CertifyWindowType.CertifySuccess:
                    if (ProcessTask != null) ProcessTask.Wait();
                    CanWindowClose = true;
                    break;
            }
           
        }

        private void VmHappyPointCertify_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "IsTimeout":
                    if (IsTimeout)
                    {
                        switch (CertifyWindow)
                        {
                            case CertifyWindowType.CertifyStart:
                            case CertifyWindowType.ProcessingError:
                                ReturnValue = new M_PopupReturn
                                {
                                    OKAnswer = false,
                                    TimeOut = true,
                                    ReturnLanguage = ShowLanguageType,
                                    PopupArgs = null
                                };
                                break;
                        }
                        if (ProcessTask != null) ProcessTask.Wait();
                        CanWindowClose = true;
                    }
                    break;
                case "InputNumbers":
                    if (InputNumbers.Length > 0)
                    {
                        InitError();
                        ReadBarCode = string.Empty;
                    }
                    OKButtonEnabled = InputNumbers.Length.Equals(10) || InputNumbers.Length.Equals(11);
                    break;
                case "ReadBarCode":
                    if (!MemberProcessStart)
                    {
                        InitError();
                        switch (ReadBarCode.Length)
                        {
                            case 17:
                                readBarCode = ReadBarCode.Substring(0, 16);
                                DoBarCodeOkCashBagCertify();
                                break;
                            case 16:
                                DoBarCodeOkCashBagCertify();
                                break;
                            default:
                                FormatedBarCode = string.Empty;
                                OKButtonEnabled = false;
                                break;
                        } 
                    }
                    break;
                case "CertifyWindow":
                    CertifyStartVisible = false;
                    CertifyProcessingVisible = false;
                    ProcessingErrorVisible = false;
                    CertifySuccessVisible = false;
                    switch (CertifyWindow)
                    {
                        case CertifyWindowType.CertifyStart:
                            CertifyStartVisible = true;
                            break;
                        case CertifyWindowType.CertifyProcessing:
                            CertifyProcessingVisible = true;
                            break;
                        case CertifyWindowType.ProcessingError:
                            ProcessingErrorVisible = true;
                            break;
                        case CertifyWindowType.CertifySuccess:
                            CertifySuccessVisible = true;
                            break;
                    }
                    break;
                case "CertifyStartVisible":
                    if (CertifyStartVisible)
                    {
                        ScanGuidText = Languages.GetMessages("LBL0082");
                        InfoGuid1Text = new List<M_Language>
                                        {
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.ko,
                                                LanguageData = "* 인증시 OK 캐시백 포인트가 적립됩니다."
                                            },
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.en,
                                                LanguageData = "en* 인증시OK 캐시백 포인트가 적립됩니다."
                                            },
                                        };
                        InfoGuid2Text = new List<M_Language>
                                        {
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.ko,
                                                LanguageData = "* 수집된 개인정보는 활용 후 자동 폐기 됩니다."
                                            },
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.en,
                                                LanguageData = "en* 수집된 개인정보는 활용 후 자동 폐기 됩니다."
                                            },
                                        };
                        
                        CancelButtonWidth = PopupWidth;
                        OKButtonWidth = 0d;
                        OKButtonEnabled = false;
                        //OkButtonText = Languages.GetMessages("CommonYes");
                        //CancelButtonText = Languages.GetMessages("CommonNo");
                        OkButtonText = Languages.GetMessages("CommonOK");
                        CancelButtonText = Languages.GetMessages("CommonCancel");
                        TimeOutSeconds = CommonValue.TimeOutSeconds;
                    }
                    break;
                case "CertifyProcessingVisible":
                    if (CertifyProcessingVisible)
                    {
                        ScanGuidText = new List<M_Language>
                                        {
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.ko,
                                                LanguageData = "인증 처리 진행 중입니다."
                                            },
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.en,
                                                LanguageData = "en인증 처리 진행 중입니다."
                                            },
                                        };
                        //InfoGuid1Text = new List<M_Language>
                        //                {
                        //                    new M_Language
                        //                    {
                        //                        Type = SupportLanguageType.ko,
                        //                        LanguageData = "* 화면 상태가 지속되면 직원을 호출 하세요."
                        //                    },
                        //                    new M_Language
                        //                    {
                        //                        Type = SupportLanguageType.en,
                        //                        LanguageData = "en* 화면 상태가 지속되면 직원을 호출 하세요."
                        //                    },
                        //                };
                        InfoGuid2Text = new List<M_Language>();                        
                        if (ProcessTask != null) ProcessTask.Wait();
                        ProcessTask = new Task(DoOkCashBagCertify);
                        ProcessTask.Start();

                        //if (ProcessTask != null)
                        //{
                        //    ProcessTask.Dispose();
                        //    ProcessTask = null;
                        //}
                        //ProcessTask = new Task(DoOkCashBagCertify);
                        //ProcessTask.Start();
                    }
                    break;
                case "ProcessingErrorVisible":
                    if (ProcessingErrorVisible)
                    {
                        ScanGuidText = new List<M_Language>
                                        {
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.ko,
                                                LanguageData = "인증 처리중 오류가 발생 했습니다."
                                            },
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.en,
                                                LanguageData = "en인증 처리중 오류가 발생 했습니다."
                                            },
                                        };
                        InfoGuid1Text = new List<M_Language>
                                        {
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.ko,
                                                LanguageData = "* 10초간 입력이 없으면 취소 처리됩니다."
                                            },
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.en,
                                                LanguageData = "en* 10초간 입력이 없으면 취소 처리됩니다."
                                            },
                                        };

                        InfoGuid2Text = new List<M_Language>();                        
                        CancelButtonWidth = PopupWidth / 2;
                        OKButtonWidth = PopupWidth / 2;
                        OKButtonEnabled = true;
                        OkButtonText = Languages.GetMessages("CommonRetry");
                        CancelButtonText = Languages.GetMessages("CommonCancel");
                        TimeOutSeconds = 10d;                        
                    }
                    break;
                case "CertifySuccessVisible":
                    if (CertifySuccessVisible)
                    {
                        ScanGuidText = new List<M_Language>
                                        {
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.ko,
                                                LanguageData = "인증 처리가 완료 되었습니다."
                                            },
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.en,
                                                LanguageData = "en인증 처리가 완료 되었습니다."
                                            },
                                        };
                        InfoGuid1Text = new List<M_Language>
                                        {
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.ko,
                                                LanguageData = "* 사용 가능 포인트를 확인하세요."
                                            },
                                            new M_Language
                                            {
                                                Type = SupportLanguageType.en,
                                                LanguageData = "en* 사용 가능 포인트를 확인하세요."
                                            },
                                        };
                        InfoGuid2Text = new List<M_Language>();                        
                        CancelButtonWidth = 0d;
                        OkButtonText = Languages.GetMessages("CommonOK");
                        OKButtonWidth = PopupWidth;
                        OKButtonEnabled = true;
                        TimeOutSeconds = 5d;
                    }
                    break;
            }
        }
        #endregion Event Handlers


    }

}