using Mapster;
using NetinaShop.Domain.Dtos.ResponseDtos;
using NetinaShop.Domain.Entities.Blogs;
using NetinaShop.Domain.Entities.Discounts;
using NetinaShop.Domain.Mappers;

namespace NetinaShop.AdminPanel.PWA.Dialogs;

public class DiscountActionDialogBoxViewModel : BaseViewModel<DiscountLDto>
{

    private readonly ISnackbar _snackbar;
    private readonly IRestWrapper _restWrapper;
    private readonly IUserUtility _userUtility;
    private readonly IDialogService _dialogService;
    private readonly MudDialogInstance _mudDialog;

    public DiscountActionDialogBoxViewModel(
        ISnackbar snackbar,
        IRestWrapper restWrapper,
        IUserUtility userUtility,
        IDialogService dialogService,
        MudDialogInstance mudDialog)
    {
        _snackbar = snackbar;
        _restWrapper = restWrapper;
        _userUtility = userUtility;
        _dialogService = dialogService;
        _mudDialog = mudDialog;
    }
    public DiscountActionDialogBoxViewModel(ISnackbar snackbar,
        IRestWrapper restWrapper,
        IUserUtility userUtility,
        IDialogService dialogService,
        MudDialogInstance mudDialog,
        DiscountSDto discount)
    {
        _snackbar = snackbar;
        _restWrapper = restWrapper;
        _userUtility = userUtility;
        _dialogService = dialogService;
        _mudDialog = mudDialog;
        _discountId = discount.Id;
        IsEditing = true;
    }

    private bool _isProductEnable;

    public bool IsProductEnable
    {
        get => _isProductEnable;
        set
        {
            _isProductEnable = value;
            if (_isProductEnable)
            {
                IsCategoryEnable = false;
                IsAllEnable = false;
            }
        }
    }
    private bool _isCategoryEnable;
    public bool IsCategoryEnable
    {
        get => _isCategoryEnable;
        set
        {
            _isCategoryEnable = value;
            if (_isCategoryEnable)
            {
                IsProductEnable = false;
                IsAllEnable = false;
            }
        }
    }
    private bool _isAllEnable;
    public bool IsAllEnable
    {
        get => _isAllEnable;
        set
        {
            _isAllEnable = value;
            if (_isAllEnable)
            {
                IsCategoryEnable = false;
                IsProductEnable = false;
            }
        }
    }

    public bool IsPercentType { get; set; } = true;
    public bool IsAmountType { get; set; }

    public DateTime? ExpireDate { get; set; }
    public DateTime? StartDate { get; set; }
    private Guid _discountId;
    public bool IsEditing = false;

    public void AmountTypeChanged(DiscountAmountType type)
    {
        switch (type)
        {
            case DiscountAmountType.Amount:
                IsAmountType = true;
                IsPercentType = false;
                break;
            case DiscountAmountType.Percent:
                IsAmountType = false;
                IsPercentType = true;
                break;
        }
    }

    public override async Task InitializeAsync()
    {
        if (IsEditing && _discountId != default)
        {
            try
            {
                var token = await _userUtility.GetBearerTokenAsync();
                if (token == null)
                    throw new Exception("Token is null");
                IsProcessing = true;
                var discount = await _restWrapper.DiscountRest.ReadOne(_discountId, token);
                PageDto = discount;

                if (PageDto.CategoryId != default)
                    SelectedCategory = new ProductCategorySDto { Id = PageDto.CategoryId, Name = PageDto.CategoryName };

                if (PageDto.ProductId != default)
                    SelectedProduct = new ProductSDto { Id = PageDto.ProductId, PersianName = PageDto.ProductName };

                ExpireDate = PageDto.ExpireDate;
                StartDate = PageDto.StartDate;
            }
            catch (ApiException ex)
            {
                var exe = await ex.GetContentAsAsync<ApiResult>();
                if (exe != null)
                    _snackbar.Add(exe.Message, Severity.Error);
                _snackbar.Add(ex.Content, Severity.Error);
                _mudDialog.Cancel();
            }
            catch (Exception e)
            {
                _snackbar.Add(e.Message, Severity.Error);
                _mudDialog.Cancel();
            }
            finally
            {

                IsProcessing = false;
            }
        }
        else
        {
            StartDate = DateTime.Today;
            ExpireDate = DateTime.Today.AddDays(7);
            PageDto.IsInfinity = false;
            PageDto.HasCode = false;
            IsAllEnable = true;
        }
        await base.InitializeAsync();
    }




    public void Cancel() => _mudDialog.Cancel();

    public async Task SubmitCreateAsync()
    {
        try
        {
            IsProcessing = true;
            if (IsAllEnable)
            {
                PageDto.Type = DiscountType.All;
            }
            else if (IsCategoryEnable)
            {
                PageDto.Type = DiscountType.Category;
                if (SelectedCategory == null)
                    throw new Exception("دسته بندی را برای تخفیف انتخاب نمایید");
                PageDto.CategoryId = SelectedCategory.Id;
            }
            else if (IsProductEnable)
            {
                PageDto.Type = DiscountType.Product;
                if (SelectedProduct == null)
                    throw new Exception("کالا مورد نظر را برای تخفیف انتخاب نمایید");
                PageDto.ProductId = SelectedProduct.Id;
            }

            var token = await _userUtility.GetBearerTokenAsync();
            if (token == null)
                throw new Exception("Token is null");
            if (ExpireDate != null)
                PageDto.ExpireDate = ExpireDate.Value;
            if(StartDate != null)
                PageDto.StartDate = StartDate.Value;

            var request = PageDto.Adapt<CreateDiscountCommand>();
            await _restWrapper.CrudApiRest<Discount, Guid>(Address.DiscountController).Create<CreateDiscountCommand>(request, token);

            _snackbar.Add($"ساخت تخفیف با موفقیت انجام شد", Severity.Success);
            _mudDialog.Close();
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            if (exe != null)
                _snackbar.Add(exe.Message, Severity.Error);
            _snackbar.Add(ex.Content, Severity.Error);
            _mudDialog.Cancel();
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
            _mudDialog.Cancel();
        }
        finally
        {

            IsProcessing = false;
        }
    }
    public async Task SubmitEditAsync()
    {
        try
        {
            IsProcessing = true;
            if (_discountId == default)
                throw new Exception("Id is null");

            if (IsAllEnable)
            {
                PageDto.Type = DiscountType.All;
            }
            else if (IsCategoryEnable)
            {
                PageDto.Type = DiscountType.Category;
                if (SelectedCategory == null)
                    throw new Exception("دسته بندی را برای تخفیف انتخاب نمایید");
                PageDto.CategoryId = SelectedCategory.Id;
            }
            else if (IsProductEnable)
            {
                PageDto.Type = DiscountType.Product;
                if (SelectedProduct == null)
                    throw new Exception("کالا مورد نظر را برای تخفیف انتخاب نمایید");
                PageDto.ProductId = SelectedProduct.Id;
            }

            var token = await _userUtility.GetBearerTokenAsync();
            if (token == null)
                throw new Exception("Token is null");
            PageDto.Id = _discountId;
            var request = PageDto.Adapt<UpdateDiscountCommand>();
            await _restWrapper.CrudApiRest<Discount, Guid>(Address.DiscountController).Update<UpdateDiscountCommand>(request, token);
            _snackbar.Add($"ویرایش تخفیف با موفقیت انجام شد", Severity.Success);
            _mudDialog.Close();
        }
        catch (ApiException ex)
        {
            var exe = await ex.GetContentAsAsync<ApiResult>();
            if (exe != null)
                _snackbar.Add(exe.Message, Severity.Error);
            _snackbar.Add(ex.Content, Severity.Error);
            _mudDialog.Cancel();
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
            _mudDialog.Cancel();
        }
        finally
        {

            IsProcessing = false;
        }
    }


    private List<ProductCategorySDto> _productCategories = new List<ProductCategorySDto>();
    public ProductCategorySDto? SelectedCategory;
    public async Task<IEnumerable<ProductCategorySDto>> SearchCategory(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;
        }
    }



    private List<ProductSDto> _products = new List<ProductSDto>();
    public ProductSDto? SelectedProduct;
    public async Task<IEnumerable<ProductSDto>> SearchProduct(string product)
    {
        try
        {
            GetProductsResponseDto response = new GetProductsResponseDto();
            if (product.IsNullOrEmpty())
                response = await _restWrapper.ProductRestApi.ReadAll(0,null,null);
            else
                response = await _restWrapper.ProductRestApi.ReadAll(product);
            _products = response.Products;
            return _products;
        }
        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 _products;
        }
        catch (Exception e)
        {
            _snackbar.Add(e.Message, Severity.Error);
            return _products;
        }
    }
}