#!/usr/bin/env node

import { loadEnvFile, loadSharedConfig, CHROME_UA, runSeed, sleep } from './_seed-utils.mjs';

const sectorsConfig = loadSharedConfig('crypto-sectors.json');

loadEnvFile(import.meta.url);

const CANONICAL_KEY = 'market:crypto-sectors:v1';
const CACHE_TTL = 3600;

const SECTORS = sectorsConfig.sectors;

async function fetchWithRateLimitRetry(url, maxAttempts = 5, headers = { Accept: 'application/json', 'User-Agent': CHROME_UA }) {
  for (let i = 0; i < maxAttempts; i++) {
    const resp = await fetch(url, { headers, signal: AbortSignal.timeout(15_000) });
    if (resp.status === 429) {
      const wait = Math.min(10_000 * (i + 1), 60_000);
      console.warn(`  CoinGecko 429 — waiting ${wait / 1000}s (attempt ${i + 1}/${maxAttempts})`);
      await sleep(wait);
      continue;
    }
    if (!resp.ok) throw new Error(`CoinGecko HTTP ${resp.status}`);
    return resp;
  }
  throw new Error('CoinGecko rate limit exceeded after retries');
}

async function fetchSectorData() {
  const allIds = [...new Set(SECTORS.flatMap(s => s.tokens))];

  const apiKey = process.env.COINGECKO_API_KEY;
  const baseUrl = apiKey ? 'https://pro-api.coingecko.com/api/v3' : 'https://api.coingecko.com/api/v3';
  const url = `${baseUrl}/coins/markets?vs_currency=usd&ids=${allIds.join(',')}&order=market_cap_desc&sparkline=false&price_change_percentage=24h`;
  const headers = { Accept: 'application/json', 'User-Agent': CHROME_UA };
  if (apiKey) headers['x-cg-pro-api-key'] = apiKey;

  const resp = await fetchWithRateLimitRetry(url, 5, headers);
  const data = await resp.json();
  if (!Array.isArray(data) || data.length === 0) throw new Error('CoinGecko returned no data');

  const byId = new Map(data.map(c => [c.id, c.price_change_percentage_24h]));

  const sectors = SECTORS.map(sector => {
    const changes = sector.tokens
      .map(id => byId.get(id))
      .filter(v => typeof v === 'number' && isFinite(v));
    const change = changes.length > 0 ? changes.reduce((a, b) => a + b, 0) / changes.length : 0;
    return { id: sector.id, name: sector.name, change };
  });

  return { sectors };
}

function validate(data) {
  return Array.isArray(data?.sectors) && data.sectors.length > 0;
}

export function declareRecords(data) {
  return Array.isArray(data?.sectors) ? data.sectors.length : 0;
}

runSeed('market', 'crypto-sectors', CANONICAL_KEY, fetchSectorData, {
  validateFn: validate,
  ttlSeconds: CACHE_TTL,
  sourceVersion: 'coingecko-sectors',

  declareRecords,
  schemaVersion: 1,
  maxStaleMin: 120,
}).catch(err => {
  const _cause = err.cause ? ` (cause: ${err.cause.message || err.cause.code || err.cause})` : '';
  console.error('FATAL:', (err.message || err) + _cause);
  process.exit(1);
});
