#!/usr/bin/env tsx
/**
 * Feed Sync Cron Script
 * Run: npx tsx scripts/sync-feeds.ts
 *
 * Checks which feeds are due for sync and runs the pipeline for each.
 */

import 'dotenv/config';
import { getOverdueFeeds, syncFeed } from '../src/lib/feeds/sync-engine.js';
import { log, logError, getPool } from '../src/lib/feeds/db.js';

const MAX_CONCURRENT = 3;

async function main(): Promise<void> {
  log('=== Feed Sync Started ===');

  try {
    // Clean up stale running syncs (>60 min)
    const { query } = await import('../src/lib/feeds/db.js');
    await query(
      `UPDATE sync_logs SET status = 'failed', finished_at = NOW(),
       error_details = '["Timed out (stale lock)"]'::jsonb
       WHERE status = 'running' AND started_at < NOW() - INTERVAL '60 minutes'`
    );

    const feeds = await getOverdueFeeds();
    if (feeds.length === 0) {
      log('No feeds due for sync');
      return;
    }

    log(`Found ${feeds.length} feeds due for sync`);

    // Process feeds with limited concurrency
    const results: Array<{ feedId: number; name: string; success: boolean; error?: string }> = [];
    const queue = [...feeds];

    const worker = async () => {
      while (queue.length > 0) {
        const feed = queue.shift()!;
        try {
          log(`Starting sync: feed ${feed.id} (${feed.name})`);
          const stats = await syncFeed(feed.id);
          results.push({ feedId: feed.id, name: feed.name, success: true });
          log(`Completed: feed ${feed.id} — ${stats.fetched} products`);
        } catch (err: any) {
          results.push({ feedId: feed.id, name: feed.name, success: false, error: err.message });
          logError(`Failed: feed ${feed.id}`, err);
        }
      }
    };

    const workers = Array.from({ length: Math.min(MAX_CONCURRENT, feeds.length) }, () => worker());
    await Promise.all(workers);

    // Summary
    const succeeded = results.filter(r => r.success).length;
    const failed = results.filter(r => !r.success).length;
    log(`=== Sync Complete: ${succeeded} succeeded, ${failed} failed ===`);

    for (const r of results) {
      log(`  ${r.success ? '✓' : '✗'} ${r.name} (${r.feedId})${r.error ? ': ' + r.error : ''}`);
    }
  } catch (err: any) {
    logError('Fatal sync error', err);
    process.exit(1);
  } finally {
    const pool = getPool();
    await pool.end();
  }
}

main();
