using MudBlazor;
using NetinaShop.Domain.Dtos.ResponseDtos;

namespace NetinaShop.AdminPanel.PWA.Pages;

public class ProductsPageViewModel : BaseViewModel<ObservableCollection<ProductSDto>>
{
    private readonly NavigationManager _navigationManager;
    private readonly ISnackbar _snackbar;
    private readonly IUserUtility _userUtility;
    private readonly IDialogService _dialogService;
    private readonly IRestWrapper _restWrapper;

    public string Search = string.Empty;
    public int CurrentPage = 0;
    public int PageCount = 1;

    public ProductsPageViewModel(NavigationManager navigationManager, ISnackbar snackbar, IUserUtility userUtility, IRestWrapper restWrapper, IDialogService dialogService)
    {
        _navigationManager = navigationManager;
        _snackbar = snackbar;
        _userUtility = userUtility;
        _restWrapper = restWrapper;
        _dialogService = dialogService;
    }

    public override async Task InitializeAsync()
    {
        try
        {
            IsProcessing = true;
            PageDto.Clear();
            var dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage,null,null);
            dto.Products.ForEach(d => PageDto.Add(d));
            if (PageDto.Count == 20)
                PageCount = 2;
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
        finally
        {

            IsProcessing = false;
        }
        await base.InitializeAsync();
    }

    public async Task ChangePageAsync(int page)
    {
        CurrentPage = page - 1;
        if (CurrentPage > PageCount - 2)
        {

            try
            {
                IsProcessing = true;

                GetProductsResponseDto dto = new GetProductsResponseDto();
                if (Search.IsNullOrEmpty())
                {
                    dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage,null,null);
                }
                else
                {
                    dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search,null);
                }

                dto.Products.ForEach(d => PageDto.Add(d));
                if (PageDto.Count % 20 == 0)
                    PageCount = CurrentPage + 2;

            }
            catch (ApiException ex)
            {
                var exe = await ex.GetContentAsAsync<ApiResult>();
                _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
            }
            catch (Exception e)
            {
                _snackbar.Add(e.Message, Severity.Error);
            }
            finally
            {

                IsProcessing = false;
            }
        }
    }

    public async Task AddProductClicked()
    {
        DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, FullWidth = true, DisableBackdropClick = true };
        var dialogResult = await _dialogService.ShowAsync<ProductActionDialogBox>("افزودن محصول جدید", maxWidth);
        var result = await dialogResult.Result;
        if (!result.Canceled && result.Data is bool and true)
        {
            await InitializeAsync();
        }
    }

    public async Task AddDigikalaProductClicked()
    {

        DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, DisableBackdropClick = true };
        var dialogResult = await _dialogService.ShowAsync<DigikalaProductActionDialogBox>("افزودن محصول جدید", maxWidth);
        var result = await dialogResult.Result;
        if (!result.Canceled && result.Data is bool and true)
        {
            await InitializeAsync();
        }
    }

    public async Task EditProductClicked(ProductSDto product)
    {
        DialogOptions maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Large, FullWidth = true, DisableBackdropClick = true };
        var parameters = new DialogParameters<ProductActionDialogBox>();
        parameters.Add(x => x.Product, product);
        var dialogResult = await _dialogService.ShowAsync<ProductActionDialogBox>($"ویرایش محصول {product.PersianName}", parameters, maxWidth);
        var result = await dialogResult.Result;
        if (!result.Canceled && result.Data is bool and true)
        {
            await InitializeAsync();
        }
    }

    public async Task DeleteProductAsync(Guid selectedCategoryId)
    {
        var options = new DialogOptions { CloseOnEscapeKey = true };
        var parameters = new DialogParameters<QuestionDialog>();
        parameters.Add(x => x.ContentText, "آیا از حذف محصول اطمینان دارید ?");
        var dialogReference = await _dialogService.ShowAsync<QuestionDialog>("حذف شرح حال", parameters, options);
        var result = await dialogReference.Result;
        if (!result.Canceled)
        {

            try
            {

                IsProcessing = true;
                var token = await _userUtility.GetBearerTokenAsync();
                await _restWrapper.CrudDtoApiRest<Product, ProductSDto, Guid>(Address.ProductController)
                    .Delete(selectedCategoryId, token);
                _snackbar.Add("حذف محصول با موفقیت انجام شد", Severity.Success);
                await InitializeAsync();

            }
            catch (ApiException ex)
            {
                var exe = await ex.GetContentAsAsync<ApiResult>();
                _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
            }
            catch (Exception e)
            {
                _snackbar.Add(e.Message, Severity.Error);
            }
            finally
            {

                IsProcessing = false;
            }
        }
    }

    public async Task SearchChanged(string search)
    {
        if (search.IsNullOrEmpty() && !Search.IsNullOrEmpty())
            await InitializeAsync();
        Search = search;
    }
    public async Task SearchAsync()
    {
        try
        {
            if (Search.IsNullOrEmpty())
                throw new AppException("دسته بندی برای جست جو وارد نشده است");
            IsProcessing = true;
            CurrentPage = 0;
            PageCount = 1;
            PageDto.Clear();
            GetProductsResponseDto dto;
            if (SelectedCategory != null)
                dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search, SelectedCategory.Id);
            else
                dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search,null);

            dto.Products.ForEach(d => PageDto.Add(d));
            if (PageDto.Count == 20)
                PageCount = 2;
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
        finally
        {

            IsProcessing = false;
        }
    }


    private List<ProductCategorySDto> _productCategories = new List<ProductCategorySDto>();
    public ProductCategorySDto? SelectedCategory;
    public async Task<IEnumerable<ProductCategorySDto>> SearchProductCategory(string category)
    {
        try
        {
            if (category.IsNullOrEmpty())
                _productCategories = await _restWrapper.ProductCategoryRestApi.ReadAll(0);
            else
                _productCategories = await _restWrapper.ProductCategoryRestApi.ReadAll(category);
            return _productCategories;
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            if (exe != null)
                _snackbar.Add(exe.Message, Severity.Error);
            _snackbar.Add(ex.Content, Severity.Error);
            return _productCategories;
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
            return _productCategories;
        }
    }

    public async Task ProductCategorySelected(ProductCategorySDto productCategory)
    {
        SelectedCategory = productCategory;
        try
        {
            if (SelectedCategory == null)
            {
                return;
            }
            IsProcessing = true;
            CurrentPage = 0;
            PageCount = 1;
            PageDto.Clear();
            GetProductsResponseDto dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search, SelectedCategory.Id);

            dto.Products.ForEach(d => PageDto.Add(d));
            if (PageDto.Count == 20)
                PageCount = 2;
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
        finally
        {

            IsProcessing = false;
        }
    }

    public async Task ClearProductCategorySearch()
    {
        SelectedCategory = null;
        try
        {
            IsProcessing = true;
            CurrentPage = 0;
            PageCount = 1;
            PageDto.Clear();
            GetProductsResponseDto dto = await _restWrapper.ProductRestApi.ReadAll(CurrentPage, Search, null);

            dto.Products.ForEach(d => PageDto.Add(d));
            if (PageDto.Count == 20)
                PageCount = 2;
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
        finally
        {

            IsProcessing = false;
        }
    }

    public async Task DisplayedChanged(ProductSDto product)
    {
        try
        {
            var token = await _userUtility.GetBearerTokenAsync();
            if (token == null)
                throw new Exception("Token is null");
            await _restWrapper.ProductRestApi.ChangeDisplayedAsync(product.Id, product.BeDisplayed, token);
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
        }
    }
}