import * as schedule from 'node-schedule';
import { ScraperService } from './scraper-service';
import { ScrapeResult } from './types';

export type ScrapeCallback = (results: ScrapeResult[]) => Promise<void>;

export class ScraperScheduler {
  private scraperService: ScraperService;
  private job: schedule.Job | null = null;
  private callback: ScrapeCallback | null = null;
  private intervalMinutes: number;

  constructor(intervalMinutes: number = 5) {
    this.scraperService = new ScraperService();
    this.intervalMinutes = intervalMinutes;
  }

  onScrapeComplete(callback: ScrapeCallback): void {
    this.callback = callback;
  }

  start(): void {
    if (this.job) {
      console.log('Scheduler already running');
      return;
    }

    // Run immediately on start
    this.runScrape();

    // Schedule recurring scrapes
    const rule = `*/${this.intervalMinutes} * * * *`;
    this.job = schedule.scheduleJob(rule, () => {
      this.runScrape();
    });

    console.log(`Scraper scheduled to run every ${this.intervalMinutes} minutes`);
  }

  stop(): void {
    if (this.job) {
      this.job.cancel();
      this.job = null;
      console.log('Scraper scheduler stopped');
    }
  }

  async runScrape(): Promise<void> {
    try {
      console.log(`[${new Date().toISOString()}] Running scheduled scrape...`);
      
      const results = await this.scraperService.scrapeAll();
      
      const successCount = results.filter(r => r.success).length;
      const totalListings = results.reduce((sum, r) => sum + r.listings.length, 0);
      
      console.log(`Scrape complete: ${successCount}/${results.length} vendors successful, ${totalListings} listings`);
      
      if (this.callback) {
        await this.callback(results);
      }
    } catch (error) {
      console.error('Error during scheduled scrape:', error);
    }
  }

  setInterval(minutes: number): void {
    this.intervalMinutes = minutes;
    
    if (this.job) {
      this.stop();
      this.start();
    }
  }

  async close(): Promise<void> {
    this.stop();
    await this.scraperService.close();
  }
}
