import { discoverMissingMtgSets, discoverMissingPokemonSets } from './discover.js';
import { importMtgSet } from './mtg.js';
import { importPokemonSet } from './pokemon.js';
import { reconcileSubmissionsForImportedSet } from './reconcile-submissions.js';

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const DEFAULT_MAX_SETS_PER_RUN = 3;
const DEFAULT_DELAY_MS = 1500;

/**
 * Merge missing MTG + Pokémon sets and pick the newest releases first.
 */
export function buildCatalogSyncQueue(missingMtg, missingPokemon, maxSetsPerRun = DEFAULT_MAX_SETS_PER_RUN) {
  const queue = [
    ...missingMtg.map((set) => ({
      game: 'mtg',
      setCode: set.code,
      name: set.name,
      releasedAt: set.releasedAt,
    })),
    ...missingPokemon.map((set) => ({
      game: 'pokemon',
      setCode: set.id,
      name: set.name,
      releasedAt: set.releasedAt,
    })),
  ];

  queue.sort((a, b) => {
    const dateA = a.releasedAt || '';
    const dateB = b.releasedAt || '';
    if (!dateA && !dateB) return 0;
    if (!dateA) return 1;
    if (!dateB) return -1;
    return dateB.localeCompare(dateA);
  });

  return queue.slice(0, maxSetsPerRun);
}

/**
 * Discover missing MTG + Pokémon sets and import up to maxSetsPerRun, paced for upstream APIs.
 */
export async function runCatalogSync(options = {}) {
  const maxSetsPerRun = options.maxSetsPerRun ?? DEFAULT_MAX_SETS_PER_RUN;
  const delayBetweenSetsMs = options.delayBetweenSetsMs ?? DEFAULT_DELAY_MS;

  const [missingMtg, missingPokemon] = await Promise.all([
    discoverMissingMtgSets(),
    discoverMissingPokemonSets(),
  ]);

  const queue = buildCatalogSyncQueue(missingMtg, missingPokemon, maxSetsPerRun);

  const summary = {
    imported: 0,
    skipped: 0,
    errors: [],
    setsProcessed: [],
    pendingMtgSets: missingMtg.length,
    pendingPokemonSets: missingPokemon.length,
    lorcana: 'skipped — manual Lorcana set map update required',
    submissionsReconciled: 0,
    reconciliation: [],
  };

  for (let index = 0; index < queue.length; index += 1) {
    const item = queue[index];
    try {
      const result =
        item.game === 'mtg'
          ? await importMtgSet(item.setCode)
          : await importPokemonSet(item.setCode);

      summary.setsProcessed.push({
        game: item.game,
        setCode: item.setCode,
        name: item.name,
        ...result,
      });
      summary.imported += result.imported;
      summary.skipped += result.skipped;

      const reconcileResult = await reconcileSubmissionsForImportedSet({
        game: item.game,
        setCode: item.setCode,
        setName: item.name,
      });
      summary.submissionsReconciled += reconcileResult.matched;
      if (reconcileResult.matched > 0 || reconcileResult.skipped > 0) {
        summary.reconciliation.push(reconcileResult);
      }
    } catch (error) {
      console.error(`[runCatalogSync] Failed ${item.game}/${item.setCode}:`, error);
      summary.errors.push({
        game: item.game,
        setCode: item.setCode,
        message: error.message,
      });
    }

    if (index < queue.length - 1) {
      await delay(delayBetweenSetsMs);
    }
  }

  console.log('[runCatalogSync]', JSON.stringify(summary));
  return summary;
}
