// src/Webshop.Application/Services/Admin/AdminPaymentMethodService.cs using System; using System.Collections.Generic; using System.Linq; using System.Text.Json; using System.Threading.Tasks; using Webshop.Application; using Webshop.Application.DTOs.Payments; using Webshop.Domain.Entities; using Webshop.Domain.Enums; using Webshop.Domain.Interfaces; namespace Webshop.Application.Services.Admin { public class AdminPaymentMethodService : IAdminPaymentMethodService { private readonly IPaymentMethodRepository _paymentMethodRepository; public AdminPaymentMethodService(IPaymentMethodRepository paymentMethodRepository) { _paymentMethodRepository = paymentMethodRepository; } public async Task>> GetAllAsync() { var paymentMethods = await _paymentMethodRepository.GetAllAsync(); var dtos = paymentMethods.Select(pm => new AdminPaymentMethodDto { Id = pm.Id, Name = pm.Name, Description = pm.Description, IsActive = pm.IsActive, PaymentGatewayType = pm.PaymentGatewayType, Configuration = pm.Configuration != null ? JsonSerializer.Deserialize(pm.Configuration) : null, ProcessingFee = pm.ProcessingFee }).ToList(); return ServiceResult.Ok>(dtos); } public async Task> GetByIdAsync(Guid id) { var paymentMethod = await _paymentMethodRepository.GetByIdAsync(id); if (paymentMethod == null) { return ServiceResult.Fail(ServiceResultType.NotFound, $"Zahlungsmethode mit ID '{id}' nicht gefunden."); } var dto = new AdminPaymentMethodDto { Id = paymentMethod.Id, Name = paymentMethod.Name, Description = paymentMethod.Description, IsActive = paymentMethod.IsActive, PaymentGatewayType = paymentMethod.PaymentGatewayType, Configuration = paymentMethod.Configuration != null ? JsonSerializer.Deserialize(paymentMethod.Configuration) : null, ProcessingFee = paymentMethod.ProcessingFee }; return ServiceResult.Ok(dto); } public async Task> CreateAsync(AdminPaymentMethodDto paymentMethodDto) { var (isValid, configJson, errorMessage) = ValidateAndSerializeConfiguration(paymentMethodDto.PaymentGatewayType, paymentMethodDto.Configuration); if (!isValid) { return ServiceResult.Fail(ServiceResultType.InvalidInput, errorMessage!); } var newPaymentMethod = new PaymentMethod { Id = Guid.NewGuid(), Name = paymentMethodDto.Name, Description = paymentMethodDto.Description, IsActive = paymentMethodDto.IsActive, PaymentGatewayType = paymentMethodDto.PaymentGatewayType, Configuration = configJson, ProcessingFee = paymentMethodDto.ProcessingFee }; await _paymentMethodRepository.AddAsync(newPaymentMethod); paymentMethodDto.Id = newPaymentMethod.Id; return ServiceResult.Ok(paymentMethodDto); } public async Task UpdateAsync(AdminPaymentMethodDto paymentMethodDto) { var existingPaymentMethod = await _paymentMethodRepository.GetByIdAsync(paymentMethodDto.Id); if (existingPaymentMethod == null) { return ServiceResult.Fail(ServiceResultType.NotFound, $"Zahlungsmethode mit ID '{paymentMethodDto.Id}' nicht gefunden."); } var (isValid, configJson, errorMessage) = ValidateAndSerializeConfiguration(paymentMethodDto.PaymentGatewayType, paymentMethodDto.Configuration); if (!isValid) { return ServiceResult.Fail(ServiceResultType.InvalidInput, errorMessage!); } existingPaymentMethod.Name = paymentMethodDto.Name; existingPaymentMethod.Description = paymentMethodDto.Description; existingPaymentMethod.IsActive = paymentMethodDto.IsActive; existingPaymentMethod.PaymentGatewayType = paymentMethodDto.PaymentGatewayType; existingPaymentMethod.Configuration = configJson; existingPaymentMethod.ProcessingFee = paymentMethodDto.ProcessingFee; await _paymentMethodRepository.UpdateAsync(existingPaymentMethod); return ServiceResult.Ok(); } public async Task DeleteAsync(Guid id) { var paymentMethod = await _paymentMethodRepository.GetByIdAsync(id); if (paymentMethod == null) { return ServiceResult.Fail(ServiceResultType.NotFound, $"Zahlungsmethode mit ID '{id}' nicht gefunden."); } await _paymentMethodRepository.DeleteAsync(id); return ServiceResult.Ok(); } private (bool IsValid, string? ConfigJson, string? ErrorMessage) ValidateAndSerializeConfiguration(PaymentGatewayType type, object? configObject) { if (configObject == null) return (true, null, null); var configElement = (JsonElement)configObject; try { switch (type) { case PaymentGatewayType.BankTransfer: var bankConfig = configElement.Deserialize(); if (bankConfig == null || string.IsNullOrEmpty(bankConfig.IBAN) || string.IsNullOrEmpty(bankConfig.BIC)) { return (false, null, "Für Banküberweisung müssen IBAN und BIC angegeben werden."); } return (true, JsonSerializer.Serialize(bankConfig), null); case PaymentGatewayType.Stripe: var stripeConfig = configElement.Deserialize(); if (stripeConfig == null || string.IsNullOrEmpty(stripeConfig.PublicKey) || string.IsNullOrEmpty(stripeConfig.SecretKey)) { return (false, null, "Für Stripe müssen PublicKey und SecretKey angegeben werden."); } return (true, JsonSerializer.Serialize(stripeConfig), null); case PaymentGatewayType.PayPal: var payPalConfig = configElement.Deserialize(); if (payPalConfig == null || string.IsNullOrEmpty(payPalConfig.ClientId) || string.IsNullOrEmpty(payPalConfig.ClientSecret)) { return (false, null, "Für PayPal müssen ClientId und ClientSecret angegeben werden."); } return (true, JsonSerializer.Serialize(payPalConfig), null); default: return (true, JsonSerializer.Serialize(new object()), null); } } catch (JsonException ex) { return (false, null, $"Ungültiges JSON-Format für die Konfiguration: {ex.Message}"); } } } }