using ConsoleApp;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SlnMesnac.Business;
using SlnMesnac.Business.business;
using SlnMesnac.Common;
using SlnMesnac.Repository.service;
using SlnMesnac.WPF.Page;
using SlnMesnac.WPF.Page.Generate;
using System;
using System.ComponentModel;
using System.IO.Ports;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;

namespace SlnMesnac.WPF.ViewModel
{
    public class MainWindowViewModel: INotifyPropertyChanged
    {
        private readonly ILogger<MainWindowViewModel> _logger;

        //代码生成
        private readonly GenerateControl generateControl = new GenerateControl();
        private readonly EmployeeLoginPage _employeeLoginPage = new EmployeeLoginPage();
        private readonly ExecutePage _executePage = new ExecutePage();
        private IBaseStaffService _baseStaffService;
        private System.Timers.Timer timer;
        public delegate void UIDCodeDelegate(string code);
        public event UIDCodeDelegate UIDCodeDelegateEvent;
        private SerialPortBusiness serialPortBusiness;
        private string serialPort;
        private int baudRate;
        private int parity;
        private int dataBits;
        private int stopBits;
        public static int wins = 1;//1为人员登录，2为强退确认，3为交接换班

        #region 委托定义
        public delegate void TransferOrderCode(string orderCode);
        public static event TransferOrderCode? TransferOrderCodeEvent;
        #endregion

        #region 参数定义
        ///// <summary>
        ///// PLC设备状态
        ///// </summary>
        //private int _PlcStatus = 0;
        //public int PlcStatus
        //{
        //    get { return _PlcStatus; }
        //    set { _PlcStatus = value; RaisePropertyChanged(nameof(PlcStatus)); }
        //}

        ///// <summary>
        ///// 打卡机状态
        ///// </summary>
        //private int _clockStatus = 0;
        //public int ClockStatus
        //{
        //    get { return _clockStatus; }
        //    set { _clockStatus = value; RaisePropertyChanged(nameof(ClockStatus)); }
        //}

        /// <summary>
        /// 扫码枪状态
        /// </summary>
        private int _codeGunStatus = 0;
        public int CodeGunStatus
        {
            get { return _codeGunStatus; }
            set 
            { 
                _codeGunStatus = value; 
                OnPropertyChanged("CodeGunStatus"); 
            }
        }

        /// <summary>
        /// 订单号框
        /// </summary>
        private string orderCodeText;
        public string OrderCodeText
        {
            get { return orderCodeText; }
            set
            {
                orderCodeText = value;
                OnPropertyChanged("OrderCodeText");
            }
        }


        public System.Windows.Controls.UserControl _content;
        public System.Windows.Controls.UserControl UserContent
        {
            get { return _content; }

            set
            {
                _content = value;
                OnPropertyChanged("UserContent");
            }
        }
        #endregion

        #region 事件定义
        /// <summary>
        /// 界面跳转按钮事件
        /// </summary>
        public RelayCommand<object> ControlOnClickCommand { get; set; }

        /// <summary>
        /// 打开系统键盘
        /// </summary>
        public RelayCommand<object> OpenSystemKeyboardCommand { get; set; }

        /// <summary>
        /// 窗体控制
        /// </summary>
        public RelayCommand<object> FormControlCommand { get; set; }

        /// <summary>
        /// 连接
        /// </summary>
        public ICommand ConnectCommand {  get; set; }

        /// <summary>
        /// 断开
        /// </summary>
        public ICommand BreakCommand { get; set; }

        /// <summary>
        /// 确认
        /// </summary>
        public ICommand ConfirmCommand { get; set; }
        #endregion

        public MainWindowViewModel()
        {
            //UserContent = _employeeLoginPage;
            IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
                .SetBasePath(System.AppContext.BaseDirectory)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
            IConfigurationRoot configuration = configurationBuilder.Build();
            serialPort = configuration.GetSection("AppConfig")["serialPort"];
            baudRate = Convert.ToInt32(configuration.GetSection("AppConfig")["baudRate"]);
            parity = Convert.ToInt32(configuration.GetSection("AppConfig")["parity"]);
            dataBits = Convert.ToInt32(configuration.GetSection("AppConfig")["dataBits"]);
            stopBits = Convert.ToInt32(configuration.GetSection("AppConfig")["stopBits"]);
            UserContent = _executePage;
            _logger = App.ServiceProvider.GetService<ILogger<MainWindowViewModel>>();
            serialPortBusiness = App.ServiceProvider.GetService<SerialPortBusiness>();
            var info = App.ServiceProvider.GetService<StringChange>();
            ControlOnClickCommand = new RelayCommand<object>(obj => ControlOnClick(obj));
            OpenSystemKeyboardCommand = new RelayCommand<object>(obj => OpenSystemKeyboard(obj));
            FormControlCommand = new RelayCommand<object>(x => FormControl(x));
            timer = new System.Timers.Timer(1000);  //  1  second  interval
            timer.Elapsed += Timer_Tick;
            timer.Enabled = true;
            this.Init();
            ConnectCommand = new RelayCommand(OpenSerialPort);
            BreakCommand = new RelayCommand(CloseSerialPort);
            ConfirmCommand = new RelayCommand(Confirm);
            SerialPortBusiness.ReceivedBarcodeInfoEvent += info =>
            {
                info = OrderCodeText;
            };
            ExecuteViewModel.ClearOrderCodeAction += ClearOrderCode;
        }

        /// <summary>
        /// 确认
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private void Confirm()
        {
            string orderCode = OrderCodeText;
            TransferOrderCodeEvent?.Invoke(orderCode);
        }

        /// <summary>
        /// 按钮文字转换事件
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #region 定义参数
        /// <summary>
        /// 当前时间
        /// </summary>
        private string _currentTimeText = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        public string CurrentTimeText
        {
            get { return _currentTimeText; }
            set { _currentTimeText = value; OnPropertyChanged("CurrentTimeText"); }
        }

        private int _serialPortDeviceStatus = 0;
        public int SerialPortDeviceStatus
        {
            get { return _serialPortDeviceStatus; }
            set { _serialPortDeviceStatus = value; OnPropertyChanged("SerialPortDeviceStatus"); }
        }
        #endregion

        /// <summary>
        /// 清空订单编码
        /// </summary>
        private void ClearOrderCode()
        {
            OrderCodeText = "";
        }

        /// <summary>
        ///  窗体控制
        /// </summary>
        /// <param name="obj"></param>
        private void FormControl(object obj)
        {
            try
            {
                string controlType = obj as string;
                switch (controlType)
                {
                    // 关闭当前窗口
                    case "Exit":
                        //Environment.Exit(0);
                        Application.Current.Shutdown();
                        break;
                    case "Generate":
                        UserContent = generateControl;
                        break;
                    // 还原 或者 最大化当前窗口
                    case "Normal":
                        if (Application.Current.MainWindow.WindowState == WindowState.Normal)
                        {
                            Application.Current.MainWindow.WindowState = WindowState.Maximized;
                            break;
                        }
                        if (Application.Current.MainWindow.WindowState == WindowState.Maximized)
                        {
                            Application.Current.MainWindow.WindowState = WindowState.Normal;
                            break;
                        }
                        break;

                    // 最小化当前窗口
                    case "Minimized":
                        Application.Current.MainWindow.WindowState = WindowState.Minimized;
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("窗体控制逻辑异常", ex);
            }
        }

        /// <summary>
        /// 初始串口
        /// </summary>
        private void Init()
        {
            this.serialPortBusiness.RefreshSerialPortDeviceStatusEvent += isFlag =>
            {

                App.Current.Dispatcher.BeginInvoke((Action)(() =>
                {
                    SerialPortDeviceStatus = isFlag;
                }));
            };
        }

        /// <summary>
        /// 打开串口
        /// </summary>
        private void OpenSerialPort()
        {
            try
            {
                this.GetParity(out int parity);
                this.serialPortBusiness.OpenSerialPort(serialPort, baudRate, parity, dataBits, stopBits);
            }
            catch (Exception ex)
            {
                _logger.LogError($"打开串口通讯异常:{ex.Message}");
            }
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        private void CloseSerialPort()
        {
            try
            {
                this.serialPortBusiness.CloseSerialPort();
            }
            catch (Exception ex)
            {
                _logger.LogError($"关闭串口通讯异常:{ex.Message}");
            }
        }

        /// <summary>
        /// 转换校验位
        /// </summary>
        /// <param name="parity"></param>
        private void GetParity(out int parity)
        {
            switch (serialPort)
            {
                case "None":
                    parity = 0;
                    break;
                case "Odd":
                    parity = 1;
                    break;
                case "Even":
                    parity = 2;
                    break;
                case "Mark":
                    parity = 3;
                    break;
                case "Space":
                    parity = 4;
                    break;
                default:
                    parity = 0;
                    break;
            }
        }

        /// <summary>
        /// 打开系统键盘
        /// </summary>
        /// <param name="obj"></param>
        private void OpenSystemKeyboard(object obj)
        {
            System.Diagnostics.Process.Start("osk.exe");
        }

        /// <summary>
        /// 界面跳转
        /// </summary>
        private void ControlOnClick(object obj)
        {
            try
            {
                string info = obj as string;
                //UserContent = inStoreInfoControl;
                switch (info)
                {
                    case "Execute":
                        UserContent = _executePage;
                        break;
                    case "Employee":
                        UserContent = _employeeLoginPage;
                        break;
                    default:
                        UserContent = _executePage;
                        break;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("界面跳转逻辑异常", ex);
            }
        }

        private void Timer_Tick(object sender, ElapsedEventArgs e)
        {
            CurrentTimeText = DateTime.Now.ToString("yyyy-MM-dd  HH:mm:ss");
        }

        public void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
