using CMSMicroservice.Protobuf.Protos.Package; using CMSMicroservice.Protobuf.Protos.Transactions; using CMSMicroservice.Protobuf.Protos.UserAddress; using CMSMicroservice.Protobuf.Protos.UserOrder; using FrontOffice.Main.Utilities; using Google.Protobuf.WellKnownTypes; using Microsoft.AspNetCore.Components; using MudBlazor; using Severity = MudBlazor.Severity; namespace FrontOffice.Main.Pages; public partial class Checkout { [Inject] private PackageContract.PackageContractClient PackageClient { get; set; } = default!; [Inject] private UserAddressContract.UserAddressContractClient UserAddressContract { get; set; } = default!; [Inject] private UserOrderContract.UserOrderContractClient UserOrderContract { get; set; } = default!; [Inject] private TransactionsContract.TransactionsContractClient TransactionContract { get; set; } = default!; [Parameter] public long? PackageId { get; set; } private Pack? _selectedPackage; private List _addresses = new(); private CustomerAddressModel? _selectedAddress; private bool _isLoadingAddresses; private bool _isProcessingPayment; // Discount code private string _discountCode = string.Empty; private bool _isApplyingDiscount; private string _discountMessage = string.Empty; private bool _discountApplied; private long _discountAmount; private long _finalPrice; // Address management private bool _isSettingDefaultAddress; private long? _settingDefaultAddressId; private bool CanProceedToPayment => _selectedPackage != null && _selectedAddress != null; protected override async Task OnInitializedAsync() { await LoadPackageDetails(); await LoadAddresses(); } private async Task LoadPackageDetails() { if (PackageId.HasValue) { try { var response = await PackageClient.GetPackageAsync(new() { Id = PackageId.Value }); if (response != null) { _selectedPackage = new Pack( Id: response.Id, Title: response.Title, Body: response.Description, Image: UrlUtility.DownloadUrl + response.ImagePath, Price: response.Price ); _finalPrice = _selectedPackage.Price; } } catch (Exception ex) { Snackbar.Add($"خطا در بارگذاری پکیج: {ex.Message}", Severity.Error); } } } private async Task LoadAddresses() { _isLoadingAddresses = true; try { var response = await UserAddressContract.GetCustomerAddressesAsync(request: new()); if (response?.Models?.Any() == true) { _addresses = response.Models.ToList(); // Select default address if available _selectedAddress = _addresses.FirstOrDefault(a => a.IsDefault) ?? _addresses.First(); } else { _addresses = new List(); } } catch (Exception ex) { Snackbar.Add($"خطا در بارگذاری آدرس‌ها: {ex.Message}", Severity.Error); _addresses = new List(); } finally { _isLoadingAddresses = false; await InvokeAsync(StateHasChanged); } } private async Task SetAddressAsDefault(long addressId) { if (_isSettingDefaultAddress) return; _isSettingDefaultAddress = true; _settingDefaultAddressId = addressId; try { await UserAddressContract.SetAddressAsDefaultAsync(new() { Id = addressId }); await LoadAddresses(); // Reload addresses to reflect the change Snackbar.Add("آدرس پیش‌فرض با موفقیت تغییر یافت.", Severity.Success); } catch (Exception ex) { Snackbar.Add($"خطا در تغییر آدرس پیش‌فرض: {ex.Message}", Severity.Error); } finally { _isSettingDefaultAddress = false; _settingDefaultAddressId = null; await InvokeAsync(StateHasChanged); } } private async Task ApplyDiscountCode() { if (string.IsNullOrWhiteSpace(_discountCode)) { _discountMessage = "لطفاً کد تخفیف را وارد کنید."; _discountApplied = false; return; } _isApplyingDiscount = true; _discountMessage = string.Empty; try { // TODO: Implement discount code validation with backend // For now, simulate a discount if (_discountCode.ToUpper() == "TEST10") { _discountAmount = (long)(_selectedPackage!.Price * 0.1); // 10% discount _finalPrice = _selectedPackage!.Price - _discountAmount; _discountMessage = "کد تخفیف با موفقیت اعمال شد."; _discountApplied = true; } else { _discountMessage = "کد تخفیف نامعتبر است."; _discountApplied = false; _discountAmount = 0; _finalPrice = _selectedPackage!.Price; } } catch (Exception ex) { _discountMessage = "خطا در اعمال کد تخفیف."; _discountApplied = false; _discountAmount = 0; _finalPrice = _selectedPackage!.Price; } finally { _isApplyingDiscount = false; await InvokeAsync(StateHasChanged); } } private async Task ProcessPayment() { Snackbar.Add("درگاه پرداخت متصل نیست! لطفا در زمان دیگری مجددا تلاش فرمایید!", Severity.Warning); return; if (!CanProceedToPayment || _selectedPackage == null || _selectedAddress == null) { Snackbar.Add("لطفاً پکیج و آدرس را انتخاب کنید.", Severity.Warning); return; } _isProcessingPayment = true; try { // Step 1: Create payment request var paymentRequest = new CustomerPaymentRequestRequest { Amount = _finalPrice, CallbackUrl = $"{Navigation.BaseUri}checkout/callback", Description = $"خرید پکیج {_selectedPackage.Title}", Currency = CurrencyEnum.Irt, Type = TransactionTypeEnum.Real }; var paymentResponse = await TransactionContract.CustomerPaymentRequestAsync(paymentRequest); if (string.IsNullOrEmpty(paymentResponse.PaymentGWUrl)) Snackbar.Add("آدرس درگاه پرداخت دریافت نشد.", Severity.Error); // Step 2: Create user order var orderRequest = new CreateNewUserOrderRequest { Amount = _finalPrice, PackageId = _selectedPackage.Id, PaymentStatus = CMSMicroservice.Protobuf.Protos.PaymentStatus.Pending }; var orderResponse = await UserOrderContract.CreateNewUserOrderAsync(orderRequest); // Step 3: Redirect to payment gateway Navigation.NavigateTo(paymentResponse.PaymentGWUrl); } catch (Exception ex) { Snackbar.Add($"خطا در پردازش پرداخت: {ex.Message}", Severity.Error); } finally { _isProcessingPayment = false; await InvokeAsync(StateHasChanged); } } private record Pack(long Id, string Title, string Body, string Image, long Price); }