using FastEndpoints;
using Knots.DTO.Discussion;
using Knots.Models;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;

namespace Knots.Endpoints.Discussion;

public class CreatePrivateDiscussionEndpoint(KnotsDbContext db)
    : Endpoint<CreatePrivateDiscussionRequest, GetDiscussionDto>
{
    public override void Configure()
    {
        Post("/discussions/private");
    }

    public override async Task HandleAsync(CreatePrivateDiscussionRequest req, CancellationToken ct)
    {
        int currentUserId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);

        // 1. retrouver l'utilisateur cible par son nom
        Models.User? target = await db.Users
            .SingleOrDefaultAsync(u => u.Username == req.Username, ct);

        if (target is null)
        {
            await SendNotFoundAsync(ct);   // utilisateur introuvable
            return;
        }

        if (target.Id == currentUserId)
        {
            await SendErrorsAsync(400, ct); // pas de discussion avec soi-même
            return;
        }

        // 2. vérifier qu'une discussion privée entre les deux n'existe pas déjà
        Models.Discussion? existing = await db.Discussions
            .Where(d => d.GroupId == null
                && d.UserDiscussions.Any(ud => ud.UserId == currentUserId)
                && d.UserDiscussions.Any(ud => ud.UserId == target.Id))
            .FirstOrDefaultAsync(ct);

        if (existing is not null)
        {
            await SendOkAsync(new GetDiscussionDto
            {
                Id = existing.Id,
                IsGroup = false,
                Name = target.Username!,
                MembersCount = null
            }, ct);
            return;
        }

        // 3. créer la discussion + les deux participants
        Models.Discussion discussion = new()
        {
            IsGroup = false,
            UserDiscussions =
            [
                new UserDiscussion { UserId = currentUserId },
                new UserDiscussion { UserId = target.Id }
            ]
        };

        db.Discussions.Add(discussion);
        await db.SaveChangesAsync(ct);

        await SendOkAsync(new GetDiscussionDto
        {
            Id = discussion.Id,
            IsGroup = false,
            Name = target.Username!,
            MembersCount = null
        }, ct);
    }
}

public class CreatePrivateDiscussionRequest
{
    public string Username { get; set; } = "";
}