const { rpkiAspaMap } = require("../services/rpki");
const { fetchIpv6AdoptionStats } = require("../ipv6-adoption");
const {
  aspaAdoptionDailyHistory, getAdoptionTrend, buildAspaAdoptionDashboard,
} = require("../aspa-adoption/tracker");

// GET /aspa-adoption → dashboard HTML
function handleDashboard(req, res) {
  res.setHeader('Content-Type', 'text/html; charset=utf-8');
  res.writeHead(200);
  return res.end(buildAspaAdoptionDashboard());
}

// Linear regression forecast -- duplicated near-identically in
// buildAspaAdoptionDashboard (server/aspa-adoption/tracker.js) since both
// use the same formula over possibly-different trend windows; kept as two
// call sites rather than merged to avoid changing either's behavior here.
function forecast(data, daysAhead) {
  if (data.length < 2) return null;
  const n = data.length;
  const xs = data.map((_, i) => i);
  const ys = data.map(d => d.coverage_pct_atlas);
  const xMean = xs.reduce((a,b)=>a+b,0)/n;
  const yMean = ys.reduce((a,b)=>a+b,0)/n;
  const num = xs.reduce((s,x,i)=>s+(x-xMean)*(ys[i]-yMean),0);
  const den = xs.reduce((s,x)=>s+(x-xMean)**2,0);
  if (den===0) return yMean;
  const slope = num/den;
  return Math.max(0, Math.min(100, Math.round((yMean + slope*(n-1+daysAhead))*100)/100));
}

// GET /api/aspa-adoption-stats?period=7d|30d|1y
function handleStats(req, res, url) {
  const period   = ['7d','30d','90d','1y'].includes(url.searchParams.get('period'))
    ? url.searchParams.get('period') : '30d';
  const trend    = getAdoptionTrend(period);
  const latest   = aspaAdoptionDailyHistory[aspaAdoptionDailyHistory.length - 1];
  const prev     = aspaAdoptionDailyHistory[aspaAdoptionDailyHistory.length - 2];

  const trend30 = getAdoptionTrend('30d');
  const result = {
    period,
    current: {
      date: latest?.date,
      aspa_objects: latest?.aspa_objects ?? rpkiAspaMap.size,
      roa_count: latest?.roa_count,
      atlas_asns_total: latest?.atlas_asns_total ?? 0,
      atlas_asns_with_aspa: latest?.atlas_asns_with_aspa ?? 0,
      coverage_pct_atlas: latest?.coverage_pct_atlas ?? 0,
      delta_from_previous: prev ? (latest?.aspa_objects ?? 0) - prev.aspa_objects : 0,
    },
    trend: trend.map(s => ({
      date: s.date,
      aspa_objects: s.aspa_objects,
      coverage_pct_atlas: s.coverage_pct_atlas,
      atlas_asns_total: s.atlas_asns_total,
    })),
    forecast: {
      predicted_90d: forecast(trend30, 90),
      confidence: trend30.length >= 10 ? 0.75 : 0.5,
      method: 'linear_regression',
      based_on_samples: trend30.length,
    },
    meta: {
      total_snapshots: aspaAdoptionDailyHistory.length,
      last_updated: latest?.date ?? null,
      denominator: 'atlas_visible_asns',
      source: 'rpki_cloudflare_feed',
    }
  };
  res.setHeader('Content-Type', 'application/json');
  res.writeHead(200);
  return res.end(JSON.stringify(result, null, 2));
}

// GET /api/aspa-adoption-stats/export?format=csv|json&period=30d
function handleStatsExport(req, res, url) {
  const fmt    = url.searchParams.get('format') === 'csv' ? 'csv' : 'json';
  const period = ['7d','30d','90d','1y'].includes(url.searchParams.get('period'))
    ? url.searchParams.get('period') : '30d';
  const data   = getAdoptionTrend(period);

  if (fmt === 'csv') {
    const header = 'date,aspa_objects,roa_count,atlas_asns_total,atlas_asns_with_aspa,coverage_pct_atlas,aspa_delta\n';
    const rows   = data.map(s =>
      `${s.date},${s.aspa_objects},${s.roa_count},${s.atlas_asns_total},${s.atlas_asns_with_aspa},${s.coverage_pct_atlas},${s.aspa_delta??0}`
    ).join('\n');
    res.setHeader('Content-Type', 'text/csv');
    res.setHeader('Content-Disposition', `attachment; filename="peercortex-aspa-adoption-${period}.csv"`);
    res.writeHead(200);
    return res.end(header + rows);
  }

  res.setHeader('Content-Type', 'application/json');
  res.setHeader('Content-Disposition', `attachment; filename="peercortex-aspa-adoption-${period}.json"`);
  res.writeHead(200);
  return res.end(JSON.stringify({ period, count: data.length, data }, null, 2));
}

// GET /api/ipv6-adoption-stats?refresh=1
async function handleIpv6Stats(req, res, url) {
  const force = url.searchParams.get('refresh') === '1';
  try {
    const data = await fetchIpv6AdoptionStats(force);
    res.setHeader('Content-Type', 'application/json');
    res.writeHead(200);
    return res.end(JSON.stringify(data, null, 2));
  } catch (err) {
    res.writeHead(503);
    return res.end(JSON.stringify({ error: 'IPv6 stats unavailable', message: err.message }));
  }
}

module.exports = { handleDashboard, handleStats, handleStatsExport, handleIpv6Stats };
