const http = require("http");
const { buildPdfHtml, buildComparisonPdfHtml } = require("../pdf-export/templates");
const { renderHtmlToPdf, pdfCacheGet, pdfCacheSet } = require("../pdf-export/renderer");

const PORT = process.env.PORT || 3101;

// Fetch JSON from an internal endpoint on this same process (loopback) --
// re-triggers the full HTTP/caching/rate-limit path for /api/validate,
// /api/aspa, /api/lookup rather than calling their handler logic directly.
async function fetchInternal(path) {
  return new Promise((resolve, reject) => {
    const opts = { hostname: '127.0.0.1', port: PORT, path, method: 'GET' };
    const req2 = http.request(opts, res2 => {
      let body = '';
      res2.on('data', c => body += c);
      res2.on('end', () => {
        try { resolve(JSON.parse(body)); }
        catch(e) { reject(new Error('JSON parse failed: ' + body.slice(0, 200))); }
      });
    });
    req2.on('error', reject);
    req2.setTimeout(30000, () => { req2.destroy(); reject(new Error('Internal request timeout')); });
    req2.end();
  });
}

// GET /api/export/pdf?asn=X&format=report|executive|technical
async function handleExportPdf(req, res, url) {
  const rawAsn = (url.searchParams.get('asn') || '').replace(/[^0-9]/g, '');
  const format  = ['executive', 'technical', 'report'].includes(url.searchParams.get('format'))
    ? url.searchParams.get('format') : 'report';
  if (!rawAsn) {
    res.writeHead(400, {'Content-Type':'application/json'});
    return res.end(JSON.stringify({ error: 'Missing asn parameter' }));
  }
  const cacheKey = `pdf:${rawAsn}:${format}`;
  const cached   = pdfCacheGet(cacheKey);
  if (cached) {
    res.writeHead(200, { ...{'Content-Type':'application/json'}, 'Content-Type': 'application/pdf', 'Content-Disposition': `inline; filename="peercortex-AS${rawAsn}-${format}.pdf"`, 'X-Cache': 'HIT', 'Content-Length': cached.length });
    return res.end(cached);
  }
  try {
    const [validateData, aspaData] = await Promise.all([
      fetchInternal(`/api/validate?asn=${rawAsn}`),
      fetchInternal(`/api/aspa?asn=${rawAsn}`).catch(() => null),
    ]);
    if (validateData.error) {
      res.writeHead(400, {'Content-Type':'application/json'});
      return res.end(JSON.stringify({ error: validateData.error }));
    }
    const html = buildPdfHtml(validateData, aspaData, format);
    const pdfBuf = await renderHtmlToPdf(html);
    pdfCacheSet(cacheKey, pdfBuf);
    res.writeHead(200, { ...{'Content-Type':'application/json'}, 'Content-Type': 'application/pdf', 'Content-Disposition': `inline; filename="peercortex-AS${rawAsn}-${format}.pdf"`, 'Content-Length': pdfBuf.length });
    return res.end(pdfBuf);
  } catch (err) {
    console.error('[PDF] Error:', err.message);
    res.writeHead(503, {'Content-Type':'application/json'});
    return res.end(JSON.stringify({ error: 'PDF generation failed', message: err.message }));
  }
}

// GET /api/export/pdf/compare?asn1=X&asn2=Y
async function handleExportPdfCompare(req, res, url) {
  const asn1 = (url.searchParams.get('asn1') || '').replace(/[^0-9]/g, '');
  const asn2 = (url.searchParams.get('asn2') || '').replace(/[^0-9]/g, '');
  if (!asn1 || !asn2) {
    res.writeHead(400, {'Content-Type':'application/json'});
    return res.end(JSON.stringify({ error: 'Missing asn1 or asn2 parameter' }));
  }
  if (asn1 === asn2) {
    res.writeHead(400, {'Content-Type':'application/json'});
    return res.end(JSON.stringify({ error: 'asn1 and asn2 must be different' }));
  }
  const cacheKey = `pdf:compare:${Math.min(+asn1,+asn2)}:${Math.max(+asn1,+asn2)}`;
  const cached   = pdfCacheGet(cacheKey);
  if (cached) {
    res.writeHead(200, { ...{'Content-Type':'application/json'}, 'Content-Type': 'application/pdf', 'Content-Disposition': `inline; filename="peercortex-AS${asn1}-vs-AS${asn2}.pdf"`, 'X-Cache': 'HIT', 'Content-Length': cached.length });
    return res.end(cached);
  }
  try {
    const [v1, a1, l1, v2, a2, l2] = await Promise.all([
      fetchInternal(`/api/validate?asn=${asn1}`),
      fetchInternal(`/api/aspa?asn=${asn1}`).catch(() => null),
      fetchInternal(`/api/lookup?asn=${asn1}`).catch(() => null),
      fetchInternal(`/api/validate?asn=${asn2}`),
      fetchInternal(`/api/aspa?asn=${asn2}`).catch(() => null),
      fetchInternal(`/api/lookup?asn=${asn2}`).catch(() => null),
    ]);
    if (v1.error || v2.error) {
      res.writeHead(400, {'Content-Type':'application/json'});
      return res.end(JSON.stringify({ error: v1.error || v2.error }));
    }
    const html = buildComparisonPdfHtml(v1, a1, l1, v2, a2, l2);
    const pdfBuf = await renderHtmlToPdf(html);
    pdfCacheSet(cacheKey, pdfBuf);
    res.writeHead(200, { ...{'Content-Type':'application/json'}, 'Content-Type': 'application/pdf', 'Content-Disposition': `inline; filename="peercortex-AS${asn1}-vs-AS${asn2}.pdf"`, 'Content-Length': pdfBuf.length });
    return res.end(pdfBuf);
  } catch (err) {
    console.error('[PDF] Error:', err.message);
    res.writeHead(503, {'Content-Type':'application/json'});
    return res.end(JSON.stringify({ error: 'PDF generation failed', message: err.message }));
  }
}

// CORS preflight for PDF export (already handled globally above, belt-and-suspenders)
function handleExportOptions(req, res) {
  res.writeHead(204);
  return res.end();
}

module.exports = { handleExportPdf, handleExportPdfCompare, handleExportOptions };
