

using Http.Core;
using Newtonsoft.Json;
using PCUT.Entities;
using PCUT.Entities.ApiResponse;
using PCUT.Extensions;
using PCUT.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Popups;
using Windows.UI.Xaml.Controls;
using Http.Core.Extensions;
using static Http.Core.Constants.HttpConstants;
using Windows.Graphics.Imaging;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Media;
using Http.Core.Exceptions;

namespace PCUT.ViewModels
{
    public class FileEditViewModel : NotificationBase
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { SetProperty(ref _name, value); }
        }

        private string _area;
        public string Area
        {
            get { return _area; }
            set { SetProperty(ref _area, value); }
        }

        private string _remarks;
        public string Remarks
        {
            get { return _remarks; }
            set { SetProperty(ref _remarks, value); }
        }

        private ImageSource _previewSource;
        public ImageSource PreviewSource
        {
            get { return _previewSource; }
            set { SetProperty(ref _previewSource, value); }
        }

        public SelectableCollection<Category> Categories { get; }
        public MetadataViewModel MetadataModel { get; }

        private string _fileId;
        private string _thumbnailId;

        public FileEditViewModel()
        {
            Categories = new SelectableCollection<Category>();
            MetadataModel = new MetadataViewModel();
            PreviewSource = new BitmapImage();

            //MetadataModel.SetFilterChangedHandle();
        }

        public async Task GetCategoriesAsync()
        {
            using (var client = HttpClientFactory.CreateClient(ClientNames.ApiClient))
            {
                var categories = await client.GetCategoriesAsync(filterByRole: true);
                Categories.Load(categories);
            }
        }

        public async Task LoadFileData(string id)
        {
            if (string.IsNullOrEmpty(id)) return;

            using (var httpClient = HttpClientFactory.CreateClient(ClientNames.ApiClient))
            {
                try
                {
                    var response = await httpClient.GetAsync(Api.CdrFileById.FormatRoute(id));
                    if (response.IsSuccessStatusCode)
                    {
                        var json = await response.Content.ReadAsStringAsync();
                        var fileData = JsonConvert.DeserializeObject<PaginationResponse<CdrFile>>(json);
                        if (fileData?.Data != null)
                        {
                            var fileApi = fileData.Data;
                            Name = fileApi.Name;
                            Area = fileApi.Area;
                            Remarks = fileApi.Remarks;
                            Categories.SelectBy(x => x.Id == fileApi.Category?.Id);
                            MetadataModel.Types.SelectBy(x => x.Id == fileApi.Type?.Id);
                            MetadataModel.Brands.SelectBy(x => x.Id == fileApi.Brand?.Id);
                            MetadataModel.Series.SelectBy(x => x.Id == fileApi.Series?.Id);
                            MetadataModel.Models.SelectBy(x => x.Id == fileApi.Model?.Id);
                            MetadataModel.SubTypes.SelectBy(x => x.Id == fileApi.SubType?.Id);
                            MetadataModel.Years.SelectBy(x => x.Id == fileApi.Year?.Id);

                            _thumbnailId = fileApi.Thumbnail?.Id;
                            _fileId = fileApi.File?.Id;
                            await LoadThumbnail(_thumbnailId);
                        }
                    }
                }
                catch (Exception ex) when (!(ex is AppOutdatedException))
                {
                }
            }
        }

        public async Task LoadThumbnail(string thumbnailId)
        {
            using (var httpClient = HttpClientFactory.CreateClient(ClientNames.ApiClient))
            {
                using (var stream = new MemoryStream())
                {
                    var response = await httpClient.DownloadAsync(Api.Download.FormatRoute(thumbnailId), stream);
                    if (response)
                    {
                        stream.Seek(0, SeekOrigin.Begin);
                        await PreviewSource.LoadStreamAsync(stream.AsRandomAccessStream());
                    }
                }
            }
        }

        public async Task<bool> UpdateFileAsync(string id, StorageFile file, Image image)
        {
            string fileId = _fileId;
            string thumbnailId = _thumbnailId;
            if (file != null)
            {
                using (var stream = await file.OpenReadAsync())
                {
                    fileId = await UpLoadFileAsync(file.Name, stream.AsStreamForRead());
                }
                if (string.IsNullOrEmpty(fileId))
                {
                    var uploadAgainDialog = new MessageDialog("Please select a file to upload!");
                    await uploadAgainDialog.ShowAsync();
                    return false;
                }

                using (var stream = await image.CreateThumbnailAsync())
                {
                    thumbnailId = await UpLoadFileAsync(Path.GetFileNameWithoutExtension(file.Name) + ".png", stream.AsStreamForRead());
                }
                if (string.IsNullOrEmpty(thumbnailId))
                {
                    var uploadAgainDialog = new MessageDialog("Please upload a Image first!");
                    await uploadAgainDialog.ShowAsync();
                    return false;
                }
            }
            if (string.IsNullOrEmpty(Name))
            {
                await new MessageDialog("Name cannot be null").ShowAsync();
                return false;
            }
            try
            {
                var fileInfo = new UpsertFile
                {
                    FileId = fileId,
                    Name = this.Name,
                    Thumbnail = thumbnailId,
                    Category = Categories.SelectedItem?.Id,
                    Type = MetadataModel.Types.SelectedItem?.Id,
                    Brand = MetadataModel.Brands.SelectedItem?.Id,
                    Series = MetadataModel.Series.SelectedItem?.Id,
                    Model = MetadataModel.Models.SelectedItem?.Id,
                    SubType = MetadataModel.SubTypes.SelectedItem?.Id,
                    Year = MetadataModel.Years.SelectedItem?.Id,
                    Area = this.Area,
                    Remarks = this.Remarks
                };
                using (HttpClient client = HttpClientFactory.CreateClient(ClientNames.ApiClient))
                {
                    var response = await client.PutAsJsonAsync(Api.CdrFileById.FormatRoute(id), fileInfo);
                    if (!response.IsSuccessStatusCode)
                    {
                        var failDialog = new MessageDialog("Error editing the file while editing!");
                        await failDialog.ShowAsync();
                        return false;
                    }
                }
            }
            catch (Exception ex) when (!(ex is AppOutdatedException))
            {
                var errorDialog = new MessageDialog($"Error: {ex.Message}");
                await errorDialog.ShowAsync();
                return false;
            }
            var successDialog = new MessageDialog("File edited successfully!");
            await successDialog.ShowAsync();
            return true;
        }

        private async Task<string> UpLoadFileAsync(string name, Stream stream)
        {
            try
            {
                using (HttpClient client = HttpClientFactory.CreateClient(ClientNames.ApiClient))
                {
                    var content = new MultipartFormDataContent();
                    var streamContent = new StreamContent(stream);
                    streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
                    {
                        Name = "file",
                        FileName = name
                    };
                    content.Add(streamContent);

                    var response = await client.PostAsync(Api.Upload, content);
                    if (response.IsSuccessStatusCode)
                    {
                        var uploadResponse = await response.DeserializeObjectAsync<DataResponse<FileData>>();
                        return uploadResponse.Data.Id;
                    }
                    else
                    {
                        var errorDialog = new MessageDialog("Error uploading file!");
                        await errorDialog.ShowAsync();
                    }
                }
            }
            catch (Exception ex) when (!(ex is AppOutdatedException))
            {
                var exceptionDialog = new MessageDialog($"Error: {ex.Message}");
                await exceptionDialog.ShowAsync();
            }
            return null;
        }
    }
}
