using Application.Abstractions.Data;
using Application.Abstractions.Messaging;
using Microsoft.EntityFrameworkCore;

namespace Application.Features.Api.Crew.ConsentSession;

internal sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Response>
{
    public async Task<Response> Handle(Command request, CancellationToken ct)
    {
        var consent = await db.CrewSessionConsent
            .FirstOrDefaultAsync(c => c.CrewSessionID == request.CrewSessionID && c.CrewMemberID == request.CrewMemberID, ct);

        if (consent is null)
        {
            throw new KeyNotFoundException("동의 정보를 찾을 수 없습니다.");
        }

        if (consent.IsConsented)
        {
            throw new InvalidOperationException("이미 동의했습니다.");
        }

        consent.Consent();

        // 전원 동의 확인
        var allConsented = await db.CrewSessionConsent
            .Where(c => c.CrewSessionID == request.CrewSessionID)
            .AllAsync(c => c.IsConsented || c.CrewMemberID == request.CrewMemberID, ct);

        if (allConsented)
        {
            var session = await db.CrewSession.FindAsync([request.CrewSessionID], ct);
            session?.Activate();
        }

        await db.SaveChangesAsync(ct);
        return new Response(allConsented);
    }
}