import { InjectQueue } from '@nestjs/bullmq';
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import type { Queue } from 'bullmq';
import {
  LEGAJOS_QUEUE_NAME,
  LEGAJOS_VENCIMIENTO_JOB_NAME,
} from './legajos-vencimiento.processor';

const REPEAT_JOB_ID = 'legajos-vencimiento-diario';
const CRON_PATTERN = '0 9 * * *'; // diario a las 09:00

/**
 * Registra al boot el job repeatable diario que recalcula estados de vencimiento
 * y emite alertas escalonadas por email.
 *
 * También expone `runOnce()` para ejecutar manualmente (endpoint admin).
 */
@Injectable()
export class LegajosVencimientoSchedulerService implements OnModuleInit {
  private readonly logger = new Logger(LegajosVencimientoSchedulerService.name);

  constructor(
    @InjectQueue(LEGAJOS_QUEUE_NAME)
    private readonly queue: Queue<{ empresaId?: string }>,
  ) {}

  async onModuleInit() {
    try {
      const existentes = await this.queue.getRepeatableJobs();
      const ya = existentes.some(
        (j) => j.name === LEGAJOS_VENCIMIENTO_JOB_NAME && j.id === REPEAT_JOB_ID,
      );
      if (ya) {
        this.logger.debug('Job de vencimientos ya está registrado');
        return;
      }
      await this.queue.add(
        LEGAJOS_VENCIMIENTO_JOB_NAME,
        {},
        {
          jobId: REPEAT_JOB_ID,
          repeat: { pattern: CRON_PATTERN },
          removeOnComplete: 50,
          removeOnFail: 50,
        },
      );
      this.logger.log(`Job diario de vencimientos registrado (${CRON_PATTERN})`);
    } catch (err) {
      // Redis puede no estar disponible en tests / CI; no romper el boot por eso.
      this.logger.warn(
        `No se pudo registrar el job de vencimientos: ${err instanceof Error ? err.message : err}`,
      );
    }
  }

  /**
   * Encola una ejecución única del job (no remueve el repeatable).
   * Usado por el endpoint POST /rrhh/legajos/jobs/actualizar-estados-vencimiento.
   */
  async runOnce(empresaId?: string) {
    await this.queue.add(
      LEGAJOS_VENCIMIENTO_JOB_NAME,
      { empresaId },
      {
        jobId: `${LEGAJOS_VENCIMIENTO_JOB_NAME}:manual:${Date.now()}`,
        removeOnComplete: 10,
        removeOnFail: 20,
      },
    );
  }
}
