using Femto.Common.Domain;
using Femto.Modules.Auth.Application.Dto;
using Femto.Modules.Auth.Data;
using Femto.Modules.Auth.Errors;
using Microsoft.EntityFrameworkCore;

namespace Femto.Modules.Auth.Application.Interface.ValidateSession;

internal class ValidateSessionCommandHandler(AuthContext context)
    : ICommandHandler<ValidateSessionCommand, ValidateSessionResult>
{
    public async Task<ValidateSessionResult> Handle(
        ValidateSessionCommand request,
        CancellationToken cancellationToken
    )
    {
        var now = DateTimeOffset.UtcNow;

        var user = await context.Users.SingleOrDefaultAsync(
            u => u.Sessions.Any(s => s.Id == request.SessionId && s.Expires > now),
            cancellationToken
        );

        if (user is null)
            throw new InvalidSessionError();

        var session = user.PossiblyRefreshSession(request.SessionId);

        return new ValidateSessionResult(
            new Session(session.Id, session.Expires),
            new UserInfo(user)
        );
    }
}
