/**
 * Price Comparison Dashboard — Public API
 *
 * Public-facing endpoints powering the "Octopart for optical transceivers"
 * price comparison page. No authentication required.
 *
 * Routes:
 *   GET /api/price-comparison            — Top 50 SKUs by vendor coverage
 *   GET /api/price-comparison/summary    — Market-level aggregate stats
 *   GET /api/price-comparison/:sku       — Per-SKU price breakdown
 */
import { Router, Request, Response } from "express";
import { pool } from "../db/client";
import { sendCSV } from "../utils/csv";

export const priceComparisonRouter = Router();

// ─── GET /api/price-comparison/summary ───────────────────────────────────────
// MUST be registered before /:sku to avoid route conflict
/**
 * Market summary:
 *   - Total unique SKUs tracked
 *   - Total price observations
 *   - Number of active vendors
 *   - Average prices broken down by form_factor
 */
priceComparisonRouter.get("/summary", async (_req: Request, res: Response) => {
  try {
    const [overview, byFormFactor] = await Promise.all([
      // Overall market counts
      pool.query(`
        WITH latest AS (
          SELECT DISTINCT ON (po.transceiver_id, po.source_vendor_id)
            po.transceiver_id,
            po.source_vendor_id,
            po.price,
            po.currency
          FROM price_observations po
          ORDER BY po.transceiver_id, po.source_vendor_id, po.time DESC
        )
        SELECT
          COUNT(DISTINCT l.transceiver_id)                      AS total_skus_tracked,
          (SELECT COUNT(*) FROM price_observations)::bigint     AS total_observations,
          COUNT(DISTINCT l.source_vendor_id)                    AS active_vendor_count,
          ROUND(AVG(l.price)::numeric, 2)                       AS overall_avg_price
        FROM latest l
      `),

      // Avg price per form_factor (using latest price per vendor per transceiver)
      pool.query(`
        WITH latest AS (
          SELECT DISTINCT ON (po.transceiver_id, po.source_vendor_id)
            po.transceiver_id,
            po.source_vendor_id,
            po.price,
            po.currency
          FROM price_observations po
          ORDER BY po.transceiver_id, po.source_vendor_id, po.time DESC
        )
        SELECT
          t.form_factor,
          COUNT(DISTINCT l.transceiver_id)              AS sku_count,
          COUNT(DISTINCT l.source_vendor_id)            AS vendor_count,
          ROUND(MIN(l.price)::numeric, 2)               AS min_price,
          ROUND(MAX(l.price)::numeric, 2)               AS max_price,
          ROUND(AVG(l.price)::numeric, 2)               AS avg_price,
          -- Most common currency for this form factor
          (
            SELECT currency
            FROM price_observations po2
            JOIN transceivers t2 ON t2.id = po2.transceiver_id
            WHERE t2.form_factor = t.form_factor
            GROUP BY currency
            ORDER BY COUNT(*) DESC
            LIMIT 1
          ) AS currency
        FROM latest l
        JOIN transceivers t ON t.id = l.transceiver_id
        GROUP BY t.form_factor
        ORDER BY sku_count DESC
      `),
    ]);

    res.json({
      success: true,
      data: {
        ...overview.rows[0],
        by_form_factor: byFormFactor.rows,
      },
    });
  } catch (err) {
    console.error("GET /api/price-comparison/summary error:", err);
    res.status(500).json({ success: false, error: "Internal server error" });
  }
});

// ─── GET /api/price-comparison ───────────────────────────────────────────────
/**
 * Top 50 transceivers ranked by number of vendors tracking them.
 * Add ?format=csv to download as CSV.
 */
priceComparisonRouter.get("/", async (req: Request, res: Response) => {
  const fmt = req.query.format as string | undefined;
  try {
    const result = await pool.query(`
      WITH latest AS (
        SELECT DISTINCT ON (po.transceiver_id, po.source_vendor_id)
          po.transceiver_id,
          po.source_vendor_id,
          po.price,
          po.currency
        FROM price_observations po
        ORDER BY po.transceiver_id, po.source_vendor_id, po.time DESC
      )
      SELECT
        t.form_factor,
        t.speed,
        t.standard_name,
        COUNT(DISTINCT l.source_vendor_id)                                          AS vendor_count,
        ROUND(MIN(l.price)::numeric, 2)                                             AS min_price,
        ROUND(MAX(l.price)::numeric, 2)                                             AS max_price,
        ROUND(AVG(l.price)::numeric, 2)                                             AS avg_price,
        -- Dominant currency (most common for this SKU)
        (
          SELECT currency
          FROM latest l2
          WHERE l2.transceiver_id = t.id
          GROUP BY currency
          ORDER BY COUNT(*) DESC
          LIMIT 1
        )                                                                            AS currency,
        ROUND(
          ((MAX(l.price) - MIN(l.price)) / NULLIF(MIN(l.price), 0) * 100)::numeric,
          1
        )                                                                            AS spread_pct
      FROM latest l
      JOIN transceivers t ON t.id = l.transceiver_id
      GROUP BY t.id, t.form_factor, t.speed, t.standard_name
      ORDER BY vendor_count DESC, avg_price ASC
      LIMIT 50
    `);

    if (fmt === "csv") {
      return sendCSV(res, result.rows, `tip-price-comparison-${new Date().toISOString().slice(0,10)}.csv`);
    }
    res.json({
      success: true,
      data: result.rows,
    });
  } catch (err) {
    console.error("GET /api/price-comparison error:", err);
    res.status(500).json({ success: false, error: "Internal server error" });
  }
});

// ─── GET /api/price-comparison/:sku ─────────────────────────────────────────
/**
 * Full price breakdown for a single SKU.
 * :sku matches against standard_name OR part_number (case-insensitive ILIKE).
 * Returns per-vendor prices, stock status, and aggregate stats.
 */
priceComparisonRouter.get("/:sku", async (req: Request, res: Response) => {
  try {
    const sku = String(req.params.sku).trim();

    // Resolve transceiver
    const transceiverResult = await pool.query(
      `SELECT id, standard_name, form_factor, speed, reach_label, fiber_type, part_number
       FROM transceivers
       WHERE standard_name ILIKE $1 OR part_number ILIKE $1
       LIMIT 1`,
      [sku]
    );

    if (transceiverResult.rows.length === 0) {
      res.status(404).json({ success: false, error: "Transceiver not found" });
      return;
    }

    const transceiver = transceiverResult.rows[0];

    // Latest price per vendor + stock level from stock_observations (if available)
    const pricesResult = await pool.query(`
      SELECT
        v.name                                   AS vendor,
        po.price,
        po.currency,
        po.stock_level,
        -- Prefer stock_observations for latest stock info (in_stock is boolean)
        COALESCE(
          (
            SELECT CASE WHEN so.in_stock THEN 'in_stock' ELSE 'out_of_stock' END
            FROM stock_observations so
            WHERE so.transceiver_id = po.transceiver_id
              AND so.source_vendor_id = po.source_vendor_id
            ORDER BY so.time DESC
            LIMIT 1
          ),
          po.stock_level
        )                                        AS stock_level,
        -- Use direct product URL from price observation, fall back to vendor shop/website
        COALESCE(
          po.url,
          v.shop_url,
          v.website
        )                                        AS url,
        po.time                                  AS observed_at
      FROM (
        SELECT DISTINCT ON (po.transceiver_id, po.source_vendor_id)
          po.transceiver_id,
          po.source_vendor_id,
          po.price,
          po.currency,
          po.stock_level,
          po.url,
          po.time
        FROM price_observations po
        WHERE po.transceiver_id = $1
        ORDER BY po.transceiver_id, po.source_vendor_id, po.time DESC
      ) po
      JOIN vendors v ON v.id = po.source_vendor_id
      ORDER BY po.price ASC
    `, [transceiver.id]);

    const prices = pricesResult.rows;

    // Compute aggregate stats
    const priceValues = prices.map((r) => parseFloat(r.price)).filter((v) => Number.isFinite(v));

    let stats: Record<string, number | null> = {
      vendor_count: prices.length,
      min: null,
      max: null,
      avg: null,
      spread_pct: null,
    };

    if (priceValues.length > 0) {
      const min = Math.min(...priceValues);
      const max = Math.max(...priceValues);
      const avg = priceValues.reduce((a, b) => a + b, 0) / priceValues.length;
      const spreadPct = min > 0 ? Math.round(((max - min) / min) * 1000) / 10 : null;

      stats = {
        vendor_count: prices.length,
        min: Math.round(min * 100) / 100,
        max: Math.round(max * 100) / 100,
        avg: Math.round(avg * 100) / 100,
        spread_pct: spreadPct,
      };
    }

    res.json({
      success: true,
      transceiver: {
        standard_name: transceiver.standard_name,
        form_factor: transceiver.form_factor,
        speed: transceiver.speed,
        reach_label: transceiver.reach_label,
        fiber_type: transceiver.fiber_type,
      },
      prices,
      stats,
    });
  } catch (err) {
    console.error("GET /api/price-comparison/:sku error:", err);
    res.status(500).json({ success: false, error: "Internal server error" });
  }
});
