// src/Webshop.Application/Services/Customers/CustomerService.cs using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; using Resend; using System.Linq; using System.Threading.Tasks; using System.Web; using Webshop.Application.DTOs; using Webshop.Application.DTOs.Auth; using Webshop.Application.DTOs.Customers; using Webshop.Domain.Identity; using Webshop.Domain.Interfaces; namespace Webshop.Application.Services.Customers { public class CustomerService : ICustomerService { private readonly ICustomerRepository _customerRepository; private readonly UserManager _userManager; private readonly IConfiguration _configuration; private readonly IResend _resend; public CustomerService(ICustomerRepository customerRepository, UserManager userManager, IConfiguration configuration, IResend resend) { _customerRepository = customerRepository; _userManager = userManager; _configuration = configuration; _resend = resend; } public async Task> GetMyProfileAsync(string userId) { var customer = await _customerRepository.GetByUserIdAsync(userId); if (customer == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Kundenprofil nicht gefunden."); var identityUser = await _userManager.FindByIdAsync(userId); if (identityUser == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Benutzerkonto nicht gefunden."); var dto = new CustomerDto { Id = customer.Id, UserId = customer.AspNetUserId, FirstName = customer.FirstName, LastName = customer.LastName, Email = identityUser.Email ?? string.Empty, PhoneNumber = identityUser.PhoneNumber, DefaultShippingAddressId = customer.DefaultShippingAddressId, DefaultBillingAddressId = customer.DefaultBillingAddressId }; return ServiceResult.Ok(dto); } public async Task UpdateMyProfileAsync(string userId, UpdateCustomerDto profileDto) { var customer = await _customerRepository.GetByUserIdAsync(userId); if (customer == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Kundenprofil nicht gefunden."); var identityUser = await _userManager.FindByIdAsync(userId); if (identityUser == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Benutzerkonto nicht gefunden."); if (!await _userManager.CheckPasswordAsync(identityUser, profileDto.CurrentPassword)) { return ServiceResult.Fail(ServiceResultType.InvalidInput, "Das zur Bestätigung eingegebene Passwort ist falsch."); } customer.FirstName = profileDto.FirstName; customer.LastName = profileDto.LastName; customer.DefaultShippingAddressId = profileDto.DefaultShippingAddressId; customer.DefaultBillingAddressId = profileDto.DefaultBillingAddressId; await _customerRepository.UpdateAsync(customer); if (!string.IsNullOrEmpty(profileDto.PhoneNumber) && identityUser.PhoneNumber != profileDto.PhoneNumber) { identityUser.PhoneNumber = profileDto.PhoneNumber; var updateResult = await _userManager.UpdateAsync(identityUser); if (!updateResult.Succeeded) { var errors = string.Join(" ", updateResult.Errors.Select(e => e.Description)); return ServiceResult.Fail(ServiceResultType.Failure, $"Fehler beim Aktualisieren der Telefonnummer: {errors}"); } } return ServiceResult.Ok(); } public async Task ChangePasswordAsync(string userId, ChangePasswordRequestDto request) { var user = await _userManager.FindByIdAsync(userId); if (user == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Benutzer nicht gefunden."); var result = await _userManager.ChangePasswordAsync(user, request.OldPassword, request.NewPassword); if (!result.Succeeded) { var errors = string.Join(" ", result.Errors.Select(e => e.Description)); return ServiceResult.Fail(ServiceResultType.InvalidInput, errors); } return ServiceResult.Ok(); } public async Task ChangeEmailAsync(string userId, string newEmail, string currentPassword) { var user = await _userManager.FindByIdAsync(userId); if (user == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Benutzer nicht gefunden."); if (!await _userManager.CheckPasswordAsync(user, currentPassword)) { return ServiceResult.Fail(ServiceResultType.InvalidInput, "Das zur Bestätigung eingegebene Passwort ist falsch."); } if (user.Email != newEmail && await _userManager.FindByEmailAsync(newEmail) != null) { return ServiceResult.Fail(ServiceResultType.Conflict, "Die neue E-Mail-Adresse ist bereits registriert."); } var token = await _userManager.GenerateChangeEmailTokenAsync(user, newEmail); var clientUrl = _configuration["App:ClientUrl"]!; var confirmationLink = $"{clientUrl}/confirm-email-change?userId={user.Id}&newEmail={HttpUtility.UrlEncode(newEmail)}&token={HttpUtility.UrlEncode(token)}"; var message = new EmailMessage(); message.From = _configuration["Resend:FromEmail"]!; message.To.Add(newEmail); message.Subject = "Bestätigen Sie Ihre neue E-Mail-Adresse"; message.HtmlBody = $"

E-Mail-Änderung Bestätigung

Bitte klicken Sie auf den folgenden Link, um Ihre neue E-Mail-Adresse zu bestätigen:

Neue E-Mail-Adresse bestätigen

"; await _resend.EmailSendAsync(message); // Die Erfolgsmeldung wird hier als Teil des "Ok"-Results übermittelt return ServiceResult.Ok("Bestätigungs-E-Mail wurde an die neue Adresse gesendet. Bitte prüfen Sie Ihr Postfach."); } } }