using Http.Core;
using PCUT.Entities;
using System;
using System.Threading.Tasks;
using Http.Core.Extensions;
using static Http.Core.Constants.HttpConstants;
using Windows.UI.Popups;
using System.Text;
using PCUT.Entities.ApiResponse;
using PCUT.Models.Categories;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using Http.Core.Exceptions;

namespace PCUT.ViewModels
{
    public class UpsertMetadataViewModel : UpsertViewModel<string>
    {
        public UpsertMetadataViewModel() : base("Metadata")
        {
        }

        private string _categoryId;
        public string CategoryId
        {
            get { return _categoryId; }
            set { SetProperty(ref _categoryId, value); }
        }

        private string _type;
        public string Type
        {
            get { return _type; }
            set
            {
                SetProperty(ref _type, value);
                Entity = value;
            }
        }

        private string _name;
        public string Name
        {
            get { return _name; }
            set { SetProperty(ref _name, value); }
        }

        public async Task UpsertMetadataAsync()
        {
            using (var client = HttpClientFactory.CreateClient(ClientNames.ApiClient))
            {
                string message;
                if (Mode == AddMode)
                    message = await AddAsync(client);
                else
                    message = await EditAsync(client);

                await new MessageDialog(message).ShowAsync();
            }
        }

        private async Task<string> AddAsync(HttpClient client)
        {
            var request = new UpsertMetadata
            {
                Type = Type.ToUpper(),
                Value = Name,
                CategoryId = CategoryId
            };
            try
            {
                var response = await client.PostAsJsonAsync(Api.Metadata, request);
                return response.IsSuccessStatusCode ? "Metadata added successfully!" : "Failed to add the metadata!";
            }
            catch (Exception ex) when (!(ex is AppOutdatedException))
            {
                return $"error: {ex.Message}";
            }
        }

        private async Task<string> EditAsync(HttpClient client)
        {
            try
            {
                var request = new UpsertMetadata
                {
                    Value = Name
                };
                var response = await client.PutAsJsonAsync(Api.MetadataById.FormatRoute(Id), request);
                return response.IsSuccessStatusCode ? "Metadata edited successfully!" : "Failed to edit the metadata!";
            }
            catch (Exception ex) when (!(ex is AppOutdatedException))
            {
                return $"error: {ex.Message}";
            }
        }

        protected override async Task LoadAsync(string id)
        {
            using (var client = HttpClientFactory.CreateClient(ClientNames.ApiClient))
            {
                try
                {
                    var url = CreateFilterUrl(id);
                    var response = await client.GetAsync(url);
                    if (response.IsSuccessStatusCode)
                    {
                        var content = await response.DeserializeObjectAsync<DataResponse<IEnumerable<CategoryMetadataModel>>>();
                        if (content.Data != null && content.Data.Any())
                        {
                            var metadata = content.Data.First();
                            Name = metadata.Value;
                        }
                    }
                }
                catch (Exception ex) when (!(ex is AppOutdatedException)) { }
            }
        }

        private string CreateFilterUrl(string id)
        {
            var filter = new StringBuilder().AppendFilter("_id", id)
                                            .BuildFilter()
                                            .ToString();
            return PathBuilder.FromRouteTemplate(Api.Metadata)
                              .AddQuery("filter", filter)
                              .Build();
        }
    }
}
