using Api.SeaHavenIndustries.DTOs; using Data.SeaHavenIndustries; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using SendGrid.Helpers.Mail; using SeaHaven.Services.Interfaces; namespace Api.SeaHavenIndustries.Controllers { //[Authorize] // Removed for testing [ApiController] [Route("api/Contact")] [Route("api/contacts")] public class ContactController : Controller { private readonly UserManager _userManager; private readonly IContactService _contactService; private readonly ILocationService _locationService; public ContactController( UserManager userManager, IContactService contactService, ILocationService locationService) { _userManager = userManager; _contactService = contactService; _locationService = locationService; } [HttpPost] [Route("AddContacts")] public async Task AddContacts(Contact_DTO contacts) { try { // ✅ Use DTO mapping method instead of manual property assignment var userId = _userManager.GetUserId(User) ?? "system"; await _contactService.CreateContactAsync(contacts.ToServiceCreateDTO(), userId); return Ok(new DataResponse { Message = "Updated Successfully", Status = "200" }); } catch (Exception ex) { return BadRequest(new Response { Status = "Error", Message = ex.Message }); } } [HttpPost] [Route("EditContacts")] public async Task EditContacts(EditContact_DTO contacts) { try { // ✅ Use DTO mapping method instead of manual property assignment var userId = _userManager.GetUserId(User) ?? "system"; await _contactService.UpdateContactAsync(contacts.Id, contacts.ToServiceUpdateDTO(), userId); return Ok(new DataResponse { Message = "Updated Successfully", Status = "200" }); } catch (KeyNotFoundException) { return BadRequest(new Response { Status = "Error", Message = "Contact not found" }); } catch (Exception ex) { return BadRequest(new Response { Status = "Error", Message = ex.Message }); } } [HttpGet] [Route("DeleteContacts")] public async Task DeleteContacts(int id) { try { var userId = _userManager.GetUserId(User) ?? "system"; // ✅ Call Service layer (not DataService directly) await _contactService.DeleteContactAsync(id, userId); return Ok(new DataResponse { Message = "Removed Successfully", Status = "200" }); } catch (KeyNotFoundException) { return BadRequest(new Response { Status = "Error", Message = "ID not matched!" }); } catch (Exception ex) { return BadRequest(new Response { Status = "Error", Message = ex.Message }); } } [HttpGet] [Route("GetContactList")] public async Task GetContactList(string? search ="", int page = 1, int pageSize = 10) { // ✅ Call Service layer var pagedResult = await _contactService.GetContactsPagedAsync(page, pageSize, search); // ✅ Use DTO mapping method (NO manual transformation in controller) var data = ContactListItem_DTO.FromServiceDTOs(pagedResult.Items); var totalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize); var viewModel = new Pagination_DTO { Data = data, PageNumber = page, PageSize = pageSize, TotalCount = pagedResult.TotalCount, TotalPages = totalPages }; return Ok(viewModel); } [HttpGet] [Route("GetContacts")] public async Task GetContacts() { // ✅ Call Service layer var data = await _contactService.GetAllContactsAsync(); return Ok(data); } [HttpGet] [Route("GetLocations")] public async Task GetLocations() { // ✅ Call Service layer var locations = await _locationService.GetAllLocationsAsync(); // ✅ Use DTO mapping method (NO manual transformation in controller) var data = LocationViewModel_DTO.FromServiceDTOs(locations); return Ok(data); } // TODO: ARCHITECTURAL VIOLATION - These methods should NOT be in ContactController // GetCategories should be in a CategoryController with ICategoryService // GetUsers should be in a UserController with IUserService // For now, commenting out to prevent direct database access [HttpGet] [Route("GetCategories")] public async Task GetCategories() { // ❌ TEMPORARY: Needs ICategoryService return StatusCode(501, new Response { Status = "Error", Message = "Not Implemented - Needs CategoryService" }); } [HttpGet] [Route("GetUsers")] public async Task GetUsers() { // ❌ TEMPORARY: Needs IUserService return StatusCode(501, new Response { Status = "Error", Message = "Not Implemented - Needs UserService" }); } // TODO: ARCHITECTURAL VIOLATION - Location CRUD methods should NOT be in ContactController // These should be in LocationController with ILocationService [HttpPost] [Route("AddLocation")] public async Task AddLocation(Location_DTO model) { try { // ✅ Use Service layer with DTO mapping var userId = _userManager.GetUserId(User) ?? "system"; await _locationService.CreateLocationAsync(model.ToServiceCreateDTO(), userId); return Ok(new DataResponse { Message = "Updated Successfully", Status = "200" }); } catch (Exception ex) { return BadRequest(new Response { Status = "Error", Message = ex.Message }); } } [HttpPost] [Route("EditLocation")] public async Task EditLocation(EditLocation_DTO model) { try { // ✅ Use Service layer with DTO mapping var userId = _userManager.GetUserId(User) ?? "system"; await _locationService.UpdateLocationAsync(model.Id, model.ToServiceUpdateDTO(), userId); return Ok(new DataResponse { Message = "Updated Successfully", Status = "200" }); } catch (KeyNotFoundException) { return BadRequest(new Response { Status = "Error", Message = "ID not matched!" }); } catch (Exception ex) { return BadRequest(new Response { Status = "Error", Message = ex.Message }); } } [HttpPost] [Route("DeleteLocation")] public async Task DeleteLocation(int Id) { try { // ✅ Use Service layer var userId = _userManager.GetUserId(User) ?? "system"; await _locationService.DeleteLocationAsync(Id, userId); return Ok(new DataResponse { Message = "Updated Successfully", Status = "200" }); } catch (KeyNotFoundException) { return BadRequest(new Response { Status = "Error", Message = "ID not matched!" }); } catch (Exception ex) { return BadRequest(new Response { Status = "Error", Message = ex.Message }); } } [HttpGet] [Route("GetAddressbook")] public async Task GetAddressbook(string? search = "", int page = 1, int pageSize = 10) { // ✅ Call Service layer var pagedResult = await _locationService.GetLocationsPagedAsync(page, pageSize, search); // ✅ Use DTO mapping method (NO manual transformation in controller) var data = LocationListItem_DTO.FromServiceDTOs(pagedResult.Items); var totalPages = (int)Math.Ceiling(pagedResult.TotalCount / (double)pageSize); var viewModel = new Pagination_DTO { Data = data, PageNumber = page, PageSize = pageSize, TotalCount = pagedResult.TotalCount, TotalPages = totalPages }; return Ok(viewModel); } } }