using Application.Abstractions.Data;
using Application.Abstractions.Messaging;
using Domain.Entities.Donations;
using Microsoft.EntityFrameworkCore;

namespace Application.Features.Api.Crew.StartSession;

internal sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Response>
{
    public async Task<Response> Handle(Command request, CancellationToken ct)
    {
        var crew = await db.Crew
            .Include(c => c.Members.Where(m => m.IsActive))
            .FirstOrDefaultAsync(c => c.ID == request.CrewID && c.IsActive, ct);

        if (crew is null)
        {
            throw new KeyNotFoundException("크루를 찾을 수 없습니다.");
        }

        if (!crew.Members.Any())
        {
            throw new InvalidOperationException("크루원이 없습니다.");
        }

        // 이미 진행 중인 세션이 있는지 확인
        var activeSession = await db.CrewSession
            .AnyAsync(s => s.CrewID == request.CrewID && s.Status != Domain.Entities.Donations.ValueObject.CrewSessionStatus.Ended, ct);

        if (activeSession)
        {
            throw new InvalidOperationException("이미 진행 중인 크루 방송이 있습니다.");
        }

        // 세션 생성 (Inviting)
        var session = CrewSession.Create(request.CrewID, request.Title);
        db.CrewSession.Add(session);
        await db.SaveChangesAsync(ct);

        // 각 크루원에 대해 동의 레코드 생성
        foreach (var member in crew.Members)
        {
            var consent = CrewSessionConsent.Create(session.ID, member.ID);
            db.CrewSessionConsent.Add(consent);

            // 크루원별 집계 초기화
            var summary = CrewDonationSummary.Create(session.ID, member.ID);
            db.CrewDonationSummary.Add(summary);
        }

        await db.SaveChangesAsync(ct);

        // 알림/쪽지 발송은 Endpoint에서 SignalR + NotificationService로 처리
        return new Response(session.ID);
    }
}