using System.Security.Claims; using Api.SeaHavenIndustries.DTOs; using Api.SeaHavenIndustries.Helper; using Data.SeaHavenIndustries; using FluentValidation; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using SeaHaven.Services.DTOs; using SeaHaven.Services.Interfaces; [ApiController] [Authorize] [Route("api/FollowUp")] [Route("api/followups")] public class FollowUpController : ControllerBase { private readonly IFollowUpService _followUpService; private readonly ILogger _logger; public FollowUpController(IFollowUpService followUpService, ILogger logger) { _followUpService = followUpService; _logger = logger; } [HttpGet("GetFollowUpList")] public async Task GetFollowUps( string? search = "", string? status = "Open", int page = 1, int pageSize = 12, CancellationToken cancellationToken = default) { var pagedResult = await _followUpService.GetFollowUpListAsync(page, pageSize, search, status, cancellationToken); var items = pagedResult.Items; var data = items.Select(x => new { x.Id, x.Reason, x.ScheduleDate, x.ScheduleStartTime, x.EmployeeId, x.WorkOrderId, x.AccountId, x.LocationId, x.AccountName, x.AssignedTo, x.LocationName, x.WorkOrderNumber, x.InternalWONumber, x.Status, x.CreatedDate, x.CreatedById, x.CreatedByName }).ToList(); return Ok(new Pagination_DTO { Data = data, PageNumber = page, PageSize = pageSize, TotalCount = pagedResult.TotalCount, TotalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize) }); } [HttpGet("GetById")] public async Task GetById(int id, CancellationToken cancellationToken) { var model = await _followUpService.GetFollowUpDetailAsync(id, cancellationToken); if (model == null) return NotFound(); return Ok(new { model.Id, model.Reason, model.ScheduleDate, model.ScheduleStartTime, model.EmployeeId, model.WorkOrderId, model.AccountId, model.LocationId, model.AccountName, model.AssignedTo, model.LocationName, model.WorkOrderNumber, model.InternalWONumber, model.Status, model.CreatedDate, model.CreatedById, model.CreatedByName }); } [HttpPost("Create")] public async Task Create(FollowUp_DTO dto, CancellationToken cancellationToken) { try { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); if (userId == null) return Unauthorized(new Response { Status = "Error", Message = "User not authenticated" }); var id = await _followUpService.CreateOpenFollowUpAsync(MapToCreateRequest(dto), userId, cancellationToken); return Ok(new DataResponse { Status = "200", Message = "Follow Up created", Data = id }); } catch (ValidationException vex) { var errors = string.Join(", ", vex.Errors.Select(e => e.ErrorMessage)); return BadRequest(new Response { Status = "Validation Error", Message = errors }); } catch (Exception ex) { return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) }); } } [HttpPost("Update")] public async Task Update(FollowUp_DTO dto, CancellationToken cancellationToken) { try { await _followUpService.UpdateFollowUpFieldsAsync(dto.Id, MapToUpdateRequest(dto), cancellationToken); return Ok(new DataResponse { Status = "200", Message = "Follow Up updated" }); } catch (ValidationException vex) { var errors = string.Join(", ", vex.Errors.Select(e => e.ErrorMessage)); return BadRequest(new Response { Status = "Validation Error", Message = errors }); } catch (KeyNotFoundException) { return NotFound(new Response { Status = "Error", Message = "Follow Up not found" }); } catch (Exception ex) { return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) }); } } [HttpPost("Complete")] public async Task Complete(int id, CancellationToken cancellationToken) { var found = await _followUpService.SetFollowUpStatusAsync(id, "Completed", cancellationToken); if (!found) return NotFound(); return Ok(); } [HttpPost("Cancel")] public async Task Cancel(int id, CancellationToken cancellationToken) { var found = await _followUpService.SetFollowUpStatusAsync(id, "Cancelled", cancellationToken); if (!found) return NotFound(); return Ok(); } [HttpPost("Delete")] public async Task Delete(int id, CancellationToken cancellationToken) { try { var found = await _followUpService.RemoveFollowUpAsync(id, cancellationToken); if (!found) return NotFound(new Response { Status = "Error", Message = "Follow Up not found" }); return Ok(new DataResponse { Status = "200", Message = "Follow Up deleted" }); } catch (KeyNotFoundException) { return NotFound(new Response { Status = "Error", Message = "Follow Up not found" }); } catch (Exception ex) { return StatusCode(500, new Response { Status = "Error", Message = _logger.Sanitize(ex) }); } } private static FollowUpCreateRequestDTO MapToCreateRequest(FollowUp_DTO dto) { return new FollowUpCreateRequestDTO { Reason = dto.Reason, ScheduleDate = dto.ScheduleDate, ScheduleStartTime = dto.ScheduleStartTime, EmployeeId = dto.EmployeeId, WorkOrderId = dto.WorkOrderId, AccountId = dto.AccountId, LocationId = dto.LocationId }; } private static FollowUpUpdateRequestDTO MapToUpdateRequest(FollowUp_DTO dto) { return new FollowUpUpdateRequestDTO { Id = dto.Id, Reason = dto.Reason, ScheduleDate = dto.ScheduleDate, ScheduleStartTime = dto.ScheduleStartTime, EmployeeId = dto.EmployeeId, WorkOrderId = dto.WorkOrderId, AccountId = dto.AccountId, LocationId = dto.LocationId }; } }