using AutoMapper;
using HandyControl.Controls;
using LogoForceTestApp.Core;
using LogoForceTestApp.Core.Mvvm;
using LogoForceTestApp.Modules.MainModule.Models;
using LogoForceTestApp.Modules.MainModule.Views;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using PropertyChanged;
using Repository;
using Repository.Entiies;
using System;
using System.Collections.Generic;
using System.IO;
using System.Management;
using System.Net.NetworkInformation;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Windows.Forms;
using Team.Utility;

namespace LogoForceTestApp.Modules.MainModule.ViewModels
{
    public class ParamPageViewModel: RegionViewModelBase
    {
        private readonly IMapper _mapper;
        private readonly IEventAggregator _eventAggregator;
        private readonly IWritableOptions<AppSettings> _appSettings;
        private readonly IRepository _repository;
        private string _csvPath;
        public string CSVPath 
        { 
            get=>_csvPath;
            set {
                SetProperty(ref _csvPath, value);
                SetChanged();
            }
        }
        private string _imageSavePath;
        public string ImageSavePath
        {
            get => _imageSavePath;
            set
            {
                SetProperty(ref _imageSavePath, value);
                SetChanged();
            }
        }
        private bool _selected;
        public bool Selected
        {
            get => _selected;
            set
            {
                SetProperty(ref _selected, value);
                SetChanged();
            }
        }
        public bool TraceDisable { get; set; }
        public bool UnUseOee { get; set; }
        //[OnChangedMethod("SetChanged")]
        public string OeeIp { get; set; }
        //[OnChangedMethod("SetChanged")]
        public int OeePort { get; set; }
        //[OnChangedMethod("SetChanged")]
        public int WaitPartDuration { get; set; } = 1;
        public string Site { get; set; }
        public int StopDuration { get; set; } = 5;
        public string Floor { get; set; }
        public string Product { get; set; }
        public string Line { get; set; }
        public string ProcessOee { get; set; }
        public string TerminalId { get; set; }
        public string MachineId { get; set; }
        public string MacAddr { get; set; }
        public List<string> AddressSource { get; set; }
        public string Status { get; set; }
        public string OpId { get; set; }
        public string IpAddr { get; set; }
        public ParamDto Param { get; set; }
        public string OeePath { get; set; }
        public DelegateCommand SaveTraceParamCommand { get; set; }
        public DelegateCommand SelectFolderCommand { get; set; }
        public DelegateCommand SelectImageFolderCommand { get; set; }
        public DelegateCommand SaveOtherCommand { get; set; }
        public DelegateCommand SaveOeeCommand { get; set; }
        public DelegateCommand SelectOeeFolderCommand { get; set; }
        public DelegateCommand DebugCommand { get; set; }
        public ParamPageViewModel(IMapper mapper,IEventAggregator eventAggregator,
            IWritableOptions<AppSettings> appSettings,IRepository repository,IRegionManager regionManager 
            ):base(regionManager)
        {
            //AddressSource=new List<string>();
            AddressSource = GetMacAddress();
            _mapper = mapper;
            _eventAggregator = eventAggregator;
            _appSettings = appSettings;
            _repository = repository;
            CSVPath = _appSettings.Value.CSVPath;
            Selected = _appSettings.Value.UnUseUpload;
            TraceDisable = _appSettings.Value.TraceDisable;
            ImageSavePath = _appSettings.Value.ImageSavePath;
            Build = _appSettings.Value.Builds;
            Project=_appSettings.Value.Project;
            Process=_appSettings.Value.Process; 
            AIM_UNIQUE=_appSettings.Value.AIM_UNIQUE;
            AimName = _appSettings.Value.AimName;
            INSPECTION_PROGRAM_NAME = _appSettings.Value.INSPECTION_PROGRAM_NAME;
            Part=_appSettings.Value.Part;
            SaveTraceParamCommand = new DelegateCommand(SaveTraceParam);
            SaveOtherCommand = new DelegateCommand(SaveOther);
            SaveOeeCommand = new DelegateCommand(SaveOeeConfig);
            SelectOeeFolderCommand = new DelegateCommand(SelectOeeFolder);
            DebugCommand = new DelegateCommand(GoOeeDebugPage);
            var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "param.json");
            if (File.Exists(filePath))
            {
                using var stream = new StreamReader(filePath);
                var oeejson= stream.ReadToEnd();
                var param = JsonConvert.DeserializeObject<Param>(oeejson);
                Param= _mapper.Map<ParamDto>(param);
                Param.PropertyChanged += Param_PropertyChanged;
            }
            else
            {
                Param = new ParamDto
                {
                    station_id = "LkYC_BO7_2F_01_002_TRACE",
                    fixture_id = "H-76HO-SMA40-2200-A-00003",
                    cavity_id = "\"1/2/3/4\"",
                    line_id = "B07-2F-01",
                    station_vendor = "Team",
                    test = "Logo 30N Non-Destructive Test",
                    OpId= "C10088888"
                };
                Param.PropertyChanged += Param_PropertyChanged;
            }
            if (string.IsNullOrWhiteSpace(Param.OpId))
            {
                Param.OpId = "C10088888";
            }
            if (string.IsNullOrWhiteSpace(Param.DownLimit))
            {
                Param.DownLimit = "30";
            }
            if (string.IsNullOrWhiteSpace(Param.UpperLimit))
            {
                Param.UpperLimit = "60";
            }

            var oeePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "oee.json");
           
            if (File.Exists(oeePath))
            {
                var streamOee = new StreamReader(oeePath);
                var json = streamOee.ReadToEnd();
                var oeeConfig=JsonConvert.DeserializeObject<OeeConfig>(json);
                UnUseOee = oeeConfig.UnUse;
                OeeIp = oeeConfig.Ip;
                OeePort = oeeConfig.Port;
                WaitPartDuration = oeeConfig.WaitPartDuration;
                StopDuration = oeeConfig.StopDuration;
                Site = oeeConfig.Site;
                Floor = oeeConfig.Floor;
                Product= oeeConfig.Product;
                Line = oeeConfig.Line;
                ProcessOee = oeeConfig.Process;
                TerminalId = oeeConfig.TerminalId;
                MachineId = oeeConfig.MachineId;
                MacAddr = oeeConfig.Macaddr;
                IpAddr = oeeConfig.Ipaddr;
                OeePath = oeeConfig.OeePath;

            }
            SelectFolderCommand = new DelegateCommand(SelectFolder);
            SelectImageFolderCommand = new DelegateCommand(SelectImageFolder);
        }

        private void GoOeeDebugPage()
        {
            //RegionManager.RequestNavigate(RegionNames.ContentRegion, nameof(OeeDebugPage));
        }

        private void SelectOeeFolder()
        {

            FolderBrowserDialog dilog = new()
            {
                Description = "请选择文件夹"
            };

            if (dilog.ShowDialog() is System.Windows.Forms.DialogResult.OK or System.Windows.Forms.DialogResult.Yes)
            {
                OeePath = dilog.SelectedPath;
            }
        }

        public static List<string> GetMacAddress()
        {

            List<string> macAddressList = new();
            string MoAddress = " ";
            ManagementClass mc = new("Win32_NetworkAdapterConfiguration");
                   ManagementObjectCollection moc2 = mc.GetInstances();
            foreach (ManagementObject mo in moc2)
            {
                if ((bool)mo["IPEnabled"] == true)
                {
                    MoAddress = mo["MacAddress"].ToString();
                    MoAddress.Replace(":", "-");
                    macAddressList.Add(MoAddress);
                }
                    
                mo.Dispose();
            }
                    // return MoAddress.ToString()
            return macAddressList;
        }

        public static List<string> GetIpAddress()
        {
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();

            List<string> ipList = new();

            foreach (NetworkInterface adapter in nics)
            {
                if (adapter.OperationalStatus == OperationalStatus.Up)
                {
                    foreach (UnicastIPAddressInformation ip in adapter.GetIPProperties().UnicastAddresses)
                    {
                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {
                            ipList.Add(ip.Address.ToString());
                        }
                    }
                }
            }

            return ipList;
        }
        private void SaveOeeConfig()
        {
            if (!Directory.Exists(OeePath))
            {
                Growl.Error("保存路径不存在,请重新选择");
                return;
            }
            if (!GetMacAddress().Contains(MacAddr))
            {
                Growl.Error("mac地址不正确,请重新输入");
                return;
            }
           
            var oeeConfig = new OeeConfig
            {
                Ip = OeeIp,
                Port = OeePort,
                WaitPartDuration = WaitPartDuration,
                StopDuration = StopDuration,
                Site = Site,
                Floor = Floor,
                Product = Product,
                Line = Line,
                Vendor = "Team",
                Process = ProcessOee,
                TerminalId = TerminalId,
                MachineId = MachineId,
                Op_id = Param.OpId,
                Ipaddr = IpAddr,
                Macaddr = MacAddr,
                OeePath = OeePath,
                UnUse = UnUseOee
            };

            var config = JsonConvert.SerializeObject(oeeConfig, Formatting.Indented);
            var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                "oee.json");
            using var stream = new StreamWriter(filePath);
            stream.Write(config);
            Growl.Info("保存配置完成");
            //_eventAggregator.GetEvent<OeeConfigChangedPublish>().Publish(oeeConfig);
            return;
        }

        private bool _loaded;

        public override void OnNavigatedFrom(NavigationContext navigationContext)
        {
            _loaded=false;
            base.OnNavigatedFrom(navigationContext);
        }
        public override void OnNavigatedTo(NavigationContext navigationContext)
        {
            _loaded = true;
            base.OnNavigatedTo(navigationContext);
        }
        private void LoginSuccess(bool obj)
        {
            if (_loaded)
            {
                RegionManager.RequestNavigate(RegionNames.ContentRegion,nameof(LoginPage));
            }
        }

        private readonly List<string> _storageChangedList = new();
        private void Param_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            _storageChangedList.Add(e.PropertyName);
            SetChanged(e.PropertyName);
        }

        private void SetChanged([CallerMemberName] string propertyName = null)
        {
            _repository.Add(new ParamLog
            {
                OperateAction = OperateAction.ChangeParam,
                Content = $"{propertyName}参数修改",
                Id=Guid.NewGuid(),
                Occured=DateTime.Now,
                OperateObject=propertyName,
                UserName=CurrentUser.CurrentUserName
            });
        }
        private async Task HasSaved(string propertyName)
        {
            await _repository.AddAsync(new ParamLog
            {
                OperateAction = OperateAction.ChangeParam,
                Content = $"{propertyName}参数修改并保存成功",
                Id = Guid.NewGuid(),
                Occured = DateTime.Now,
                OperateObject = propertyName,
                UserName = CurrentUser.CurrentUserName
            });
        }
        private void SelectFolder()
        {
            System.Windows.Forms.FolderBrowserDialog dilog = new System.Windows.Forms.FolderBrowserDialog
            {
                Description = "请选择文件夹"
            };

            if (dilog.ShowDialog() == System.Windows.Forms.DialogResult.OK || dilog.ShowDialog() == System.Windows.Forms.DialogResult.Yes)
            {
                CSVPath = dilog.SelectedPath;
            }
        }

        private void SelectImageFolder()
        {
            System.Windows.Forms.FolderBrowserDialog dilog = new System.Windows.Forms.FolderBrowserDialog
            {
                Description = "请选择文件夹"
            };

            if (dilog.ShowDialog() is System.Windows.Forms.DialogResult.OK or System.Windows.Forms.DialogResult.Yes)
            {
                ImageSavePath = dilog.SelectedPath;
            }
        }
       
        private void SaveOther()
        {
            _appSettings.Update(async c =>
            {
                if (c.CSVPath != CSVPath)
                {
                    c.CSVPath = CSVPath;
                    await HasSaved(nameof(CSVPath));
                }
                if (c.UnUseUpload != Selected)
                {
                    c.UnUseUpload = Selected;
                    await HasSaved(nameof(c.UnUseUpload));
                }
                if (c.ImageSavePath != ImageSavePath)
                {
                    c.ImageSavePath = ImageSavePath;
                    await HasSaved(nameof(c.ImageSavePath));
                }
                if (c.Process!=Process)
                {
                    c.Process = Process;
                    await HasSaved(nameof(c.Process));
                }
                if (c.AIM_UNIQUE != AIM_UNIQUE)
                {
                    c.AIM_UNIQUE = AIM_UNIQUE;
                    await HasSaved(nameof(c.AIM_UNIQUE));
                }
                if (c.AimName != AimName)
                {
                    c.AimName = AimName;
                    await HasSaved(nameof(c.AimName));
                }

                if (c.AIM_UNIQUE != AIM_UNIQUE)
                {
                    c.AIM_UNIQUE = AIM_UNIQUE;
                    await HasSaved(nameof(c.AIM_UNIQUE));
                }
                if (c.INSPECTION_PROGRAM_NAME != INSPECTION_PROGRAM_NAME)
                {
                    c.INSPECTION_PROGRAM_NAME = INSPECTION_PROGRAM_NAME;
                    await HasSaved(nameof(c.INSPECTION_PROGRAM_NAME));
                }
                if (c.Project != Project)
                {
                    c.Project = Project;
                    await HasSaved(nameof(c.Project));
                }
                if (c.Part != Part)
                {
                    c.Part = Part;
                    await HasSaved(nameof(c.Part));
                }
                if (c.Builds != Build)
                {
                    c.Builds = Build;
                    await HasSaved(nameof(c.Builds));
                }
                if (c.TraceDisable != TraceDisable)
                {
                    c.TraceDisable = TraceDisable;
                    await HasSaved(nameof(c.TraceDisable));
                }
                //if (c.ID != Build)
                //{
                //    c.Builds = Build;
                //    await HasSaved(nameof(c.Builds));
                //}
            });
            
            Growl.Info("保存参数成功");
            _eventAggregator.GetEvent<OtherParamEvent>().Publish(true);
        }
        private async void SaveTraceParam()
        {
            var param = _mapper.Map<Param>(Param);
            var json = JsonConvert.SerializeObject(param);
            var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "param.json");
            using var stream = new StreamWriter(filePath);
            await stream.WriteAsync(json);
            await stream.FlushAsync();
            Growl.Info("保存trace参数成功");
            foreach (var item in _storageChangedList)
            {
                await HasSaved(item);
            }
            _storageChangedList.Clear();
            _eventAggregator.GetEvent<SaveTraceParam>().Publish(param);
        }

        private string aimName;

        public string AimName
        { 
            get => aimName;
            set
            {
                SetProperty(ref aimName, value);
                SetChanged();
            }
        }

        private string aIM_UNIQUE;

        public string AIM_UNIQUE 
        { 
            get => aIM_UNIQUE;
            set 
            { 
                SetProperty(ref aIM_UNIQUE, value);
                SetChanged();
            }

        }

        private string iNSPECTION_PROGRAM_NAME;

        public string INSPECTION_PROGRAM_NAME 
        { 
            get => iNSPECTION_PROGRAM_NAME;
            set { 
                SetProperty(ref iNSPECTION_PROGRAM_NAME, value); 
                SetChanged();
            }
        }

        private string project;

        public string Project { 
            get => project;
            set 
            { 
                SetProperty(ref project, value);
                SetChanged();
            } 
        }

        private string part;

        public string Part {
            get => part;
            set { 
                SetProperty(ref part, value);
                SetChanged();
            }
        }

        private string process;

        public string Process 
        { 
            get => process;
            set 
            { 
                SetProperty(ref process, value);
                SetChanged();
            }
        }

        private string build;

        public string Build 
        {
            get => build;
            set { 
                SetProperty(ref build, value);
                SetChanged();
            }
        }

    }
}