import { CatalogRecord } from '@/types/catalog';
import { db } from '@/db/client';
import { syncCatalog } from './catalog-sync-service';

/**
 * Calculates the next Date when a catalog should sync based on its schedule settings.
 */
export function calculateNextSyncDate(
  scheduleType: 'daily' | 'weekly' = 'daily',
  scheduleDay: string = 'Every Monday',
  scheduleHour: number = 2,
  schedulePeriod: 'AM' | 'PM' = 'AM',
  scheduleTz: string = 'UTC'
): string {
  const now = new Date();
  let targetHour = scheduleHour % 12;
  if (schedulePeriod === 'PM') targetHour += 12;

  const daysOfWeek = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
  const dayClean = scheduleDay.toLowerCase().replace('every ', '').trim();
  const targetDayIndex = daysOfWeek.indexOf(dayClean);

  const next = new Date(now);
  next.setHours(targetHour, 0, 0, 0);

  if (scheduleType === 'weekly' && targetDayIndex !== -1) {
    const currentDay = now.getDay();
    let daysUntil = (targetDayIndex - currentDay + 7) % 7;
    if (daysUntil === 0 && next <= now) {
      daysUntil = 7;
    }
    next.setDate(now.getDate() + daysUntil);
  } else {
    // Daily
    if (next <= now) {
      next.setDate(next.getDate() + 1);
    }
  }

  return next.toISOString();
}

/**
 * Background worker task to execute due scheduled catalog syncs.
 */
export async function runScheduledCatalogSyncs(): Promise<{ processed: number; errors: number }> {
  try {
    const dueCatalogs = await db.getDueScheduledCatalogs();
    if (!dueCatalogs || dueCatalogs.length === 0) {
      return { processed: 0, errors: 0 };
    }

    let processed = 0;
    let errors = 0;

    for (const catalog of dueCatalogs) {
      try {
        await syncCatalog(catalog.id);
        processed++;
      } catch (err) {
        console.error(`[Scheduler] Failed to sync catalog ${catalog.id}:`, err);
        errors++;
      }
    }

    return { processed, errors };
  } catch (err) {
    console.error('[Scheduler] Error running scheduled catalog syncs:', err);
    return { processed: 0, errors: 1 };
  }
}
