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 { /// /// Follow-Up service implementation /// Contains business logic, validation, and orchestration for Follow-Up operations /// public class FollowUpService : IFollowUpService { private readonly IFollowUpDataService _followUpDataService; private readonly ICreateFollowUpValidation _createValidator; private readonly IUpdateFollowUpValidation _updateValidator; public FollowUpService( IFollowUpDataService followUpDataService, ICreateFollowUpValidation createValidator, IUpdateFollowUpValidation updateValidator) { _followUpDataService = followUpDataService; _createValidator = createValidator; _updateValidator = updateValidator; } public async Task GetFollowUpByIdAsync(int id) { var followUp = await _followUpDataService.GetByIdAsync(id); return followUp == null ? null : MapToDTO(followUp); } public async Task GetFollowUpByIdWithDetailsAsync(int id) { var followUp = await _followUpDataService.GetByIdWithDetailsAsync(id); return followUp == null ? null : MapToDTO(followUp); } public async Task> GetAllFollowUpsAsync() { var followUps = await _followUpDataService.GetAllAsync(); return followUps.Select(MapToDTO); } public async Task> GetFollowUpsByWorkOrderIdAsync(int workOrderId) { var followUps = await _followUpDataService.GetByWorkOrderIdAsync(workOrderId); return followUps.Select(MapToDTO); } public async Task> GetFollowUpsPagedAsync(int page, int pageSize, string? search = null, string? status = null) { var (items, totalCount) = await _followUpDataService.GetPagedAsync(page, pageSize, search); var filteredItems = items.AsEnumerable(); if (!string.IsNullOrWhiteSpace(status)) { filteredItems = filteredItems.Where(f => f.Status == status); } return new PagedResult { Items = filteredItems.Select(MapToDTO).ToList(), TotalCount = totalCount, Page = page, PageSize = pageSize }; } public async Task CreateFollowUpAsync(CreateFollowUpDTO dto, string userId) { var validationResult = await _createValidator.ValidateAsync(dto); if (!validationResult.IsValid) { throw new ValidationException(validationResult.Errors); } var followUp = new FollowUps { Reason = dto.Reason, ScheduleDate = dto.ScheduleDate, ScheduleStartTime = dto.ScheduleStartTime, Status = dto.Status, EmployeeId = dto.EmployeeId, WorkOrderId = dto.WorkOrderId, AccountId = dto.AccountId, LocationId = dto.LocationId, CreatedDate = DateTime.UtcNow, createdby = userId }; var created = await _followUpDataService.AddAsync(followUp); return MapToDTO(created); } public async Task UpdateFollowUpAsync(int id, UpdateFollowUpDTO dto, string userId) { var validationResult = await _updateValidator.ValidateAsync(dto); if (!validationResult.IsValid) { throw new ValidationException(validationResult.Errors); } var followUp = await _followUpDataService.GetByIdAsync(id); if (followUp == null) throw new InvalidOperationException($"Follow-Up with ID {id} not found"); if (dto.Reason != null) followUp.Reason = dto.Reason; if (dto.ScheduleDate.HasValue) followUp.ScheduleDate = dto.ScheduleDate.Value; if (dto.ScheduleStartTime.HasValue) followUp.ScheduleStartTime = dto.ScheduleStartTime.Value; if (dto.Status != null) followUp.Status = dto.Status; if (dto.EmployeeId.HasValue) followUp.EmployeeId = dto.EmployeeId; if (dto.WorkOrderId.HasValue) followUp.WorkOrderId = dto.WorkOrderId; if (dto.AccountId.HasValue) followUp.AccountId = dto.AccountId; if (dto.LocationId.HasValue) followUp.LocationId = dto.LocationId; followUp.LastModificationTime = DateTime.UtcNow; if (int.TryParse(userId, out int userIdInt)) followUp.LastModifierUserId = userIdInt; await _followUpDataService.UpdateAsync(followUp); return MapToDTO(followUp); } public async Task DeleteFollowUpAsync(int id, string userId) { var followUp = await _followUpDataService.GetByIdAsync(id); if (followUp == null) throw new InvalidOperationException($"Follow-Up with ID {id} not found"); followUp.IsDeleted = true; followUp.DeleterUserId = userId; followUp.DeletionTime = DateTime.UtcNow; await _followUpDataService.UpdateAsync(followUp); } public async Task FollowUpExistsAsync(int id) { return await _followUpDataService.ExistsAsync(id); } public async Task GetTotalFollowUpCountAsync() { return await _followUpDataService.CountAsync(); } private FollowUpDTO MapToDTO(FollowUps followUp) { return new FollowUpDTO { Id = followUp.Id, Reason = followUp.Reason, ScheduleDate = followUp.ScheduleDate, ScheduleStartTime = followUp.ScheduleStartTime, Status = followUp.Status, EmployeeId = followUp.EmployeeId, EmployeeName = followUp.Employee != null ? $"{followUp.Employee.FirstName} {followUp.Employee.LastName}" : null, WorkOrderId = followUp.WorkOrderId, AccountId = followUp.AccountId, AccountName = followUp.Account?.Name, LocationId = followUp.LocationId, LocationName = followUp.Location?.Name, CreatedDate = followUp.CreatedDate }; } } }