/**
 * Hype Cycle API routes
 *
 * GET /api/hype-cycle              — All technologies with current phase
 * GET /api/hype-cycle/enriched     — All technologies with data-driven metrics
 * GET /api/hype-cycle/lifecycle    — Revenue lifecycle predictions for all speeds
 * GET /api/hype-cycle/regional/:tech — Regional adoption model for a technology
 * GET /api/hype-cycle/:tech        — Specific technology with 5-year forecast
 */
import { Router, Request, Response } from "express";
import {
  computeAllHypeCycles,
  computeHypeCycle,
  findTechnology,
  TECH_GENERATIONS,
  SPECIAL_TECHS,
} from "../hype-cycle/norton-bass";
import {
  getDataDrivenOverrides,
  getSpeedClassMetrics,
  computeRevenueLifecycle,
  computeRegionalAdoption,
} from "../hype-cycle/data-enrichment";

export const hypeCycleRouter = Router();

const q = (p: string, req: Request): string | undefined =>
  req.query[p] ? String(req.query[p]) : undefined;

// GET /api/hype-cycle — All technologies (model-only, fast)
hypeCycleRouter.get("/", (_req: Request, res: Response) => {
  const yearParam = q("year", _req);
  const year = yearParam ? parseInt(yearParam) : new Date().getFullYear();

  const results = computeAllHypeCycles(year);
  const sorted = [...results].sort((a, b) => a.positionPct - b.positionPct);

  res.json({
    success: true,
    year,
    model: "Norton-Bass Multigenerational Diffusion",
    technologies: sorted.map((r) => ({
      technology: r.technology,
      phase: r.phaseLabel,
      positionPct: r.positionPct,
      adoptionPct: r.adoptionPct,
      compositeScore: r.compositeScore,
      peakYear: r.forecast.peakShipmentYear,
      yearsToPlateauFromNow: r.forecast.yearsToPlateauFromNow,
    })),
  });
});

// GET /api/hype-cycle/enriched — Data-driven enrichment from scraped data
hypeCycleRouter.get("/enriched", async (_req: Request, res: Response) => {
  try {
    const yearParam = q("year", _req);
    const year = yearParam ? parseInt(yearParam) : new Date().getFullYear();

    const overridesMap = await getDataDrivenOverrides();
    const allTechs = [...TECH_GENERATIONS, ...SPECIAL_TECHS];

    const results = allTechs.map((tech) => {
      const overrides = overridesMap.get(tech.speedGbps);
      return computeHypeCycle(tech, year, overrides);
    });

    const sorted = [...results].sort((a, b) => a.positionPct - b.positionPct);

    // Also include raw metrics for transparency
    const speedMetrics = await getSpeedClassMetrics();

    res.json({
      success: true,
      year,
      model: "Norton-Bass + Data-Driven Enrichment",
      dataSource: {
        totalTransceivers: speedMetrics.reduce((s, m) => s + m.skuCount, 0),
        totalPricePoints: speedMetrics.reduce((s, m) => s + m.priceCount, 0),
        speedClasses: speedMetrics.length,
      },
      technologies: sorted.map((r) => ({
        technology: r.technology,
        phase: r.phaseLabel,
        positionPct: r.positionPct,
        adoptionPct: r.adoptionPct,
        compositeScore: r.compositeScore,
        peakYear: r.forecast.peakShipmentYear,
        yearsToPlateauFromNow: r.forecast.yearsToPlateauFromNow,
        metrics: r.metrics,
        fiveYearForecast: r.forecast.fiveYearProjection,
      })),
      rawSpeedMetrics: speedMetrics.map((m) => ({
        speedGbps: m.speedGbps,
        vendorCount: m.vendorCount,
        skuCount: m.skuCount,
        avgPrice: m.avgPrice ? Math.round(m.avgPrice * 100) / 100 : null,
        minPrice: m.minPrice ? Math.round(m.minPrice * 100) / 100 : null,
        maxPrice: m.maxPrice ? Math.round(m.maxPrice * 100) / 100 : null,
        formFactors: m.formFactors,
        reachVariants: m.reachVariants,
      })),
    });
  } catch (err) {
    console.error("Enriched hype cycle error:", err);
    res.status(500).json({ success: false, error: "Failed to compute enriched hype cycle" });
  }
});

// GET /api/hype-cycle/lifecycle — Revenue lifecycle predictions
hypeCycleRouter.get("/lifecycle", async (_req: Request, res: Response) => {
  try {
    const currentYear = new Date().getFullYear();
    const speedMetrics = await getSpeedClassMetrics();
    const priceMap = new Map(speedMetrics.map((m) => [m.speedGbps, m.avgPrice]));

    const allTechs = [...TECH_GENERATIONS, ...SPECIAL_TECHS];
    const lifecycles = allTechs.map((tech) =>
      computeRevenueLifecycle(
        tech.speedGbps,
        tech.name,
        tech.introYear,
        tech.peakYear,
        currentYear,
        priceMap.get(tech.speedGbps),
      )
    );

    // Sort by revenue index (highest current revenue first)
    const sorted = [...lifecycles].sort((a, b) => b.revenueIndex - a.revenueIndex);

    res.json({
      success: true,
      currentYear,
      lifecycles: sorted,
    });
  } catch (err) {
    console.error("Lifecycle error:", err);
    res.status(500).json({ success: false, error: "Failed to compute lifecycles" });
  }
});

// GET /api/hype-cycle/regional/:tech — Regional adoption by technology
hypeCycleRouter.get("/regional/:tech", (req: Request, res: Response) => {
  const techQuery = String(req.params.tech);
  const currentYear = new Date().getFullYear();

  const tech = findTechnology(techQuery);
  if (!tech) {
    res.status(404).json({
      success: false,
      error: `Technology "${techQuery}" not found. Available: 1G, 10G, 25G, 40G, 100G, 400G, 800G, 1.6T, CPO, LPO, 400ZR`,
    });
    return;
  }

  const regions = computeRegionalAdoption(tech.peakYear, currentYear, tech.name);

  res.json({
    success: true,
    technology: tech.name,
    speedGbps: tech.speedGbps,
    globalPeakYear: tech.peakYear,
    regions,
  });
});

// GET /api/hype-cycle/analysis — Bass-fitted results from DB (hype_cycle_analysis table)
hypeCycleRouter.get("/analysis", async (_req: Request, res: Response) => {
  try {
    const { pool } = await import("../db/client");
    const { rows } = await pool.query(`
      SELECT DISTINCT ON (technology)
        technology, computed_at,
        bass_p, bass_q, bass_m,
        t_peak_year, current_t,
        ROUND(current_share * 100, 1)       AS share_pct,
        ROUND(projected_share_1y * 100, 1)  AS share_1y_pct,
        ROUND(projected_share_3y * 100, 1)  AS share_3y_pct,
        hype_phase, hype_score,
        phase_since_year, years_to_next_phase,
        asp_current_usd, asp_decline_pct_3y,
        r_squared, data_points, notes
      FROM hype_cycle_analysis
      ORDER BY technology, computed_at DESC
    `);

    if (rows.length === 0) {
      res.json({ success: true, source: "db", data: [], message: "No analysis yet — run compute:hype-cycle job" });
      return;
    }

    res.json({ success: true, source: "db", computed_at: rows[0]?.computed_at, data: rows });
  } catch (err) {
    console.error("Hype cycle analysis DB error:", err);
    res.status(500).json({ success: false, error: "Failed to fetch analysis" });
  }
});

// GET /api/hype-cycle/:tech — Specific technology detail (must be last!)
hypeCycleRouter.get("/:tech", (req: Request, res: Response) => {
  const techQuery = String(req.params.tech);
  const yearParam = q("year", req);
  const year = yearParam ? parseInt(yearParam) : new Date().getFullYear();

  const tech = findTechnology(techQuery);
  if (!tech) {
    res.status(404).json({
      success: false,
      error: `Technology "${techQuery}" not found. Available: 1G, 10G, 25G, 40G, 100G, 400G, 800G, 1.6T, CPO, LPO, 400ZR`,
    });
    return;
  }

  const result = computeHypeCycle(tech, year);

  // Add regional data
  const regions = computeRegionalAdoption(tech.peakYear, year, tech.name);

  // Add revenue lifecycle
  const lifecycle = computeRevenueLifecycle(
    tech.speedGbps,
    tech.name,
    tech.introYear,
    tech.peakYear,
    year,
  );

  res.json({
    success: true,
    ...result,
    regionalAdoption: regions,
    revenueLifecycle: lifecycle,
  });
});
