using Knot.Contracts.Relations.Domain; using Knot.Modules.Relations.Application.Contacts; using Knot.Shared.Infrastructure; using Knot.Shared.Kernel; using MediatR; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.EntityFrameworkCore; namespace Knot.Modules.Relations.Presentation.Endpoints; public static class ContactsEndpoints { public static void MapContactsEndpoints(this WebApplication app) { var group = app.MapGroup("api/contacts").RequireAuthorization(); group.MapGet("", async (ISender sender, IUserContext userContext, CancellationToken ct) => { var result = await sender.Send(new GetContactsQuery(userContext.UserId), ct); return result.IsSuccess ? Results.Ok(result.Value) : Results.BadRequest(result.Error); }); group.MapGet("requests", async (ISender sender, IUserContext userContext, CancellationToken ct) => { var result = await sender.Send(new GetIncomingRequestsQuery(userContext.UserId), ct); return result.IsSuccess ? Results.Ok(result.Value) : Results.BadRequest(result.Error); }); group.MapGet("status/{userId:guid}", async ([FromRoute] Guid userId, ISender sender, IUserContext userContext, [FromServices] IContactsDbContext context, CancellationToken ct) => { var contact = await context.Contacts .FirstOrDefaultAsync(c => (c.UserId == userContext.UserId && c.ContactId == userId) || (c.UserId == userId && c.ContactId == userContext.UserId), ct); if (contact == null) { return Results.Ok(new { status = "none", friendshipId = (string?)null }); } string status; string? friendshipId = contact.Id.ToString(); if (contact.UserId == userContext.UserId && contact.Status == ContactStatus.Pending) { status = "outgoing"; } else if (contact.Status == ContactStatus.Pending) { status = "pending"; } else if (contact.Status == ContactStatus.Accepted) { status = "accepted"; } else if (contact.Status == ContactStatus.Declined) { status = "declined"; } else { status = "none"; } return Results.Ok(new { status, friendshipId }); }); group.MapPost("request", async ([FromBody] SendContactRequest request, ISender sender, IUserContext userContext, CancellationToken ct) => { var result = await sender.Send(new SendContactRequestCommand(userContext.UserId, request.ContactId), ct); return result.IsSuccess ? Results.Ok(new { status = "pending" }) : Results.BadRequest(result.Error.Description); }); group.MapPost("{id:guid}/accept", async ([FromRoute] Guid id, ISender sender, IUserContext userContext, CancellationToken ct) => { var result = await sender.Send(new AcceptContactRequestCommand(userContext.UserId, id), ct); return result.IsSuccess ? Results.Ok(new { id = result.Value }) : Results.NotFound(result.Error.Description); }); group.MapPost("{id:guid}/decline", async ([FromRoute] Guid id, ISender sender, IUserContext userContext, CancellationToken ct) => { var result = await sender.Send(new DeclineContactRequestCommand(userContext.UserId, id), ct); return result.IsSuccess ? Results.Ok(new { success = true }) : Results.NotFound(result.Error.Description); }); group.MapDelete("{id:guid}", async ([FromRoute] Guid id, ISender sender, IUserContext userContext, CancellationToken ct) => { var result = await sender.Send(new RemoveContactCommand(userContext.UserId, id), ct); return result.IsSuccess ? Results.Ok(new SuccessResponse(true)) : Results.NotFound(result.Error.Description); }); } public record SendContactRequest(Guid ContactId); }