import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

import { SecurityAuditLog } from './security-audit-log.entity';

export interface LogAccessData {
  action: string;
  adminId: string;
  adminEmail?: string;
  details: Record<string, unknown>;
}

/**
 * SecurityAuditLogService - Audit trail for security log access
 *
 * Every access to security IP logs is recorded here for compliance:
 * - Who accessed the data (admin ID and email)
 * - What query was performed (action type and parameters)
 * - When the access occurred (timestamp)
 *
 * This audit trail is essential for:
 * - Internal security audits
 * - Demonstrating compliance with data protection requests
 * - Investigating unauthorized access attempts
 */
@Injectable()
export class SecurityAuditLogService {
  private readonly logger = new Logger(SecurityAuditLogService.name);

  constructor(
    @InjectRepository(SecurityAuditLog)
    private readonly repo: Repository<SecurityAuditLog>,
  ) {}

  /**
   * Log an access to security IP data.
   *
   * Should be called from every controller method that queries IP logs.
   */
  async logAccess(data: LogAccessData): Promise<void> {
    try {
      const auditEntry = this.repo.create({
        action: data.action,
        adminId: data.adminId,
        adminEmail: data.adminEmail ?? null,
        details: data.details,
        timestamp: new Date(),
      });
      await this.repo.save(auditEntry);

      this.logger.log(`Security IP log access: ${data.action}`, {
        adminId: data.adminId,
        action: data.action,
      });
    } catch (error) {
      // Log the error but don't fail the main operation
      // Audit logging failure is serious but shouldn't block legitimate admin work
      this.logger.error('Failed to log security IP access audit', {
        error: error instanceof Error ? error.message : 'Unknown error',
        action: data.action,
        adminId: data.adminId,
      });
    }
  }

  /**
   * Get audit logs for a specific admin.
   *
   * Useful for investigating admin activity.
   */
  async findByAdminId(adminId: string): Promise<SecurityAuditLog[]> {
    return this.repo.find({
      where: { adminId },
      order: { timestamp: 'DESC' },
      take: 1000, // Limit to prevent excessive data retrieval
    });
  }

  /**
   * Get recent audit logs.
   *
   * Useful for monitoring dashboard.
   */
  async findRecent(limit = 100): Promise<SecurityAuditLog[]> {
    return this.repo.find({
      order: { timestamp: 'DESC' },
      take: limit,
    });
  }
}
