using GerbilManagerWebAPI.Common; using GerbilManagerWebAPI.Dtos; using GerbilManagerWebAPI.Models; using Gridify; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.EntityFrameworkCore; namespace GerbilManagerWebAPI.Endpoints { public static class ContactEndpoints { public static IEndpointRouteBuilder MapContactEndpoints(this IEndpointRouteBuilder app) { var group = app.MapGroup("/contacts").WithTags("Contacts"); group.MapGet("/", async ([AsParameters] GridifyParams query, ApplicationContext db) => TypedResults.Ok(await db.Contacts.AsNoTracking().ToPagedResultAsync(query, ToDto))); group.MapGet("/{id:guid}", async Task, NotFound>> (Guid id, ApplicationContext db) => { var c = await db.Contacts.AsNoTracking().FirstOrDefaultAsync(x => x.Id == id); return c is null ? TypedResults.NotFound() : TypedResults.Ok(ToDto(c)); }); group.MapPost("/", async (ContactInput input, ApplicationContext db) => { var c = new Contact { Id = Guid.NewGuid(), Name = input.Name, Email = input.Email, Phone = input.Phone, Address = input.Address, Notes = input.Notes, IsBreeder = input.IsBreeder, IsReceiver = input.IsReceiver, NameSuffix = input.NameSuffix, IsManual = true }; db.Contacts.Add(c); await db.SaveChangesAsync(); return TypedResults.Created($"/contacts/{c.Id}", ToDto(c)); }); group.MapPut("/{id:guid}", async Task> (Guid id, ContactInput input, ApplicationContext db) => { var c = await db.Contacts.FirstOrDefaultAsync(x => x.Id == id); if (c is null) return TypedResults.NotFound(); c.Name = input.Name; c.Email = input.Email; c.Phone = input.Phone; c.Address = input.Address; c.Notes = input.Notes; c.IsBreeder = input.IsBreeder; c.IsReceiver = input.IsReceiver; c.NameSuffix = input.NameSuffix; await db.SaveChangesAsync(); return TypedResults.NoContent(); }); // 409 if any gerbil references this contact as origin or receiver. group.MapDelete("/{id:guid}", async Task>> (Guid id, ApplicationContext db) => { var c = await db.Contacts.FirstOrDefaultAsync(x => x.Id == id); if (c is null) return TypedResults.NotFound(); bool linked = await db.Gerbils.AnyAsync(g => g.OriginContactId == id || g.ReceiverContactId == id); if (linked) return TypedResults.Conflict("Contact is linked to one or more gerbils and cannot be deleted."); db.Contacts.Remove(c); await db.SaveChangesAsync(); return TypedResults.NoContent(); }); return app; } private static ContactDto ToDto(Contact c) => new(c.Id, c.Name, c.Email, c.Phone, c.Address, c.Notes, c.IsBreeder, c.IsReceiver, c.NameSuffix, c.Provenance); } }