import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { Cron, CronExpression, SchedulerRegistry } from '@nestjs/schedule';
import { CronJob } from 'cron';
import { createLogger } from '@core/observability/logging/config/winston.config';
import { OutlookSyncService } from './outlook-sync.service';

const logger = createLogger('MeetingAttendanceOutlookSyncSchedulerService');

@Injectable()
export class OutlookSyncSchedulerService implements OnModuleInit, OnModuleDestroy {
  private readonly reconcileJobName = 'meeting-attendance-outlook-reconcile';

  constructor(
    private readonly schedulerRegistry: SchedulerRegistry,
    private readonly outlookSyncService: OutlookSyncService,
  ) {}

  async onModuleInit() {
    await this.reloadReconcileJob();
  }

  onModuleDestroy() {
    try {
      this.schedulerRegistry.deleteCronJob(this.reconcileJobName);
    } catch {
      // ignore
    }
  }

  async reloadReconcileJob() {
    try {
      this.schedulerRegistry.deleteCronJob(this.reconcileJobName);
    } catch {
      // ignore first load
    }

    const settings = await this.outlookSyncService.getSettings();
    const expression = settings.reconcileCron || '0 */2 * * *';

    const job = new CronJob(expression, async () => {
      try {
        await this.outlookSyncService.reconcileAllEnabledMailboxes();
      } catch (error) {
        logger.error(`Scheduled reconcile failed: ${String(error)}`);
      }
    });
    this.schedulerRegistry.addCronJob(this.reconcileJobName, job);
    job.start();
    logger.log(`Outlook reconcile cron job started with expression: ${expression}`);
  }

  @Cron(CronExpression.EVERY_30_MINUTES)
  async renewSubscriptionsTask() {
    try {
      await this.outlookSyncService.renewSubscriptionsIfNeeded();
    } catch (error) {
      logger.error(`Renew subscriptions task failed: ${String(error)}`);
    }
  }

  @Cron('*/3 * * * *')
  async deltaPollTask() {
    try {
      await this.outlookSyncService.syncAllEnabledMailboxesDelta();
    } catch (error) {
      logger.error(`Delta poll task failed: ${String(error)}`);
    }
  }
}
