using Http.Core.Contexts;
using Newtonsoft.Json;
using PCUT.ViewModels;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238

namespace PCUT.Pages
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class DataCenterPage : Page
    {
        private const int MaxRecentFiles = 20;
        private FileListViewModel ViewModels { get; }
        public ObservableCollection<RecentFile> RecentFiles { get; }
        private readonly string _settingKey;

        public DataCenterPage()
        {
            this.InitializeComponent();
            ViewModels = DataContext as FileListViewModel;
            RecentFiles = new ObservableCollection<RecentFile>();
            
            _settingKey = $"RecentFilev2{UserContext.Instance.Profile.UserName}";
            ViewModels.SetFilterMetadataOnFileChange();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            var mainMenuPageViewModel = e.Parameter as MainMenuPageViewModel;
            ViewModels.Categories = mainMenuPageViewModel.Categories;
            ViewModels.Pagination.InitSearchText(mainMenuPageViewModel.DataCenterSearchValue);
            ViewModels.Pagination.TextSearched += (sender, args) =>
            {
                mainMenuPageViewModel.DataCenterSearchValue = args.Text;
            };
            base.OnNavigatedTo(e);
        }

        private async void Page_Loaded(object sender, RoutedEventArgs e)
        {
            ViewModels.MetadataModel.BindAll(Type, Brand, Series, Model, Subtypes, Year);

            LoadRecentFiles();
            await ViewModels.MetadataModel.LoadAllMetadataAsync();
            ViewModels.Pagination.Page = 1;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            ViewModels.Pagination.Dispose();
        }

        private void FileList_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
        {
            if (ViewModels.FilteredFiles.SelectedIndex >= 0)
            {
                var selectedItem = ViewModels.FilteredFiles.SelectedItem;

                UpsertRecentFile(selectedItem.Id, selectedItem.Name);
                this.Frame.Navigate(typeof(DesignCenterPage), selectedItem.Id);
            }
        }

        private void RecentFiles_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
        {
            if (RecentFileList.SelectedItem is RecentFile recentFile)
            {
                this.Frame.Navigate(typeof(DesignCenterPage), recentFile.ItemId);
            }
        }

        private void LoadRecentFiles()
        {
            var localSettings = ApplicationData.Current.LocalSettings;
            if (localSettings.Values.ContainsKey(_settingKey))
            {
                string json = (string)localSettings.Values[_settingKey];
                try
                {
                    var recentFiles = JsonConvert.DeserializeObject<IEnumerable<RecentFile>>(json);
                    foreach (var file in recentFiles)
                        RecentFiles.Add(file);
                }
                catch (JsonException)
                {
                    localSettings.Values.Remove(_settingKey);
                }
            }
        }

        private void UpsertRecentFile(string itemId, string fileName)
        {
            IList<RecentFile> recentFiles;
            var localSettings = ApplicationData.Current.LocalSettings;
            if (localSettings.Values.ContainsKey(_settingKey))
            {
                recentFiles = JsonConvert.DeserializeObject<IList<RecentFile>>(localSettings.Values[_settingKey] as string);
            }
            else
            {
                recentFiles = new List<RecentFile>();
            }
            UpsertRecentFile(recentFiles, itemId, fileName);
            localSettings.Values[_settingKey] = JsonConvert.SerializeObject(recentFiles);
        }

        private static void UpsertRecentFile(IList<RecentFile> recentFiles, string itemId, string fileName)
        {
            var file = recentFiles.FirstOrDefault(x => x.ItemId == itemId);
            if (file is null)
            {
                if (recentFiles.Count >= MaxRecentFiles)
                {
                    recentFiles.RemoveAt(MaxRecentFiles - 1);
                }
                recentFiles.Insert(0, new RecentFile { ItemId = itemId, FileName = fileName });
            }
            else
            {
                var index = recentFiles.IndexOf(file);
                recentFiles.RemoveAt(index);
                recentFiles.Insert(0, file);
                file.FileName = fileName;
            }
        }

        private void btnFirst_Click(object sender, RoutedEventArgs e)
        {
            ViewModels.Pagination.Page = 1;
        }

        private void btnLast_Click(object sender, RoutedEventArgs e)
        {
            ViewModels.Pagination.Page = ViewModels.Pagination.TotalPage;
        }

        private void btnPrevious_Click(object sender, RoutedEventArgs e)
        {
            ViewModels.Pagination.Page--;
        }

        private void btnNext_Click(object sender, RoutedEventArgs e)
        {
            ViewModels.Pagination.Page++;
        }

        public class RecentFile
        {
            public string ItemId { get; set; }
            public string FileName { get; set; }
        }
    }
}
