using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Blazored.Modal;
using Blazored.Modal.Services;
using Blazored.Toast.Services;
using DiplomovaPrace.Contracts;
using DiplomovaPrace.Contracts.Orders;
using DiplomovaPrace.Contracts.Orders.ViewModels;
using DiplomovaPrace.Web.Admin.Services;
using DiplomovaPrace.Web.Admin.Shared.Common;
using DiplomovaPrace.Web.Admin.Store.DeliveryTypeUseCase;
using DiplomovaPrace.Web.Admin.Store.OrderStateUseCase;
using DiplomovaPrace.Web.Admin.Store.PaymentStateUseCase;
using DiplomovaPrace.Web.Admin.Store.PaymentTypeUseCase;
using Fluxor;
using Havit.Collections;
using Microsoft.AspNetCore.Components;

namespace DiplomovaPrace.Web.Admin.Pages.Orders
{
	public partial class OrderList
	{
		private const int PageSize = 10;

		[CascadingParameter]
		public IModalService Modal { get; set; }

		[Inject]
		private IToastService ToastService { get; set; }

		[Inject]
		private IState<DeliveryTypeState> DeliveryTypeState { get; set; }

		[Inject]
		private IState<OrderState> OrderState { get; set; }

		[Inject]
		private IState<PaymentState> PaymentState { get; set; }

		[Inject]
		private IState<PaymentTypeState> PaymentTypeState { get; set; }

		[Inject]
		private IOrderService  OrderService { get; set; }

		[Inject]
		private IOrderFacadeContract OrderFacadeContract { get; set; }

		private List<OrderListItem> orderListItems = new();

		private OrderListQueryFilter filterModel = new();

		private SortDirection sortDirection = SortDirection.Descending;

		private string activeSortExpression = nameof(OrderListItem.OrderedDate);

		private int currentPageIndex;

		private int totalPages;

		protected override async Task OnInitializedAsync()
		{
			await base.OnInitializedAsync().ConfigureAwait(false);

			await LoadAllOrderPropertiesAsync().ConfigureAwait(false);
			await LoadOrdersAsync().ConfigureAwait(false);
		}

		private async Task LoadAllOrderPropertiesAsync()
		{
			if (DeliveryTypeState.Value.DeliveryTypes is null ||
				OrderState.Value.OrderStates is null ||
				PaymentState.Value.PaymentStates is null ||
				PaymentTypeState.Value.PaymentTypes is null)
			{
				await OrderService.RequestOrderPropertiesAsync().ConfigureAwait(false);
			}
		}

		private async Task LoadOrdersAsync()
		{
			SortItem[] sortItem = new SortItem[1] { new SortItem { Direction = sortDirection, Expression = activeSortExpression } };

			PagedQueryRequest<OrderListQueryFilter> pagedQuery = new()
			{
				Filter = filterModel,
				PageIndex = currentPageIndex,
				PageSize = PageSize,
				Sorting = sortItem
			};

			PagedQueryResult<OrderListItem> data = await OrderFacadeContract.GetOrderListAsync(pagedQuery).ConfigureAwait(false);
			orderListItems = data.Data;

			GetTotalPages(data.TotalCount);
		}

		private async Task ShowDeleteConfirmModalAsync(int orderId)
		{
			ModalOptions options = new()
			{
				DisableBackgroundCancel = true,
				Animation = ModalAnimation.FadeInOut(0.25),
				HideCloseButton = true
			};
			ModalParameters parameters = new();

			// Posílat Id je zbytečné
			parameters.Add(nameof(OrderListItem.ID), orderId);
			parameters.Add("ConfirmButtonText", "Smazat");
			parameters.Add("CancelButtonText", "Zrušit");
			//parameters.Add("BodyText", $"Opravdu chcete smazat objednávku s číslem: <strong>{orderId}</strong>?");
			parameters.Add("BodyText", $"Opravdu chcete smazat tuto objednávku?");

			ModalResult result = await Modal.Show<ConfirmModal>("Smazání objednávky", parameters, options).Result.ConfigureAwait(false);

			if (result.Cancelled)
			{
				return;
			}

			if (await OrderService.DeleteOrder(new ValueDto<int> { Value = orderId }))
			{
				var order = orderListItems.FirstOrDefault(i => i.ID == orderId);
				orderListItems.Remove(order);

				ToastService.ShowSuccess("Objednávka úspěšně smazána!", "POVEDLO SE");
			}
			else
			{
				ToastService.ShowError("Ajajaj! Něco se nepovedlo.", "CHYBA");
			}
		}

		private async Task HandleSortChangeAsync(string sortExpression)
		{
			if ((orderListItems.Count > 1) || (totalPages > 1))
			{
				if (activeSortExpression.Equals(sortExpression))
				{
					sortDirection = (sortDirection == SortDirection.Ascending) ? SortDirection.Descending : SortDirection.Ascending;
				}
				else
				{
					activeSortExpression = sortExpression;
					sortDirection = SortDirection.Ascending;
				}

				await LoadOrdersAsync().ConfigureAwait(false);
			}
		}
 
		private async Task HandleFilterChangeAsync(ChangeEventArgs e, string filterPropertyName)
		{
			int.TryParse(e.Value.ToString(), out int value);
			filterModel.GetType().GetProperty(filterPropertyName).SetValue(filterModel, value == 0 ? null : (int?)value);

			await LoadOrdersAsync().ConfigureAwait(false);
		}

		private async Task HandleSearchAsync(ChangeEventArgs e)
		{
			filterModel.SearchString = e.Value.ToString();

			await LoadOrdersAsync().ConfigureAwait(false);
		}

		private void GetTotalPages(int ordersCount)
		{
			totalPages = ordersCount / PageSize;

			if ((ordersCount % PageSize) > 0)
			{
				totalPages++;
			}

			if (totalPages <= currentPageIndex)
			{
				currentPageIndex = 0;
			}
		}

		private async Task HandlePageChangeAsync(int newPageIndex)
		{
			if (newPageIndex != currentPageIndex)
			{
				currentPageIndex = newPageIndex;

				await LoadOrdersAsync().ConfigureAwait(false);
			}
		}

		private async Task HandlePageShiftAsync(int shift)
		{
			if (shift == 1)
			{
				if ((currentPageIndex + 1) < totalPages)
				{
					currentPageIndex++;
					await LoadOrdersAsync().ConfigureAwait(false);
				}
			}
			else
			{
				if ((currentPageIndex - 1) >= 0)
				{
					currentPageIndex--;
					await LoadOrdersAsync().ConfigureAwait(false);
				}
			}
		}
	}
}