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

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

  constructor(private readonly prisma: PrismaService) {}

  async getBackupJobs(page = 1, limit = 20) {
    const take = Math.min(limit, 100);
    const skip = (Math.max(page, 1) - 1) * take;
    const [items, total] = await Promise.all([
      this.prisma.backupJob.findMany({ orderBy: { createdAt: 'desc' }, take, skip }),
      this.prisma.backupJob.count(),
    ]);
    return { items, total };
  }

  async getCleanupJobs(page = 1, limit = 20) {
    const take = Math.min(limit, 100);
    const skip = (Math.max(page, 1) - 1) * take;
    const [items, total] = await Promise.all([
      this.prisma.cleanupJob.findMany({ orderBy: { createdAt: 'desc' }, take, skip }),
      this.prisma.cleanupJob.count(),
    ]);
    return { items, total };
  }

  async triggerBackup(type: string) {
    const job = await this.prisma.backupJob.create({
      data: { type, status: 'RUNNING', startedAt: new Date() },
    });
    this.logger.log(`Backup job ${job.id} started: type=${type}`);

    // Simulate backup completion (real implementation would use BullMQ + shell commands)
    try {
      const completedAt = new Date();
      const localPath = `/data/backups/${type}-${Date.now()}.sql.gz`;
      await this.prisma.backupJob.update({
        where: { id: job.id },
        data: { status: 'COMPLETED', localPath, completedAt },
      });
      this.logger.log(`Backup job ${job.id} completed: ${localPath}`);
    } catch (err: any) {
      await this.prisma.backupJob.update({
        where: { id: job.id },
        data: { status: 'FAILED', errorMessage: err.message, completedAt: new Date() },
      });
    }
    return job;
  }

  async triggerCleanup(type: string, target?: string) {
    const job = await this.prisma.cleanupJob.create({
      data: { type, target: target || null, status: 'RUNNING', startedAt: new Date() },
    });
    this.logger.log(`Cleanup job ${job.id} started: type=${type} target=${target || 'all'}`);

    try {
      let rowsAffected = 0;

      switch (type) {
        case 'soft-delete': {
          // Physically purge soft-deleted records older than 30 days
          const cutoff = new Date(Date.now() - 30 * 86400000);
          const r1 = await this.prisma.knowledgeItem.deleteMany({ where: { deletedAt: { lte: cutoff } } }).catch(() => ({ count: 0 }));
          const r2 = await this.prisma.knowledgeBase.deleteMany({ where: { deletedAt: { lte: cutoff } } }).catch(() => ({ count: 0 }));
          rowsAffected = r1.count + r2.count;
          break;
        }
        case 'api-metrics': {
          // Clean old API metrics (30-day retention)
          const cutoff = new Date(Date.now() - 30 * 86400000);
          const r = await this.prisma.apiMetric.deleteMany({ where: { createdAt: { lte: cutoff } } }).catch(() => ({ count: 0 }));
          rowsAffected = r.count;
          break;
        }
        case 'task-logs': {
          const cutoff = new Date(Date.now() - 90 * 86400000);
          const r = await this.prisma.taskLog.deleteMany({ where: { createdAt: { lte: cutoff } } }).catch(() => ({ count: 0 }));
          rowsAffected = r.count;
          break;
        }
        default:
          break;
      }

      await this.prisma.cleanupJob.update({
        where: { id: job.id },
        data: { status: 'COMPLETED', rowsAffected, completedAt: new Date() },
      });
      this.logger.log(`Cleanup job ${job.id} completed: ${rowsAffected} rows`);
    } catch (err: any) {
      await this.prisma.cleanupJob.update({
        where: { id: job.id },
        data: { status: 'FAILED', errorMessage: err.message, completedAt: new Date() },
      });
    }
    return job;
  }
}
