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

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

  async findAll(userId: string) {
    return this.prisma.dailyLearningActivity.findMany({
      where: { userId },
      orderBy: { activityDate: 'asc' },
    });
  }

  async findByDateRange(userId: string, from: Date, to: Date) {
    return this.prisma.dailyLearningActivity.findMany({
      where: { userId, activityDate: { gte: from, lte: to } },
      orderBy: { activityDate: 'asc' },
    });
  }

  /** M8: Upsert daily activity from reading event (within transaction, timezone-aware). */
  async upsertFromReadingEvent(tx: any, data: {
    userId: string;
    clientTimestampMs: bigint;
    clientTimezoneOffsetMinutes: number | null;
    activeSecondsDelta: number;
    isNewMaterial?: boolean;
    isMarkedRead?: boolean;
  }) {
    const activityDate = this.computeActivityDate(data.clientTimestampMs, data.clientTimezoneOffsetMinutes);
    const { userId, activeSecondsDelta, isNewMaterial, isMarkedRead } = data;

    return tx.dailyLearningActivity.upsert({
      where: { userId_activityDate: { userId, activityDate } },
      create: {
        userId,
        activityDate,
        durationSeconds: activeSecondsDelta,
        readingSeconds: activeSecondsDelta,
        materialsReadCount: isNewMaterial ? 1 : 0,
        markedReadCount: isMarkedRead ? 1 : 0,
      },
      update: {
        durationSeconds: { increment: activeSecondsDelta },
        readingSeconds: { increment: activeSecondsDelta },
        materialsReadCount: isNewMaterial ? { increment: 1 } : undefined,
        markedReadCount: isMarkedRead ? { increment: 1 } : undefined,
      },
    });
  }

  /** Compute local date from timestamp and timezone offset. */
  private computeActivityDate(timestampMs: bigint, offsetMinutes: number | null): Date {
    const offsetMs = (offsetMinutes ?? 0) * 60 * 1000;
    const localMs = Number(timestampMs) + offsetMs;
    const date = new Date(localMs);
    return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
  }
}
