// src/Webshop.Application/Services/Customers/AddressService.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Webshop.Application; using Webshop.Application.DTOs.Customers; using Webshop.Domain.Entities; using Webshop.Domain.Interfaces; namespace Webshop.Application.Services.Customers { public class AddressService : IAddressService { private readonly IAddressRepository _addressRepository; private readonly ICustomerRepository _customerRepository; public AddressService(IAddressRepository addressRepository, ICustomerRepository customerRepository) { _addressRepository = addressRepository; _customerRepository = customerRepository; } public async Task>> GetMyAddressesAsync(string userId) { var customer = await _customerRepository.GetByUserIdAsync(userId); if (customer == null) { // If the customer profile doesn't exist for a valid user, return an empty list. return ServiceResult.Ok>(new List()); } var addresses = await _addressRepository.GetAllForCustomerAsync(customer.Id); return ServiceResult.Ok(addresses.Select(MapToDto)); } public async Task> GetMyAddressByIdAsync(Guid addressId, string userId) { var customer = await _customerRepository.GetByUserIdAsync(userId); if (customer == null) { return ServiceResult.Fail(ServiceResultType.NotFound, "Kundenprofil nicht gefunden."); } var address = await _addressRepository.GetByIdAsync(addressId); if (address == null) { return ServiceResult.Fail(ServiceResultType.NotFound, $"Adresse mit ID '{addressId}' nicht gefunden."); } if (address.CustomerId != customer.Id) { return ServiceResult.Fail(ServiceResultType.Forbidden, "Zugriff auf diese Adresse verweigert."); } return ServiceResult.Ok(MapToDto(address)); } public async Task> CreateAddressAsync(CreateAddressDto addressDto, string userId) { var customer = await _customerRepository.GetByUserIdAsync(userId); if (customer == null) { return ServiceResult.Fail(ServiceResultType.NotFound, "Kundenprofil nicht gefunden."); } var newAddress = new Address { CustomerId = customer.Id, FirstName = addressDto.FirstName ?? customer.FirstName, LastName = addressDto.LastName ?? customer.LastName, Street = addressDto.Street, HouseNumber = addressDto.HouseNumber, City = addressDto.City, PostalCode = addressDto.PostalCode, Country = addressDto.Country, Type = addressDto.Type }; await _addressRepository.AddAsync(newAddress); return ServiceResult.Ok(MapToDto(newAddress)); } public async Task UpdateAddressAsync(UpdateAddressDto addressDto, string userId) { var customer = await _customerRepository.GetByUserIdAsync(userId); if (customer == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Kundenprofil nicht gefunden."); var address = await _addressRepository.GetByIdAsync(addressDto.Id); if (address == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Adresse nicht gefunden."); if (address.CustomerId != customer.Id) return ServiceResult.Fail(ServiceResultType.Forbidden, "Zugriff auf diese Adresse verweigert."); address.FirstName = addressDto.FirstName; address.LastName = addressDto.LastName; address.Street = addressDto.Street; address.HouseNumber = addressDto.HouseNumber; address.City = addressDto.City; address.PostalCode = addressDto.PostalCode; address.Country = addressDto.Country; address.Type = addressDto.Type; await _addressRepository.UpdateAsync(address); return ServiceResult.Ok(); } public async Task DeleteAddressAsync(Guid addressId, string userId) { var customer = await _customerRepository.GetByUserIdAsync(userId); if (customer == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Kundenprofil nicht gefunden."); var address = await _addressRepository.GetByIdAsync(addressId); if (address == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Adresse nicht gefunden."); if (address.CustomerId != customer.Id) return ServiceResult.Fail(ServiceResultType.Forbidden, "Zugriff auf diese Adresse verweigert."); await _addressRepository.DeleteAsync(addressId); return ServiceResult.Ok(); } public async Task SetDefaultShippingAddressAsync(Guid addressId, string userId) { var customer = await _customerRepository.GetByUserIdAsync(userId); if (customer == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Kundenprofil nicht gefunden."); var address = await _addressRepository.GetByIdAsync(addressId); if (address == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Adresse nicht gefunden."); if (address.CustomerId != customer.Id) return ServiceResult.Fail(ServiceResultType.Forbidden, "Zugriff auf diese Adresse verweigert."); customer.DefaultShippingAddressId = addressId; await _customerRepository.UpdateAsync(customer); return ServiceResult.Ok(); } public async Task SetDefaultBillingAddressAsync(Guid addressId, string userId) { var customer = await _customerRepository.GetByUserIdAsync(userId); if (customer == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Kundenprofil nicht gefunden."); var address = await _addressRepository.GetByIdAsync(addressId); if (address == null) return ServiceResult.Fail(ServiceResultType.NotFound, "Adresse nicht gefunden."); if (address.CustomerId != customer.Id) return ServiceResult.Fail(ServiceResultType.Forbidden, "Zugriff auf diese Adresse verweigert."); customer.DefaultBillingAddressId = addressId; await _customerRepository.UpdateAsync(customer); return ServiceResult.Ok(); } private AddressDto MapToDto(Address address) { return new AddressDto { Id = address.Id, FirstName = address.FirstName, LastName = address.LastName, Street = address.Street, HouseNumber = address.HouseNumber, City = address.City, PostalCode = address.PostalCode, Country = address.Country, Type = address.Type }; } } }