using System.Security.Claims;
using System.Security.Cryptography;
using FastEndpoints;
using Microsoft.EntityFrameworkCore;
using TrackQrApi.Data;
using TrackQrApi.Features.Auth.Common;
using TrackQrApi.Features.Email.Services;
using TrackQrApi.Models;

namespace TrackQrApi.Features.Auth.Endpoints;

public class ResendVerificationEndpoint(AppDbContext db, IEmailService emailService) : EndpointWithoutRequest
{
    public override void Configure()
    {
        Post("/auth/resend-verification");
    }

    public override async Task HandleAsync(CancellationToken ct)
    {
        var userId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);

        var user = await db.Users.FindAsync([userId], ct);
        if (user == null)
        {
            await HttpContext.Response.SendAsync(new MessageResponse("User not found"), 404, cancellation: ct);
            return;
        }

        if (user.VerifiedAt != null)
        {
            await HttpContext.Response.SendAsync(new MessageResponse("Email is already verified"), 400,
                cancellation: ct);
            return;
        }

        // Remove existing tokens
        var existingTokens = await db.EmailVerificationTokens
            .Where(t => t.UserId == userId)
            .ToListAsync(ct);
        db.EmailVerificationTokens.RemoveRange(existingTokens);

        // Create new token
        var tokenBytes = RandomNumberGenerator.GetBytes(32);
        var tokenString = Convert.ToHexString(tokenBytes).ToLowerInvariant();

        var verificationToken = new EmailVerificationToken
        {
            Id = Guid.NewGuid(),
            UserId = userId,
            Token = tokenString,
            ExpiresAt = DateTime.UtcNow.AddHours(24),
            CreatedAt = DateTime.UtcNow
        };

        db.EmailVerificationTokens.Add(verificationToken);
        await db.SaveChangesAsync(ct);

        // Send verification email
        await emailService.SendEmailVerificationAsync(user.Email, tokenString, ct);

        await HttpContext.Response.SendAsync(new MessageResponse("Verification email sent"), cancellation: ct);
    }
}