using FSI.Lib.MVVM;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Data;
using System.Windows.Input;

namespace FSI.Lib.Guis.Folder.Mgt
{
    public class ViewModel : MVVM.ViewModelBase
    {
        readonly IDataProvider _dataProvider;
        private string _search;
        private ICollectionView _collView;

        public ICommand RefreshCommand => new DelegateCommand(RefreshData);
        private ICommand _cmdQuickSearch;
        private ICommand _cmdOpen;
        private ICommand _cmdCopyToClip;

        public ViewModel(IDataProvider dataProvider)
        {
            Datas = new ObservableCollection<Model>();
            _dataProvider = dataProvider;

            _cmdQuickSearch = new RelayCommand<object>(ExecuteQuickSearch, CanExecuteQuickSearch);
            _cmdOpen = new RelayCommand<object>(ExecuteOpen, CanExecuteOpen);
            _cmdCopyToClip = new RelayCommand<object>(ExecuteCopyToClip, CanExecuteCopyToClip);
        }

        public ObservableCollection<Model> Datas { get; }
        public ObservableCollection<Model> FilteredData { get; set; }

        public Model SelectedData { get; set; }

        public IEnumerable<IInterface> InputData { get; set; }

        public void Load()
        {
            var datas = _dataProvider.Load(InputData);
            Datas.Clear();

            if (datas != null)
            {
                foreach (Model data in datas)
                {
                    Datas.Add(data);
                }
            }

            FilteredData = new ObservableCollection<Model>(Datas);
            _collView = CollectionViewSource.GetDefaultView(FilteredData);
        }

        public string Search
        {
            get => _search;
            set
            {
                _search = value;

                _collView.Filter = e =>
                {
                    var item = (Model)e;

                    return ((item.Plant?.StartsWith(_search, StringComparison.OrdinalIgnoreCase) ?? false)
                                                || (item.SubPlant?.StartsWith(_search, StringComparison.OrdinalIgnoreCase) ?? false)
#if NET472
                                                || (item.Path?.Contains(_search) ?? false)
                                                || (item.DescriptionDtl?.Contains(_search) ?? false)
#elif NET6_0
                                                || (item.Path?.Contains(_search, StringComparison.OrdinalIgnoreCase) ?? false)
                                                || (item.DescriptionDtl?.Contains(_search, StringComparison.OrdinalIgnoreCase) ?? false)
#endif
                                                );
                };

                _collView.Refresh();
                FilteredData = new ObservableCollection<Model>(_collView.OfType<Model>().ToList());
                OnPropertyChanged();
            }
        }

        public void QuickSearch(string search)
        {
            Search = search + " ";
        }

        private void RefreshData(object obj)
        {
            Search = string.Empty;
        }

        private bool CanExecuteQuickSearch(object obj)
        {
            return true;
        }

        private void ExecuteQuickSearch(object obj)
        {
            QuickSearch(obj.ToString());
        }

        public ICommand CmdQuickSearch
        {
            get { return _cmdQuickSearch; }
            set => _cmdQuickSearch = value;
        }

        private bool CanExecuteOpen(object obj)
        {
            if (Directory.Exists(SelectedData.Path))
                return true;
            else
                return false;
        }

        private void ExecuteOpen(object obj)
        {
            new Process
            {
                StartInfo = new ProcessStartInfo()
                {
                    FileName = "explorer.exe",
                    Arguments = SelectedData.Path
                }
            }.Start();
        }

        public ICommand CmdOpen
        {
            get { return _cmdOpen; }
            set => _cmdOpen = value;
        }

        private bool CanExecuteCopyToClip(object obj)
        {
            if (Directory.Exists(SelectedData.Path))
                return true;
            else
                return false;
        }

        private void ExecuteCopyToClip(object obj)
        {
            TextCopy.ClipboardService.SetText(SelectedData.Path);
        }

        public ICommand CmdCopyToClip
        {
            get { return _cmdCopyToClip; }
            set => _cmdCopyToClip = value;
        }
    }

    public class DataProvider : IDataProvider
    {
        public IEnumerable<Model> Load(IEnumerable<IInterface> folders)
        {
            var newDatas = new ObservableCollection<Model>();

            foreach (IInterface folder in folders)
            {
                Model newData = new();
                newData.Plant = folder.Plant;
                newData.SubPlant = folder.SubPlant;
                newData.Name = folder.Name;
                newData.Description = folder.Description;
                newData.Path = folder.Path;

                newDatas.Add(newData);
            }

            newDatas = new ObservableCollection<Model>(newDatas.OrderBy(i => i.DescriptionDtl));

            return newDatas;
        }
    }
}
