using System.Text;
using System.Text.Json;
using BackOffice.Common.BaseComponents;
using BackOffice.Common.Utilities;
using CMSMicroservice.Protobuf.Protos;
using CMSMicroservice.Protobuf.Protos.UserOrder;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MudBlazor;
using DateTimeConverterCL;
using DataModel = CMSMicroservice.Protobuf.Protos.UserOrder.GetAllUserOrderByFilterResponseModel;
using Google.Protobuf.WellKnownTypes;

namespace BackOffice.Pages.UserOrder;

public partial class UserOrderMainPage
{
    [Parameter] public long? UserId { get; set; }
    [Inject] public UserOrderContract.UserOrderContractClient UserOrderContract { get; set; }
    [Inject] public IJSRuntime JsRuntime { get; set; }
    private bool _isLoading = true;
    private MudDataGrid<DataModel> _gridData;
    BasePageComponent _basePage;

    private long? _orderIdFilter;
    private long? _userIdFilter;
    private long? _transactionIdFilter;
    private int? _paymentStatusFilter;
    private int? _deliveryStatusFilter;
    private int? _paymentMethodFilter;
    private DateTime? _paymentDateFrom;
    private DateTime? _paymentDateTo;

    private GetAllUserOrderByFilterRequest _request = new() { Filter = new() };


    private async Task<GridData<DataModel>> ServerReload(GridState<DataModel> state)
    {
      try
      {
        _request.Filter ??= new();
        _request.PaginationState ??= new();
        _request.PaginationState.PageNumber = state.Page + 1;
        _request.PaginationState.PageSize = state.PageSize;

        if (_orderIdFilter.HasValue && _orderIdFilter.Value > 0)
        {
            _request.Filter.Id = _orderIdFilter.Value;
        }
        else
        {
            _request.Filter.Id = null;
        }

        if (UserId.HasValue && UserId.Value > 0)
        {
            _request.Filter.UserId = UserId.Value;
        }
        else
        {
            _request.Filter.UserId = _userIdFilter.HasValue && _userIdFilter.Value > 0
                ? _userIdFilter.Value
                : null;
        }

        if (_paymentDateFrom.HasValue)
        {
            _request.Filter.FromDate =
                Timestamp.FromDateTime(DateTime.SpecifyKind(_paymentDateFrom.Value.Date, DateTimeKind.Utc));
        }
        else
        {
            _request.Filter.FromDate = null;
        }

        if (_paymentDateTo.HasValue)
        {
            _request.Filter.ToDate =
                Timestamp.FromDateTime(DateTime.SpecifyKind(_paymentDateTo.Value.Date.AddDays(1).AddTicks(-1), DateTimeKind.Utc));
        }
        else
        {
            _request.Filter.ToDate = null;
        }

        if (_paymentStatusFilter.HasValue)
        {
            _request.Filter.PaymentStatus = (PaymentStatus)_paymentStatusFilter.Value;
        }
        else
        {
            _request.Filter.ClearPaymentStatusItem();
        }

        if (_deliveryStatusFilter.HasValue)
        {
            _request.Filter.DeliveryStatus = (DeliveryStatus)_deliveryStatusFilter.Value;
        }
        else
        {
            _request.Filter.ClearDeliveryStatusItem();
        }

        if (_paymentMethodFilter.HasValue)
        {
            _request.Filter.PaymentMethod = (PaymentMethod)_paymentMethodFilter.Value;
        }
        else
        {
            _request.Filter.ClearPaymentMethodItem();
        }

        if (_transactionIdFilter.HasValue && _transactionIdFilter.Value > 0)
        {
            _request.Filter.TransactionId = _transactionIdFilter.Value;
        }
        else
        {
            _request.Filter.TransactionId = null;
        }

        var result = await UserOrderContract.GetAllUserOrderByFilterAsync(_request);
        if (result != null && result.Models != null && result.Models.Any())
        {
            return new GridData<DataModel>
            {
                Items = result.Models.ToList(),
                TotalItems = (int)result.MetaData.TotalCount
            };
        }

        return new GridData<DataModel>();
      }
      catch (Exception ex)
      {
        Snackbar.Add($"خطا در بارگذاری سفارشات: {ex.Message}", MudBlazor.Severity.Error);
        return new GridData<DataModel>();
      }
    }

    private async Task OpenDetails(DataModel model)
    {
        var parameters = new DialogParameters
        {
            { nameof(BackOffice.Pages.UserOrder.Components.UserOrderDetailsDialog.OrderId), model.Id }
        };

        var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Large, FullWidth = true };
        var dialog =
            await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.UserOrderDetailsDialog>("جزئیات سفارش",
                parameters, options);
        var result = await dialog.Result;

        if (!result.Canceled)
        {
            ReLoadData();
        }
    }

    private async Task OnDelete(DataModel model)
    {
        var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small };
        bool? result = await DialogService.ShowMessageBox(
            "اخطار",
            $"آیا از حذف سفارش شماره «{model.Id}» مطمئن هستید؟",
            yesText: "حذف", cancelText: "لغو",
            options: options);
        if (result != null && result.Value)
        {
            await UserOrderContract.DeleteUserOrderAsync(new()
            {
                Id = model.Id
            });
            ReLoadData();
        }

        StateHasChanged();
    }

    public async void ReLoadData()
    {
        if (_gridData != null)
            await _gridData.ReloadServerData();
    }

    public async Task OnFilterSubmit()
    {
        _basePage.IsFiltered = true;
        StateHasChanged();
        ReLoadData();
    }

    public async Task OnFilterCleared()
    {
        _basePage.IsFiltered = false;
        StateHasChanged();
        _request = new() { Filter = new() { } };
        _orderIdFilter = null;
        _userIdFilter = null;
        _transactionIdFilter = null;
        _paymentStatusFilter = null;
        _deliveryStatusFilter = null;
        _paymentDateFrom = null;
        _paymentDateTo = null;
        _paymentMethodFilter = null;
        ReLoadData();
    }

    private Color GetDeliveryStatusColor(int status)
    {
        return status switch
        {
            1 => Color.Warning, // Pending
            2 => Color.Info, // InTransit
            3 => Color.Success, // Delivered
            4 => Color.Error, // Returned
            5 => Color.Dark, // Cancelled
            6 => Color.Primary, // ReadyForOfficePickup
            _ => Color.Default // None / Unknown
        };
    }

    private string GetDeliveryStatusText(int status)
    {
        return status switch
        {
            1 => "در انتظار ارسال",
            2 => "تحویل پست",
            3 => "تحویل به مشتری",
            4 => "مرجوع شده",
            5 => "لغو شده",
            6 => "آماده تحویل در دفتر",
            _ => "بدون ارسال / نامشخص"
        };
    }

    private string GetPaymentMethodText(int method)
    {
        return method switch
        {
            1 => "کیف پول",
            _ => "درگاه پرداخت"
        };
    }

    // Domain PaymentStatus: Success=0, Reject=1, Pending=2
    private static string GetPaymentStatusText(int status) => status switch
    {
        0 => "پرداخت شده",
        1 => "پرداخت ناموفق",
        2 => "در انتظار پرداخت",
        _ => "نامشخص"
    };

    private async Task OpenChangeStatus(DataModel model)
    {
        var parameters = new DialogParameters
        {
            { nameof(BackOffice.Pages.UserOrder.Components.ChangeOrderStatusDialog.OrderId), model.Id },
            { nameof(BackOffice.Pages.UserOrder.Components.ChangeOrderStatusDialog.CurrentStatus), model.DeliveryStatus.GetHashCode() }
        };

        var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
        var dialog = await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.ChangeOrderStatusDialog>(
            "تغییر وضعیت ارسال سفارش", parameters, options);
        var result = await dialog.Result;

        if (!result.Canceled)
        {
            ReLoadData();
        }
    }

    private async Task OpenApplyDiscount(DataModel model)
    {
        var parameters = new DialogParameters
        {
            { nameof(BackOffice.Pages.UserOrder.Components.ApplyDiscountDialog.OrderId), model.Id }
        };

        var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
        var dialog = await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.ApplyDiscountDialog>(
            "اعمال تخفیف روی سفارش", parameters, options);
        var result = await dialog.Result;

        if (!result.Canceled)
        {
            ReLoadData();
        }
    }

    private async Task OpenCancelOrder(DataModel model)
    {
        var parameters = new DialogParameters
        {
            { nameof(BackOffice.Pages.UserOrder.Components.CancelOrderDialog.OrderId), model.Id }
        };

        var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
        var dialog = await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.CancelOrderDialog>(
            "لغو سفارش", parameters, options);
        var result = await dialog.Result;

        if (!result.Canceled)
        {
            ReLoadData();
        }
    }

    private async Task ExportToExcel()
    {
        try
        {
            var exportRequest = new GetAllUserOrderByFilterRequest
            {
                Filter = _request.Filter ?? new(),
                PaginationState = new PaginationState
                {
                    PageNumber = 1,
                    PageSize = 1000
                }
            };

            var result = await UserOrderContract.GetAllUserOrderByFilterAsync(exportRequest);

            if (result?.Models == null || !result.Models.Any())
            {
                Snackbar.Add("داده‌ای برای خروجی وجود ندارد.", Severity.Info);
                return;
            }

            var headers = new[]
            {
                "شناسه", "کاربر", "نام مشتری", "مبلغ", "وضعیت پرداخت", "وضعیت ارسال", "روش پرداخت", "تاریخ پرداخت"
            };

            var rows = result.Models.Select(o => new object?[]
            {
                o.Id,
                o.UserId,
                CsvExportHelper.CustomerName(o.UserFullName, userId: o.UserId),
                o.Amount,
                GetPaymentStatusText(o.PaymentStatus.GetHashCode()),
                GetDeliveryStatusText(o.DeliveryStatus.GetHashCode()),
                GetPaymentMethodText(o.PaymentMethod.GetHashCode()),
                o.PaymentDate?.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() ?? "-"
            });

            var filename = $"user-orders-{DateTime.Now:yyyyMMddHHmmss}.xls";
            await JsRuntime.InvokeVoidAsync("jsSaveAsFile", filename,
                CsvExportHelper.ToExcelXmlBase64("سفارش‌ها", headers, rows));
            Snackbar.Add("خروجی Excel آماده شد.", Severity.Success);
        }
        catch (Exception ex)
        {
            Snackbar.Add($"خطا در خروجی Excel: {ex.Message}", Severity.Error);
        }
    }
}
