/**
 * WS2: Automated Datasheet Generation
 *
 * Generates professional PDF datasheets for transceivers and switches.
 * Uses HTML templates rendered via the dashboard's static serving.
 * Returns structured HTML that can be printed to PDF client-side or via Puppeteer.
 */
import { Router } from "express";
import { pool } from "../db/client";

export const datasheetRouter = Router();

/**
 * GET /api/datasheets/transceiver/:id
 * Returns structured datasheet data for a transceiver (JSON or HTML)
 */
datasheetRouter.get("/transceiver/:id", async (req, res) => {
  try {
    const { format = "json" } = req.query;
    const id = req.params.id;

    // Get transceiver with full details
    const t = await pool.query(
      `SELECT t.*, v.name AS vendor_name, v.website AS vendor_website, v.logo_r2_key,
              s.name AS standard_full_name, s.ieee_reference, s.year_ratified
       FROM transceivers t
       LEFT JOIN vendors v ON t.vendor_id = v.id
       LEFT JOIN standards s ON t.standard_id = s.id
       WHERE t.slug = $1 OR t.id::text = $1`,
      [id]
    );

    if (!t.rows[0]) return res.status(404).json({ error: "Transceiver not found" });
    const product = t.rows[0];

    // Get compatible switches (top 30)
    const compat = await pool.query(
      `SELECT sw.model, sw.series, sv.name AS vendor, c.firmware_min, c.verified_by
       FROM compatibility c
       JOIN switches sw ON c.switch_id = sw.id
       JOIN vendors sv ON sw.vendor_id = sv.id
       WHERE c.transceiver_id = $1 AND c.status = 'compatible'
       ORDER BY sv.name, sw.model LIMIT 30`,
      [product.id]
    );

    // Get latest prices from multiple vendors
    const prices = await pool.query(
      `SELECT DISTINCT ON (sv.name)
        sv.name AS vendor, po.price, po.currency, po.stock_level, po.url, po.time
       FROM price_observations po
       JOIN vendors sv ON po.source_vendor_id = sv.id
       WHERE po.transceiver_id = $1
       ORDER BY sv.name, po.time DESC`,
      [product.id]
    );

    // Power budget calculation
    const txPowerMin = product.tx_power_min_dbm ? parseFloat(product.tx_power_min_dbm) : null;
    const txPowerMax = product.tx_power_max_dbm ? parseFloat(product.tx_power_max_dbm) : null;
    const rxSensitivity = product.rx_sensitivity_dbm ? parseFloat(product.rx_sensitivity_dbm) : null;
    const opticalBudget = product.optical_budget_db ? parseFloat(product.optical_budget_db) : null;
    let powerBudget = null;
    if (txPowerMin !== null && rxSensitivity !== null) {
      const budget = txPowerMin - rxSensitivity;
      const connectorLoss = 0.5; // 2 connectors × 0.25 dB
      const spliceLoss = 0.1;
      const fiberLoss = product.fiber_type === 'SMF'
        ? (product.reach_meters / 1000) * 0.35 // 0.35 dB/km at 1310nm
        : (product.reach_meters / 1000) * 3.5;  // 3.5 dB/km at 850nm MMF
      const margin = budget - fiberLoss - connectorLoss - spliceLoss;
      powerBudget = {
        tx_power_min_dbm: txPowerMin,
        tx_power_max_dbm: txPowerMax,
        rx_sensitivity_dbm: rxSensitivity,
        link_budget_db: Math.round(budget * 10) / 10,
        fiber_loss_db: Math.round(fiberLoss * 10) / 10,
        connector_loss_db: connectorLoss,
        splice_loss_db: spliceLoss,
        margin_db: Math.round(margin * 10) / 10,
        sufficient: margin >= 3,
      };
    }

    const datasheet = {
      product: {
        slug: product.slug,
        part_number: product.part_number,
        vendor: product.vendor_name,
        standard: product.standard_full_name || product.standard_name,
        ieee_reference: product.ieee_reference,
        form_factor: product.form_factor,
        speed: product.speed,
        speed_gbps: parseFloat(product.speed_gbps),
        lanes: product.lanes,
        lane_rate: product.lane_rate,
        modulation: product.modulation,
        reach_label: product.reach_label,
        reach_meters: product.reach_meters,
        fiber_type: product.fiber_type,
        wavelengths: product.wavelengths,
        connector: product.connector,
        power_consumption_w: product.power_consumption_w ? parseFloat(product.power_consumption_w) : null,
        temp_range: product.temp_range,
        dom_support: product.dom_support,
        category: product.category,
        market_status: product.market_status,
        image_url: product.image_url,
      },
      optical: powerBudget,
      wdm: product.wdm_type ? {
        type: product.wdm_type,
        channels: product.channel_count,
        spacing_ghz: product.channel_spacing_ghz ? parseFloat(product.channel_spacing_ghz) : null,
        tunable: product.tunable,
        itu_grid: product.itu_grid,
      } : null,
      coherent: product.coherent ? {
        baud_rate_gbaud: product.baud_rate_gbaud ? parseFloat(product.baud_rate_gbaud) : null,
        fec_type: product.fec_type,
        dsp_vendor: product.dsp_vendor,
      } : null,
      compatible_switches: compat.rows,
      pricing: prices.rows.map(p => ({
        vendor: p.vendor,
        price: parseFloat(p.price),
        currency: p.currency,
        stock: p.stock_level,
        url: p.url,
        as_of: p.time,
      })),
      flexoptix: {
        buy_url: `https://www.flexoptix.net/en/catalogsearch/result/?q=${encodeURIComponent(product.form_factor + ' ' + product.speed_gbps + 'G ' + product.reach_label)}`,
        flexbox_note: "Flexoptix transceivers support FlexBox coding — one module works in any vendor's switch.",
      },
      generated_at: new Date().toISOString(),
    };

    if (format === "html") {
      res.setHeader("Content-Type", "text/html");
      res.send(renderDatasheetHtml(datasheet));
    } else {
      res.json(datasheet);
    }
  } catch (err) {
    console.error("Datasheet error:", err);
    res.status(500).json({ error: "Internal server error" });
  }
});

/**
 * GET /api/datasheets/switch/:id
 */
datasheetRouter.get("/switch/:id", async (req, res) => {
  try {
    const id = req.params.id;

    const sw = await pool.query(
      `SELECT sw.*, v.name AS vendor_name, v.website AS vendor_website
       FROM switches sw JOIN vendors v ON sw.vendor_id = v.id
       WHERE sw.model = $1 OR sw.id::text = $1`,
      [id]
    );
    if (!sw.rows[0]) return res.status(404).json({ error: "Switch not found" });
    const device = sw.rows[0];

    const compat = await pool.query(
      `SELECT t.form_factor, t.speed, t.speed_gbps, t.reach_label, t.fiber_type,
              tv.name AS transceiver_vendor, c.firmware_min
       FROM compatibility c
       JOIN transceivers t ON c.transceiver_id = t.id
       JOIN vendors tv ON t.vendor_id = tv.id
       WHERE c.switch_id = $1 AND c.status = 'compatible'
       ORDER BY t.speed_gbps DESC, tv.name LIMIT 50`,
      [device.id]
    );

    const docs = await pool.query(
      `SELECT doc_type, title, source_url FROM product_documents WHERE switch_id = $1 ORDER BY doc_type`,
      [device.id]
    );

    res.json({
      switch: {
        model: device.model,
        series: device.series,
        vendor: device.vendor_name,
        category: device.category,
        ports_config: device.ports_config,
        total_ports: device.total_ports,
        max_speed_gbps: device.max_speed_gbps,
        switching_capacity_tbps: device.switching_capacity_tbps,
        asic: device.asic_vendor ? `${device.asic_vendor} ${device.asic_model || ''}`.trim() : null,
        sonic_compatible: device.sonic_compatible,
        image_url: device.image_url,
      },
      compatible_transceivers: compat.rows,
      documents: docs.rows,
      generated_at: new Date().toISOString(),
    });
  } catch (err) {
    console.error("Switch datasheet error:", err);
    res.status(500).json({ error: "Internal server error" });
  }
});

/**
 * GET /api/datasheets/list — recently generated datasheets
 */
datasheetRouter.get("/list", async (_req, res) => {
  try {
    const result = await pool.query(
      `SELECT * FROM generated_datasheets ORDER BY generated_at DESC LIMIT 50`
    );
    res.json({ datasheets: result.rows });
  } catch (err) {
    res.status(500).json({ error: "Internal server error" });
  }
});

function renderDatasheetHtml(ds: any): string {
  const p = ds.product;
  const prices = ds.pricing.map((pr: any) => `<tr><td>${pr.vendor}</td><td>${pr.currency} ${pr.price.toFixed(2)}</td><td>${pr.stock || 'N/A'}</td></tr>`).join('');
  const switches = ds.compatible_switches.map((s: any) => `<tr><td>${s.vendor}</td><td>${s.model}</td><td>${s.firmware_min || 'Any'}</td></tr>`).join('');

  return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${p.form_factor} ${p.speed} ${p.reach_label} — Datasheet | TIP</title>
<style>
  @import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&display=swap');
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { font-family: 'DM Sans', sans-serif; color: #333; background: #fff; max-width: 210mm; margin: 0 auto; padding: 20mm; }
  .header { display: flex; justify-content: space-between; align-items: center; border-bottom: 3px solid #FF6600; padding-bottom: 16px; margin-bottom: 24px; }
  .header h1 { font-size: 24px; font-weight: 700; }
  .header .badge { background: #FF6600; color: white; padding: 4px 12px; border-radius: 12px; font-size: 12px; font-weight: 600; }
  .section { margin-bottom: 20px; }
  .section h2 { font-size: 16px; font-weight: 600; color: #FF6600; margin-bottom: 8px; border-bottom: 1px solid #eee; padding-bottom: 4px; }
  table { width: 100%; border-collapse: collapse; font-size: 13px; }
  th, td { padding: 6px 10px; text-align: left; border-bottom: 1px solid #f0f0f0; }
  th { background: #f8f8f8; font-weight: 600; }
  .specs-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .spec-item { display: flex; justify-content: space-between; padding: 4px 0; border-bottom: 1px solid #f5f5f5; font-size: 13px; }
  .spec-label { color: #888; }
  .spec-value { font-weight: 600; }
  .power-budget { background: #f8f9fa; padding: 12px; border-radius: 8px; font-size: 13px; }
  .power-budget .ok { color: #2d6a4f; } .power-budget .warn { color: #c1121f; }
  .footer { margin-top: 30px; padding-top: 12px; border-top: 2px solid #FF6600; font-size: 11px; color: #888; display: flex; justify-content: space-between; }
  .cta { background: #FF6600; color: white; padding: 10px 20px; border-radius: 8px; text-decoration: none; font-weight: 600; display: inline-block; margin-top: 12px; }
  @media print { body { padding: 10mm; } }
</style>
</head>
<body>
  <div class="header">
    <div>
      <h1>${p.form_factor} ${p.speed} ${p.reach_label}</h1>
      <p style="color:#888;font-size:14px">${p.standard || ''} ${p.ieee_reference ? '(' + p.ieee_reference + ')' : ''}</p>
    </div>
    <div class="badge">${p.market_status || 'Active'}</div>
  </div>

  ${p.image_url ? `<div style="text-align:center;margin-bottom:20px"><img src="${p.image_url}" alt="${p.form_factor}" style="max-height:120px;border-radius:8px"></div>` : ''}

  <div class="section">
    <h2>Specifications</h2>
    <div class="specs-grid">
      <div class="spec-item"><span class="spec-label">Form Factor</span><span class="spec-value">${p.form_factor}</span></div>
      <div class="spec-item"><span class="spec-label">Speed</span><span class="spec-value">${p.speed} (${p.speed_gbps} Gbps)</span></div>
      <div class="spec-item"><span class="spec-label">Reach</span><span class="spec-value">${p.reach_label} (${p.reach_meters >= 1000 ? (p.reach_meters/1000) + ' km' : p.reach_meters + ' m'})</span></div>
      <div class="spec-item"><span class="spec-label">Fiber</span><span class="spec-value">${p.fiber_type || 'N/A'}</span></div>
      <div class="spec-item"><span class="spec-label">Connector</span><span class="spec-value">${p.connector || 'N/A'}</span></div>
      <div class="spec-item"><span class="spec-label">Wavelength</span><span class="spec-value">${p.wavelengths || 'N/A'}</span></div>
      ${p.lanes ? `<div class="spec-item"><span class="spec-label">Lanes</span><span class="spec-value">${p.lanes}× ${p.lane_rate || ''}</span></div>` : ''}
      ${p.modulation ? `<div class="spec-item"><span class="spec-label">Modulation</span><span class="spec-value">${p.modulation}</span></div>` : ''}
      <div class="spec-item"><span class="spec-label">Power</span><span class="spec-value">${p.power_consumption_w ? p.power_consumption_w + ' W' : 'N/A'}</span></div>
      <div class="spec-item"><span class="spec-label">Temperature</span><span class="spec-value">${p.temp_range === 'COM' ? '0°C to 70°C (Commercial)' : '-40°C to 85°C (Industrial)'}</span></div>
    </div>
  </div>

  ${ds.optical ? `
  <div class="section">
    <h2>Power Budget</h2>
    <div class="power-budget">
      TX Power: ${ds.optical.tx_power_min_dbm} to ${ds.optical.tx_power_max_dbm} dBm |
      RX Sensitivity: ${ds.optical.rx_sensitivity_dbm} dBm |
      Link Budget: ${ds.optical.link_budget_db} dB |
      Fiber Loss: ${ds.optical.fiber_loss_db} dB |
      <strong class="${ds.optical.sufficient ? 'ok' : 'warn'}">Margin: ${ds.optical.margin_db} dB ${ds.optical.sufficient ? '✓' : '⚠ INSUFFICIENT'}</strong>
    </div>
  </div>` : ''}

  ${prices ? `
  <div class="section">
    <h2>Current Pricing</h2>
    <table><tr><th>Vendor</th><th>Price</th><th>Stock</th></tr>${prices}</table>
  </div>` : ''}

  ${switches ? `
  <div class="section">
    <h2>Compatible Switches (${ds.compatible_switches.length})</h2>
    <table><tr><th>Vendor</th><th>Model</th><th>Min Firmware</th></tr>${switches}</table>
  </div>` : ''}

  <div class="section">
    <a class="cta" href="${ds.flexoptix.buy_url}">Buy at Flexoptix →</a>
    <p style="font-size:12px;color:#888;margin-top:8px">${ds.flexoptix.flexbox_note}</p>
  </div>

  <div class="footer">
    <span>Generated by Transceiver Intelligence Platform (TIP) v0.2.0</span>
    <span>${ds.generated_at}</span>
  </div>
</body>
</html>`;
}
