import { Injectable, Logger } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';

export interface AuditLogEntry {
  shareId: bigint;
  userId: bigint;
  action: 'STORE' | 'RETRIEVE' | 'REVOKE' | 'ROTATE';
  sourceService: string;
  sourceIp: string;
  success: boolean;
  errorMessage?: string;
}

@Injectable()
export class AuditLogRepository {
  private readonly logger = new Logger(AuditLogRepository.name);

  constructor(private readonly prisma: PrismaService) {}

  async log(entry: AuditLogEntry): Promise<void> {
    try {
      await this.prisma.shareAccessLog.create({
        data: {
          shareId: entry.shareId,
          userId: entry.userId,
          action: entry.action,
          sourceService: entry.sourceService,
          sourceIp: entry.sourceIp,
          success: entry.success,
          errorMessage: entry.errorMessage,
        },
      });
      this.logger.debug(
        `Audit log created: ${entry.action} for share ${entry.shareId}`,
      );
    } catch (error) {
      this.logger.error(`Failed to create audit log: ${error.message}`);
      // Don't throw - audit log failures shouldn't affect main operations
    }
  }

  async findByShareId(shareId: bigint, limit = 100) {
    return this.prisma.shareAccessLog.findMany({
      where: { shareId },
      orderBy: { createdAt: 'desc' },
      take: limit,
    });
  }

  async findByUserId(userId: bigint, limit = 100) {
    return this.prisma.shareAccessLog.findMany({
      where: { userId },
      orderBy: { createdAt: 'desc' },
      take: limit,
    });
  }

  async countRetrievesByUserToday(userId: bigint): Promise<number> {
    const startOfDay = new Date();
    startOfDay.setHours(0, 0, 0, 0);

    return this.prisma.shareAccessLog.count({
      where: {
        userId,
        action: 'RETRIEVE',
        createdAt: { gte: startOfDay },
      },
    });
  }
}
