import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

import { DataRetentionService, type CleanupResult } from './data-retention.service';

/**
 * Data Retention Cron Job
 *
 * Executes GDPR-compliant data retention policies on a daily schedule.
 * Runs at 3:00 AM UTC to minimize impact on production traffic.
 *
 * Schedule:
 * - Daily execution: 3:00 AM UTC
 * - Low-traffic window to minimize database load
 *
 * Monitoring:
 * - Logs execution results for audit trail
 * - Reports errors for alerting
 * - Tracks deletion/anonymization counts
 */
@Injectable()
export class DataRetentionCron {
  private readonly logger = new Logger(DataRetentionCron.name);

  constructor(private readonly dataRetentionService: DataRetentionService) {}

  /**
   * Execute data retention policies daily at 3:00 AM UTC.
   */
  @Cron(CronExpression.EVERY_DAY_AT_3AM, {
    name: 'data-retention-cleanup',
    timeZone: 'UTC',
  })
  async handleDataRetentionCleanup(): Promise<void> {
    this.logger.log('Starting scheduled data retention cleanup');
    const startTime = Date.now();

    try {
      const results = await this.dataRetentionService.executeAllPolicies();

      const totalDeleted = results.reduce((sum, r) => sum + r.deletedCount, 0);
      const totalAnonymized = results.reduce(
        (sum, r) => sum + (r.anonymizedCount || 0),
        0,
      );
      const totalDuration = Date.now() - startTime;

      this.logger.log(
        `Data retention cleanup completed in ${totalDuration}ms: ${totalDeleted} deleted, ${totalAnonymized} anonymized`,
      );

      // Log individual policy results
      for (const result of results) {
        if (result.errors && result.errors.length > 0) {
          this.logger.error(
            `Policy "${result.policy}" failed: ${result.errors.join(', ')}`,
          );
        } else {
          const anonymizedInfo = result.anonymizedCount
            ? `, ${result.anonymizedCount} anonymized`
            : '';
          this.logger.log(
            `Policy "${result.policy}": ${result.deletedCount} deleted${anonymizedInfo} (${result.durationMs}ms)`,
          );
        }
      }

      // Log warnings for high deletion counts
      const highDeletionThreshold = 10000;
      for (const result of results) {
        if (result.deletedCount > highDeletionThreshold) {
          this.logger.warn(
            `High deletion count for "${result.policy}": ${result.deletedCount} records deleted`,
          );
        }
      }
    } catch (error) {
      const errorMessage =
        error instanceof Error ? error.message : 'Unknown error';
      this.logger.error(
        `Data retention cleanup failed: ${errorMessage}`,
        error instanceof Error ? error.stack : undefined,
      );
      throw error;
    }
  }

  /**
   * Manual trigger for data retention cleanup.
   */
  async triggerManualCleanup(): Promise<CleanupResult[]> {
    this.logger.log('Manual data retention cleanup triggered');
    return this.dataRetentionService.executeAllPolicies();
  }

  /**
   * Get summary of last scheduled execution.
   */
  getLastExecutionSummary() {
    return this.dataRetentionService.getLastExecutionSummary();
  }

  /**
   * Get full audit log of retention operations.
   */
  getAuditLog() {
    return this.dataRetentionService.getAuditLog();
  }
}
