using Append.Blazor.Printing;
using Syncfusion.Pdf.Graphics;

namespace Netina.AdminPanel.PWA.Dialogs;

public class OrderActionDialogBoxViewModel : BaseViewModel<OrderLDto>
{

    private readonly ISnackbar _snackbar;
    private readonly IRestWrapper _restWrapper;
    private readonly IUserUtility _userUtility;
    private readonly IDialogService _dialogService;
    private readonly MudDialogInstance _mudDialog;
    private readonly IPrintingService _printingService;
    private readonly IJSRuntime _jsRuntime;
    private readonly IConfiguration _configuration;

    public OrderActionDialogBoxViewModel(ISnackbar snackbar,
        IRestWrapper restWrapper,
        IUserUtility userUtility,
        IDialogService dialogService,
        MudDialogInstance mudDialog,
        IPrintingService printingService, 
        IJSRuntime jsRuntime,
        IConfiguration configuration) : base(userUtility)
    {
        _snackbar = snackbar;
        _restWrapper = restWrapper;
        _userUtility = userUtility;
        _dialogService = dialogService;
        _mudDialog = mudDialog;
        _printingService = printingService;
        _jsRuntime = jsRuntime;
        _configuration = configuration;
    }
    public OrderActionDialogBoxViewModel(ISnackbar snackbar,
        IRestWrapper restWrapper,
        IUserUtility userUtility,
        IDialogService dialogService,
        MudDialogInstance mudDialog,
        OrderSDto order,
        IPrintingService printingService,
        IJSRuntime jsRuntime,
        IConfiguration configuration) : base(userUtility)
    {
        _snackbar = snackbar;
        _restWrapper = restWrapper;
        _userUtility = userUtility;
        _dialogService = dialogService;
        _mudDialog = mudDialog;
        PageDto.Id = order.Id;
        IsEditing = true;
        _printingService = printingService;
        _jsRuntime = jsRuntime;
        _configuration = configuration;
    }


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

    public string ConfirmOrderButtonText { get; set; } = string.Empty;

    public bool IsEditing = false;
    public bool CanConfirm = true;


    public override async Task InitializeAsync()
    {
        if (IsEditing && PageDto.Id != default)
        {
            try
            {

                var token = await _userUtility.GetBearerTokenAsync();
                if (token == null)
                    throw new Exception("Token is null");

                IsProcessing = true;

                var order = await _restWrapper.OrderRestApi.ReadOne(PageDto.Id, token);
                PageDto = order;
                switch (PageDto.OrderStatus)
                {
                    case OrderStatus.OrderBag:
                        ConfirmOrderButtonText = "ثبت پرداختی سفارش";
                        break;
                    case OrderStatus.Submitted:
                        ConfirmOrderButtonText = "ثبت پرداختی سفارش";
                        break;
                    case OrderStatus.Paid:
                        ConfirmOrderButtonText = "ثبت سفارش";
                        break;
                    case OrderStatus.Processing:
                        ConfirmOrderButtonText = "ثبت ارسال سفارش";
                        break;
                    case OrderStatus.Delivered:
                        ConfirmOrderButtonText = "ثبت انجام سفارش";
                        break;
                    case OrderStatus.Done:
                        ConfirmOrderButtonText = "انجام شده";
                        CanConfirm = false;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            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 PrintInvoiceAsync()
    {
        try
        {
            var token = await _userUtility.GetBearerTokenAsync();
            if (token == null)
                throw new Exception("Token is null");
            IsProcessing = true;
            var apiUrl = _configuration.GetValue<string>("ApiUrl");
            string fileUrl = $"{apiUrl}{Address.OrderController}/{PageDto.Id}/invoice?access_token={token.Split("Bearer").Last().Trim()}";


            PdfStringFormat format = new PdfStringFormat(PdfTextAlignment.Left);
            format.TextDirection = PdfTextDirection.RightToLeft;
            await _jsRuntime.InvokeVoidAsync("openFile", new {fileName = "invoice.pdf",url=fileUrl});

        }
        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 SubmitConfirmAsync()
    {
        OrderStatus nextOrderStatus = OrderStatus.Canceled;
        switch (PageDto.OrderStatus)
        {
            case OrderStatus.OrderBag:
                return;
                break;
            case OrderStatus.Submitted:
                nextOrderStatus = OrderStatus.Paid;
                break;
            case OrderStatus.Paid:
                nextOrderStatus = OrderStatus.Processing;
                break;
            case OrderStatus.Processing:
                nextOrderStatus = OrderStatus.Delivered;
                break;
            case OrderStatus.Delivered:
                nextOrderStatus = OrderStatus.Done;
                break;
            case OrderStatus.Done:
                return;
                break;
            case OrderStatus.Canceled:
                return;
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }

        if (nextOrderStatus == OrderStatus.Delivered)
        {
            var options = new DialogOptions { MaxWidth = MaxWidth.Small, FullWidth = true, NoHeader = true, CloseOnEscapeKey = true };
            var trackingDialog = await _dialogService.ShowAsync<OrderTrackingCodeActionDialogBox>("ارسال کد رهگیری پستی", options);
            var trackingDialogResult = await trackingDialog.Result;
            if (!trackingDialogResult.Canceled && trackingDialogResult.Data is string trackingCode)
            {
                try
                {
                    var token = await _userUtility.GetBearerTokenAsync();
                    if (token == null)
                        throw new Exception("Token is null");
                    IsProcessing = true;


                    await _restWrapper.OrderRestApi.ConfirmOrderStepAsync(PageDto.Id, nextOrderStatus,trackingCode, token);
                    _snackbar.Add($"سفارش {PageDto.FactorCode} به {nextOrderStatus.ToDisplay()} تغییر یافت", Severity.Success);
                    _mudDialog.Close(true);
                }
                catch (ApiException ex)
                {
                    var exe = await ex.GetContentAsAsync<ApiResult>();
                    _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
                    _mudDialog.Cancel();
                }
                catch (Exception e)
                {
                    _snackbar.Add(e.Message, Severity.Error);
                    _mudDialog.Cancel();
                }
                finally
                {

                    IsProcessing = false;
                }
            }
            return;
        }
        var reference = await _dialogService.ShowQuestionDialog($"آیا از ثبت سفارش به {nextOrderStatus.ToDisplay()} اطمینان دارید ?");
        var result = await reference.Result;

        if (!result.Canceled)
        {

            try
            {
                var token = await _userUtility.GetBearerTokenAsync();
                if (token == null)
                    throw new Exception("Token is null");
                IsProcessing = true;
                

                await _restWrapper.OrderRestApi.ConfirmOrderStepAsync(PageDto.Id, nextOrderStatus, token);
                _snackbar.Add($"سفارش {PageDto.FactorCode} به {nextOrderStatus.ToDisplay()} تغییر یافت", Severity.Success);
                _mudDialog.Close(true);
            }
            catch (ApiException ex)
            {
                var exe = await ex.GetContentAsAsync<ApiResult>();
                _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
                _mudDialog.Cancel();
            }
            catch (Exception e)
            {
                _snackbar.Add(e.Message, Severity.Error);
                _mudDialog.Cancel();
            }
            finally
            {

                IsProcessing = false;
            }
        }

    }

    public async Task CancelAsync()
    {
        var reference = await _dialogService.ShowQuestionDialog($"ایا از کنسل کردن سفارش اطمینان دارید ?");
        var result = await reference.Result;
        if (!result.Canceled)
        {
            try
            {
                var token = await _userUtility.GetBearerTokenAsync();
                if (token == null)
                    throw new Exception("Token is null");
                IsProcessing = true;


                await _restWrapper.OrderRestApi.CancelOrderStepAsync(PageDto.Id, token);
                _snackbar.Add($"سفارش {PageDto.FactorCode} کنسل شد", Severity.Warning);
                _mudDialog.Close(true);
            }
            catch (ApiException ex)
            {
                var exe = await ex.GetContentAsAsync<ApiResult>();
                _snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
                _mudDialog.Cancel();
            }
            catch (Exception e)
            {
                _snackbar.Add(e.Message, Severity.Error);
                _mudDialog.Cancel();
            }
            finally
            {

                IsProcessing = false;
            }
        }
    }
}
