import { Queue, Worker, type Job } from 'bullmq';
import { env } from '../config/env';
import { logger } from '../utils/logger';
import { feedService } from '../modules/calendar/feed.service';

const QUEUE_NAME = 'calendar-feed-refresh';
const MAX_FEEDS_PER_CYCLE = 10;

class CalendarFeedQueueService {
  private queue: Queue;
  private worker: Worker | null = null;

  constructor() {
    this.queue = new Queue(QUEUE_NAME, {
      connection: { url: env.REDIS_URL },
      defaultJobOptions: {
        removeOnComplete: { age: 60 * 60, count: 100 },
        removeOnFail: { age: 24 * 60 * 60 },
      },
    });
  }

  startWorker() {
    // Add repeatable job: every 15 minutes
    this.queue.add(
      'refresh-cycle',
      {},
      {
        repeat: { every: 15 * 60 * 1000 },
        jobId: 'calendar-feed-refresh-cycle',
      }
    );

    this.worker = new Worker(
      QUEUE_NAME,
      async (_job: Job) => {
        const feeds = await feedService.getFeedsDueForRefresh(MAX_FEEDS_PER_CYCLE);

        if (feeds.length === 0) return;

        logger.debug(`Calendar feed refresh cycle: ${feeds.length} feeds due`);

        for (const feed of feeds) {
          try {
            await feedService.refreshFeed(feed.id);
          } catch (err) {
            const message = err instanceof Error ? err.message : 'Unknown error';
            logger.warn(`Feed refresh failed for ${feed.name}: ${message}`);
          }
        }
      },
      {
        connection: { url: env.REDIS_URL },
        concurrency: 1,
      }
    );

    this.worker.on('completed', (job) => {
      logger.debug(`Calendar feed refresh job ${job.id} completed`);
    });

    this.worker.on('failed', (job, err) => {
      logger.error(`Calendar feed refresh job ${job?.id} failed: ${err.message}`);
    });

    logger.info('Calendar feed queue worker started');
  }

  async close() {
    if (this.worker) {
      await this.worker.close();
    }
    await this.queue.close();
    logger.info('Calendar feed queue closed');
  }
}

export const calendarFeedQueueService = new CalendarFeedQueueService();
