using Data.SeaHavenIndustries; using FluentValidation; using SeaHaven.DataServices.Interfaces; using SeaHaven.Services.DTOs; using SeaHaven.Services.Interfaces; using SeaHaven.Services.Validation; namespace SeaHaven.Services.Implementation { /// /// Location service implementation /// Contains business logic, validation, and orchestration for Location operations /// public class LocationService : ILocationService { private readonly ILocationDataService _locationDataService; private readonly ICreateLocationValidation _createValidator; private readonly IUpdateLocationValidation _updateValidator; public LocationService( ILocationDataService locationDataService, ICreateLocationValidation createValidator, IUpdateLocationValidation updateValidator) { _locationDataService = locationDataService; _createValidator = createValidator; _updateValidator = updateValidator; } // Query operations public async Task GetLocationByIdAsync(int id) { var location = await _locationDataService.GetByIdAsync(id); return location == null ? null : MapToDTO(location); } public async Task GetLocationByIdWithDetailsAsync(int id) { var location = await _locationDataService.GetByIdWithDetailsAsync(id); return location == null ? null : MapToDTO(location); } public async Task> GetAllLocationsAsync() { var locations = await _locationDataService.GetAllAsync(); return locations.Select(MapToDTO); } public async Task> GetLocationsByAccountIdAsync(int accountId) { var locations = await _locationDataService.GetByAccountIdAsync(accountId); return locations.Select(MapToDTO); } public async Task> GetLocationsPagedAsync(int page, int pageSize, string? search = null) { var (items, totalCount) = await _locationDataService.GetPagedAsync(page, pageSize, search); return new PagedResult { Items = items.Select(MapToDTO).ToList(), TotalCount = totalCount, Page = page, PageSize = pageSize }; } public async Task> GetSiteOptionsAsync(string? search = null) { var rows = await _locationDataService.GetSiteOptionsAsync(search); return rows .Select(r => new SiteOptionDTO { Id = r.Id, Code = r.Code, City = r.City, State = r.State }) .ToList(); } public async Task CreateLocationAsync(CreateLocationDTO dto, string userId) { var validationResult = await _createValidator.ValidateAsync(dto); if (!validationResult.IsValid) { throw new ValidationException(validationResult.Errors); } var location = new Locations { Name = dto.LocationName, Title = dto.LocationName, Address1 = dto.Address, City = dto.City, State = dto.State, Zip = dto.Zipcode, CreatedDate = DateTime.UtcNow, createdby = userId }; var created = await _locationDataService.AddAsync(location); return MapToDTO(created); } public async Task UpdateLocationAsync(int id, UpdateLocationDTO dto, string userId) { var validationResult = await _updateValidator.ValidateAsync(dto); if (!validationResult.IsValid) { throw new ValidationException(validationResult.Errors); } var location = await _locationDataService.GetByIdAsync(id); if (location == null) throw new InvalidOperationException($"Location with ID {id} not found"); // Update properties if (dto.LocationName != null) location.Name = dto.LocationName; if (dto.LocationName != null) location.Title = dto.LocationName; if (dto.Address != null) location.Address1 = dto.Address; if (dto.City != null) location.City = dto.City; if (dto.State != null) location.State = dto.State; if (dto.Zipcode != null) location.Zip = dto.Zipcode; location.LastModificationTime = DateTime.UtcNow; if (int.TryParse(userId, out int userIdInt)) location.LastModifierUserId = userIdInt; await _locationDataService.UpdateAsync(location); return MapToDTO(location); } public async Task DeleteLocationAsync(int id, string userId) { var location = await _locationDataService.GetByIdAsync(id); if (location == null) throw new InvalidOperationException($"Location with ID {id} not found"); location.IsDeleted = true; location.DeleterUserId = userId; location.DeletionTime = DateTime.UtcNow; await _locationDataService.UpdateAsync(location); } public async Task LocationExistsAsync(int id) { return await _locationDataService.ExistsAsync(id); } public async Task GetTotalLocationCountAsync() { return await _locationDataService.CountAsync(); } public async Task> GetLocationListPagedAsync( int page, int pageSize, string? search, CancellationToken cancellationToken) { var (items, totalCount) = await _locationDataService.GetListPagedAsync(page, pageSize, search, cancellationToken); return new PagedResult { Items = items.Select(MapToDTO).ToList(), TotalCount = totalCount, Page = page, PageSize = pageSize }; } public async Task GetLocationDetailAsync(int id, CancellationToken cancellationToken) { var location = await _locationDataService.GetDetailByIdAsync(id, cancellationToken); return location == null ? null : MapToDTO(location); } public async Task CreateLocationFromRequestAsync(LocationCreateRequestDTO request, CancellationToken cancellationToken) { var location = new Locations { Name = request.Name, Title = request.Title, Address1 = request.Address, City = request.City, State = request.State, Zip = request.ZipCode, PhoneNumber = request.Phone, Email = request.ContactEmail, Status = request.Status }; await _locationDataService.AddAsync(location, cancellationToken); } public async Task UpdateLocationFromRequestAsync(int id, LocationUpdateRequestDTO request, CancellationToken cancellationToken) { var location = await _locationDataService.GetByIdForUpdateAsync(id, cancellationToken); if (location == null) throw new KeyNotFoundException($"Location with ID {id} not found"); location.Name = request.Name; location.Title = request.Title; location.Address1 = request.Address; location.City = request.City; location.State = request.State; location.Zip = request.ZipCode; location.PhoneNumber = request.Phone; location.Email = request.ContactEmail; location.Status = request.Status; await _locationDataService.UpdateAsync(location, cancellationToken); } public Task DeleteLocationByIdAsync(int id, CancellationToken cancellationToken) { return _locationDataService.DeleteByIdAsync(id, cancellationToken); } // Private helper methods private LocationDTO MapToDTO(Locations location) { return new LocationDTO { Id = location.Id, Name = location.Name, Title = location.Title, Address1 = location.Address1, Address2 = location.Address2, City = location.City, State = location.State, Zip = location.Zip, PhoneNumber = location.PhoneNumber, Email = location.Email, Status = location.Status, CreatedDate = location.CreatedDate, CreatedBy = location.createdby }; } } }