import { Injectable } from '@nestjs/common';
import { PrismaService } from '@core/database/prisma/prisma.service';
import { Prisma, MeetingStatus } from '@prisma/client';

@Injectable()
export class MeetingRepository {
  constructor(private readonly prisma: PrismaService) {}

  findMeetingById(id: string) {
    return this.prisma.meeting.findUnique({
      where: { id },
    });
  }

  findMeetingWithDetails(id: string) {
    return this.prisma.meeting.findUnique({
      where: { id },
      include: {
        creator: {
          select: {
            id: true,
            displayName: true,
            email: true,
            departmentMemberships: {
              where: { leftAt: null },
              include: {
                department: { select: { id: true, name: true, code: true } },
                position: { select: { id: true, name: true, level: true } },
              },
            },
          },
        },
        attendances: {
          include: {
            user: {
              select: {
                id: true,
                displayName: true,
                email: true,
                departmentMemberships: {
                  where: { leftAt: null },
                  include: {
                    department: { select: { id: true, name: true, code: true } },
                    position: { select: { id: true, name: true, level: true } },
                  },
                },
              },
            },
          },
        },
        requiredAttendees: {
          include: {
            user: {
              select: {
                id: true,
                displayName: true,
                email: true,
                departmentMemberships: {
                  where: { leftAt: null },
                  include: {
                    department: { select: { id: true, name: true, code: true } },
                    position: { select: { id: true, name: true, level: true } },
                  },
                },
                roles: { include: { role: true } },
              },
            },
          },
        },
        externalAttendees: {
          orderBy: [{ sourceRole: 'asc' }, { email: 'asc' }],
        },
      },
    });
  }

  listMeetings(where: Prisma.MeetingWhereInput, page: number, limit: number, orderBy: Prisma.MeetingOrderByWithRelationInput) {
    return this.prisma.meeting.findMany({
      where,
      include: {
        creator: { select: { id: true, displayName: true, email: true } },
        attendances: {
          include: {
            user: { select: { id: true, displayName: true, email: true } },
          },
        },
        requiredAttendees: { select: { id: true } },
      },
      orderBy,
      skip: (page - 1) * limit,
      take: limit,
    });
  }

  countMeetings(where: Prisma.MeetingWhereInput) {
    return this.prisma.meeting.count({ where });
  }

  createMeeting(data: Prisma.MeetingCreateInput) {
    return this.prisma.meeting.create({
      data,
      include: { creator: { select: { id: true, displayName: true, email: true } } },
    });
  }

  updateMeeting(id: string, data: Prisma.MeetingUpdateInput) {
    return this.prisma.meeting.update({
      where: { id },
      data,
      include: { creator: { select: { id: true, displayName: true, email: true } } },
    });
  }

  deleteMeeting(id: string) {
    return this.prisma.meeting.delete({ where: { id } });
  }

  updateMeetingStatus(id: string, status: MeetingStatus) {
    return this.prisma.meeting.update({
      where: { id },
      data: { status },
    });
  }
}
