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

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

  findByCheckpointUserAndDate(
    checkpointId: string,
    userId: string,
    localDate: string,
  ) {
    return this.prisma.siteDailySummary.findUnique({
      where: {
        checkpointId_userId_localDate: { checkpointId, userId, localDate },
      },
    });
  }

  findByCheckpointAndDate(checkpointId: string, localDate: string) {
    return this.prisma.siteDailySummary.findMany({
      where: { checkpointId, localDate },
      include: {
        user: {
          select: { id: true, displayName: true, email: true },
        },
      },
    });
  }

  async upsertSummary(
    checkpointId: string,
    userId: string,
    localDate: string,
    updateData: {
      eventType: 'CHECK_IN' | 'CHECK_OUT';
      timestamp: Date;
      eventId: string;
      hasGeoAnomaly: boolean;
    },
  ) {
    const isCheckIn = updateData.eventType === 'CHECK_IN';
    const existing = await this.findByCheckpointUserAndDate(
      checkpointId,
      userId,
      localDate,
    );

    if (!existing) {
      return this.prisma.siteDailySummary.create({
        data: {
          checkpoint: { connect: { id: checkpointId } },
          user: { connect: { id: userId } },
          localDate,
          firstCheckInAt: isCheckIn ? updateData.timestamp : null,
          lastCheckOutAt: isCheckIn ? null : updateData.timestamp,
          checkInCount: isCheckIn ? 1 : 0,
          checkOutCount: isCheckIn ? 0 : 1,
          hasGeoAnomaly: updateData.hasGeoAnomaly,
          lastEventId: updateData.eventId,
        },
      });
    }

    return this.prisma.siteDailySummary.update({
      where: { id: existing.id },
      data: {
        ...(isCheckIn
          ? {
              firstCheckInAt: existing.firstCheckInAt ?? updateData.timestamp,
              checkInCount: { increment: 1 },
            }
          : {
              lastCheckOutAt: updateData.timestamp,
              checkOutCount: { increment: 1 },
            }),
        ...(updateData.hasGeoAnomaly ? { hasGeoAnomaly: true } : {}),
        lastEventId: updateData.eventId,
      },
    });
  }
}
