using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Prism.Commands;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using StartServerWPF.Models;
using StartServerWPF.Modules.Main.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;

namespace StartServerWPF.Modules.Main.ViewModels
{
    public class SetParamViewModel : BindableBase
    {
        public SetParamViewModel(IDialogService dialogService, SystemConfigModel configModel, 
                                 WorkareaModel workareaModel, WorkareasModelArray workareasModelArray)
        {
            this._dialogService = dialogService;
            _systemConfig = configModel;
            WareaModel = workareaModel;
            wareaModelSingleton = workareaModel;
            this._workareasModelArray = workareasModelArray;
            MainModel = _systemConfig.vpnInfo;
            WorkareaNameSource = new ObservableCollection<string>();
            _workareasModelArray.workarea.Select(n=>n.workareaname).ToList().ForEach(a=> WorkareaNameSource.Add(a));           
        }
        private string _title = "应用列表";
        public string Title => _title;

        string apmStationFile = string.Empty;
        string apmttime2dFile = string.Empty;
        private readonly IDialogService _dialogService;
        private SystemConfigModel _systemConfig;
        private  WorkareasModelArray _workareasModelArray;
        private ObservableCollection<string> _workareaNameSource;
        public ObservableCollection<string> WorkareaNameSource
        {
            get => _workareaNameSource;
            set { SetProperty(ref _workareaNameSource, value); }
        }

        private int _wareaSelectedIndex;
        public int WareaSelectedIndex
        {
            get => _wareaSelectedIndex;
            set {
                if (value >= 0)
                {
                    try
                    {
                        var area = _workareasModelArray.workarea[value];
                        WareaModel.savepath = area.filepath;
                        string file = Path.Combine(area.filepath, Path.GetFileName(area.filepath) + ".json");
                        string json = File.ReadAllText(file);
                        WareaModel = JsonConvert.DeserializeObject<WorkareaModel>(json);
                    }
                    catch (Exception ex)
                    {
                        //生成工区默认配置文件
                        string str = File.ReadAllText(Path.Combine(JsonParser.workareaPath, "Workarea.json"));
                        string path = WareaModel.savepath;
                        WareaModel = JsonConvert.DeserializeObject<WorkareaModel>(str);
                        WareaModel.savepath = path;
                        string file = Path.Combine(path, Path.GetFileName(path) + ".json");
                        WareaModel.workareaname = Path.GetFileName(WareaModel.savepath);

                        File.WriteAllText(file, JsonConvert.SerializeObject(WareaModel));                     
                        //MessageBox.Show("当前工区目录配置文件不存在，" + ex.Message);
                    } 
                }
                SetProperty(ref _wareaSelectedIndex, value);
            }
        }
        private WorkareaModel wareaModelSingleton = null;
        private WorkareaModel _wareaModel = new WorkareaModel();
        public WorkareaModel WareaModel
        {
            get => _wareaModel;
            set { SetProperty(ref _wareaModel, value); }
        }
        private string _addWorkareaName;
        public string AddWorkareaName
        {
            get => _addWorkareaName;
            set { SetProperty(ref _addWorkareaName, value); }
        }

        private VpnInfo _mainModel = new VpnInfo();
        public VpnInfo MainModel
        {
            get => _mainModel;
            set { SetProperty(ref _mainModel, value); }
        }

        public DelegateCommand LoadedCommand => new(() =>
        {
            apmStationFile = string.Empty;
            apmttime2dFile = string.Empty;
            WareaSelectedIndex = _workareasModelArray.selectIndex;
        });

        public DelegateCommand AddItemCommand => new(() =>
        {
            DialogParameters param = new DialogParameters();
        //    param.Add("type", 1);// 编辑
            _dialogService.ShowDialog("AddWorkAreaDialog",
             param,
             new Action<IDialogResult>(result =>
             {
                 if (result != null && result.Result == ButtonResult.OK)
                 {
                     var area = result.Parameters.GetValue<Workareas>("param1");
                     var file = _workareasModelArray.workarea.Where(f => f.workareaname == area.workareaname).FirstOrDefault();
                     if (file == null)
                     {
                         _workareasModelArray.workarea.Add(area);
                         WorkareaNameSource.Add(area.workareaname);
                         WareaSelectedIndex= WorkareaNameSource.Count()-1;
                     }
                     else
                     {
                         //更新当前工区目录
                         file.filepath = area.filepath;
                         WareaSelectedIndex = _workareasModelArray.selectIndex;
                     }
                 }
             }));
        });

        public DelegateCommand ImportCommand => new(() =>
        {
            System.Windows.Forms.OpenFileDialog fbd = new System.Windows.Forms.OpenFileDialog();
            fbd.Multiselect = false;
            fbd.Filter = ".json|*.json|.txt|*.txt";
            if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    string jsonStr = File.ReadAllText(fbd.FileName);
                    _workareasModelArray = JsonConvert.DeserializeObject<WorkareasModelArray>(jsonStr);
                    WorkareaNameSource = new ObservableCollection<string>();
                    _workareasModelArray.workarea.Select(n => n.workareaname).ToList().ForEach(a => WorkareaNameSource.Add(a));
                    WareaSelectedIndex = _workareasModelArray.selectIndex;
                    var item = _workareasModelArray.workarea[_workareasModelArray.selectIndex];
                    string areaPath = Path.Combine(item.filepath, Path.GetFileName(item.filepath) + ".json");
                    var currentWorkarea = new WorkareaModel();
                    if (File.Exists(areaPath))
                    {
                        string workarea = File.ReadAllText(areaPath);
                        currentWorkarea = JsonConvert.DeserializeObject<WorkareaModel>(workarea);
                        if (currentWorkarea.StationConfig.Stations == null)
                        {
                            currentWorkarea.StationConfig.Stations = currentWorkarea.CreateStationFromCSV(Path.Combine(JsonParser.workareaPath, currentWorkarea.apmModel.station), currentWorkarea.StationConfig.Location)
                                                      ?.Select(a => new StationState { IsEnable = a.Enable, Name = a.Num }).ToList();
                        }
                        WareaModel = currentWorkarea;
                    }
                    else
                    {
                        MessageBox.Show("工区配置文件不存在！");
                    }
                }
                catch (Exception ex)
                {

                    MessageBox.Show("导入工区失败，" + ex);
                }
            }
        });

        public DelegateCommand DeleteItemCommand => new(() =>
        {
            if (MessageBox.Show($"删除{WareaModel.workareaname}工区所有文件？", "提示", MessageBoxButton.OKCancel,
                   MessageBoxImage.Exclamation) == MessageBoxResult.OK)
            {
                if (Directory.Exists(WareaModel.savepath))
                {
                    Directory.Delete(WareaModel.savepath, true);
                }
               var area= _workareasModelArray.workarea.Where(a => a.workareaname == WareaModel.workareaname).FirstOrDefault();
                WorkareaNameSource.Remove(WareaModel.workareaname);
                _workareasModelArray.workarea.Remove(area);
                WareaSelectedIndex =0;
            }
        });
   
        public DelegateCommand<object> SelectFileCommand => new((obj) =>
        {      
            string para = obj.ToString();
            System.Windows.Forms.OpenFileDialog fbd = new System.Windows.Forms.OpenFileDialog();
            fbd.Multiselect = false;
            //   fbd.InitialDirectory = Path.GetFullPath(_wareaModel.savepath);
            if (fbd.ShowDialog()== System.Windows.Forms.DialogResult.OK)
            {
                switch (para)
                {
                    case "apmsStation":
                        WareaModel.apmModel.station = fbd.SafeFileName;
                        apmStationFile = fbd.FileName;

                        WareaModel.StationConfig.Stations= WareaModel.CreateStationFromCSV(apmStationFile, WareaModel.StationConfig.Location)
                                                      ?.Select(a => new StationState { IsEnable = a.Enable, Name = a.Num }).ToList();
                        break;
                    case "apmsttime2d":
                        WareaModel.apmModel.ttime[0].ttime2d = fbd.SafeFileName;
                        apmttime2dFile = fbd.FileName;
                        break;
                    default:
                        break;
                }
            }
        });

        public DelegateCommand<object> FilePathSaveCommand=> new((obj)=>
        {
            string para= obj.ToString();
            System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog();
          //  fbd.SelectedPath = MainModel.DataSavePath;
            fbd.ShowNewFolderButton = true;
            if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string path= fbd.SelectedPath.Replace("\\", "/");
                if (para == "savepath")
                {
                    WareaModel.savepath = path;
                }

            }
        });
        public DelegateCommand LogPathSaveCommand=> new(() =>
        {
            System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog();
            fbd.SelectedPath = System.Environment.CurrentDirectory + "\\" + MainModel.SystemLogPath;
            fbd.ShowNewFolderButton = true;
            if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                MainModel.SystemLogPath = fbd.SelectedPath;
            }
        });

        public ICommand ConfirmCommand
        {
            get => new DelegateCommand(() =>
            {
                // 数据校验（关键字段不能为空、年龄做数字区间的校验、做UserName的唯一检查（自定义特性检查）
                if (string.IsNullOrEmpty(WareaModel.savepath) 
                || string.IsNullOrEmpty(WareaModel.apmModel.station)
                || string.IsNullOrEmpty(WareaModel.apmModel.ttime[0].ttime2d))
                {
                    MessageBox.Show("目录内容不能为空", "提示", MessageBoxButton.OK);
                    return;
                }
                if (MessageBox.Show("确认修改？", "参数设置", MessageBoxButton.OKCancel,
                      MessageBoxImage.Exclamation) == MessageBoxResult.OK)
                {
                    //1 Workarea配置更新，选择的索引
                    _workareasModelArray.selectIndex = WareaSelectedIndex;
                    JsonParser.WriteSystemConfigFile(Path.Combine(JsonParser.workareaPath, "Workareas.json"), _workareasModelArray);          
                    _wareaModel.apmModel.channels = new List<StationChannelsModel>
                    {
                            new StationChannelsModel()
                            {
                              location = _wareaModel.StationConfig.Location,
                              network = _wareaModel.StationConfig.Network,
                              channels = _wareaModel.StationConfig.Channels,
                              station = string.Join(",", _wareaModel.StationConfig.Stations.Where(p => p.IsEnable).Select(n => n.Name))
                            }
                    };

                    wareaModelSingleton.workareaname = _wareaModel.workareaname;
                    wareaModelSingleton.apmpush2wx  =_wareaModel.apmpush2wx; 
                    wareaModelSingleton.toolpush2wx  =_wareaModel.toolpush2wx;
                    wareaModelSingleton.savepath    =_wareaModel.savepath;
                    wareaModelSingleton.chartsavepath=_wareaModel.chartsavepath;
                    wareaModelSingleton.apmsavepath =_wareaModel.apmsavepath;
                    wareaModelSingleton.toolsavepath =_wareaModel.toolsavepath;
                    wareaModelSingleton.delayTime    =_wareaModel.delayTime;
                    wareaModelSingleton.apmModel = _wareaModel.apmModel;
                    wareaModelSingleton.StationConfig = _wareaModel.StationConfig;

                    JsonParser.WriteSystemConfigFile(Path.Combine(_wareaModel.savepath, Path.GetFileName(_wareaModel.savepath) + ".json"), _wareaModel);
                                  
                    string temJson = JsonConvert.SerializeObject(_wareaModel);
                    var curWorkarea = JsonConvert.DeserializeObject<WorkareaModel>(temJson);
                    if (!string.IsNullOrEmpty(apmStationFile))
                    {
                        string destFileName = Path.GetFullPath(Path.Combine(curWorkarea.savepath, curWorkarea.apmModel.station));
                        if (destFileName != apmStationFile)
                        {
                            File.Copy(apmStationFile, destFileName, true);
                        }
                        apmStationFile = null;
                    }
                    if (!string.IsNullOrEmpty(apmttime2dFile))
                    {
                       string destFileName = Path.GetFullPath(Path.Combine(curWorkarea.savepath, curWorkarea.apmModel.ttime[0].ttime2d));
                        if (destFileName != apmttime2dFile)
                        {
                            File.Copy(apmttime2dFile, destFileName, true);
                        }
                        apmttime2dFile = null;
                    }

                    //2 gw.apms.exe配置更新
                    {
                        ApmsModel apms = curWorkarea.apmModel;
                        apms.station = Path.GetFullPath(Path.Combine(curWorkarea.savepath, curWorkarea.apmModel.station)).Replace("\\", "/");
                        apms.ttime[0].ttime2d = Path.GetFullPath(Path.Combine(curWorkarea.savepath, curWorkarea.apmModel.ttime[0].ttime2d)).Replace("\\", "/");
                        apms.savepath = Path.Combine(curWorkarea.savepath, curWorkarea.apmsavepath);
                        apms.push2wx = curWorkarea.apmpush2wx ? "YES" : "NO";
                        JsonParser.WriteSystemConfigFile(Path.Combine(_systemConfig.proApms.ProPath, "apms.json"), apms);
                    }

                    //3 gw.tools.exe配置更新
                    {
                        ApmsModel tools = curWorkarea.apmModel;
                        tools.station = Path.GetFullPath(Path.Combine(curWorkarea.savepath, curWorkarea.apmModel.station)).Replace("\\", "/");
                        tools.ttime[0].ttime2d = Path.GetFullPath(Path.Combine(curWorkarea.savepath, curWorkarea.apmModel.ttime[0].ttime2d)).Replace("\\", "/");
                        tools.savepath =curWorkarea.savepath+"/"+ curWorkarea.toolsavepath;
                        tools.push2wx = curWorkarea.toolpush2wx ? "YES" : "NO"; ;
                        JsonParser.WriteSystemConfigFile(Path.Combine(_systemConfig.proTools.ProPath, "apms.json"), tools);
                    
                     //4 SystemConfig.json配置更新
                        int index = _systemConfig.proTools.ProParams.IndexOf("-savepath");
                        string str = _systemConfig.proTools.ProParams.Substring(0, index) + "-savepath";
                        _systemConfig.proTools.ProParams = $"{str} {Path.Combine(curWorkarea.savepath, curWorkarea.chartsavepath).Replace("\\", "/")} -delay {curWorkarea.delayTime * 60}";                     
                        JsonParser.WriteSystemConfigFile(JsonParser.systemConfigPath, _systemConfig);
                    }
                    //dataProTools配置更新
                    ApmsModel protools = curWorkarea.apmModel;
                    // tools.savepath = SavePath;      // _workareaModel.savepath + "/" +SavePath;;
                    protools.station = Path.GetFullPath(Path.Combine(curWorkarea.savepath, curWorkarea.apmModel.station)).Replace("\\", "/");
                    protools.ttime[0].ttime2d = Path.GetFullPath(Path.Combine(curWorkarea.savepath, curWorkarea.apmModel.ttime[0].ttime2d)).Replace("\\", "/");
                  //  protools.push2wx = _workareaModel.toolpush2wx ? "YES" : "NO";

                    JsonParser.WriteSystemConfigFile(Path.Combine(_systemConfig.dataProTools.ProPath, "apms.json"), protools);

                    //5 gw.recvftp.exe配置更新
                    JsonParser.UpdateRecvJson(Path.Combine(_systemConfig.proRecv.ProPath, _systemConfig.proRecv.JsonPath), Path.Combine(curWorkarea.savepath,  curWorkarea.chartsavepath).Replace("\\", "/"));
                }
            });
        }

    }
}
