/**
 * Stock Observations API
 *
 * Exposes warehouse stock data scraped from fs.com (DE-Lager, Global-Lager,
 * Nachlieferung, units_sold, compatible_brands) and other vendors.
 *
 * Routes:
 *   GET /api/stock                         — Latest obs per transceiver × vendor (paginated)
 *   GET /api/stock/summary                 — Aggregate warehouse stats (totals, top movers)
 *   GET /api/stock/velocity                — Abverkauf velocity results (paginated, filterable)
 *   GET /api/stock/velocity/:id            — Velocity + event history for one transceiver
 *   GET /api/stock/:transceiverIdOrSku     — Full obs history for one transceiver
 */
import { Router, Request, Response } from "express";
import { pool } from "../db/client";

export const stockRouter = Router();

// ─── helpers ─────────────────────────────────────────────────────────────────

function intParam(req: Request, name: string, fallback: number): number {
  const v = req.query[name];
  const parsed = v ? parseInt(String(v), 10) : NaN;
  return Number.isFinite(parsed) ? parsed : fallback;
}

// ─── GET /api/stock ──────────────────────────────────────────────────────────
/**
 * Returns the most recent stock observation per (transceiver, vendor) pair.
 * Query params:
 *   vendor_id   — filter by source vendor UUID
 *   in_stock    — "true" | "false"
 *   min_de      — minimum DE-Lager quantity
 *   min_global  — minimum Global-Lager quantity
 *   part_number — partial match on part_number
 *   limit       — default 50, max 200
 *   offset      — default 0
 */
stockRouter.get("/", async (req: Request, res: Response) => {
  try {
    const limit = Math.min(intParam(req, "limit", 50), 200);
    const offset = intParam(req, "offset", 0);
    const vendorId = req.query.vendor_id ? String(req.query.vendor_id) : null;
    const inStock = req.query.in_stock === "true" ? true : req.query.in_stock === "false" ? false : null;
    const minDe = req.query.min_de ? parseInt(String(req.query.min_de), 10) : null;
    const minGlobal = req.query.min_global ? parseInt(String(req.query.min_global), 10) : null;
    const partNumber = req.query.part_number ? String(req.query.part_number) : null;

    const conditions: string[] = [];
    const params: unknown[] = [];
    let p = 1;

    if (vendorId) { conditions.push(`so.source_vendor_id = $${p++}`); params.push(vendorId); }
    if (inStock !== null) { conditions.push(`so.in_stock = $${p++}`); params.push(inStock); }
    if (minDe !== null) { conditions.push(`so.warehouse_de_qty >= $${p++}`); params.push(minDe); }
    if (minGlobal !== null) { conditions.push(`so.warehouse_global_qty >= $${p++}`); params.push(minGlobal); }
    if (partNumber) { conditions.push(`t.part_number ILIKE $${p++}`); params.push(`%${partNumber}%`); }

    const whereClause = conditions.length ? `AND ${conditions.join(" AND ")}` : "";

    const sql = `
      SELECT
        so.time,
        t.id                       AS transceiver_id,
        t.part_number,
        t.form_factor,
        t.speed,
        v.name                     AS vendor_name,
        v.website                  AS vendor_website,
        so.in_stock,
        so.quantity_available,
        so.warehouse_de_qty,
        so.warehouse_de_delivery_date,
        so.warehouse_global_qty,
        so.warehouse_global_delivery_date,
        so.backorder_qty,
        so.backorder_estimated_date,
        so.units_sold,
        so.compatible_brands,
        so.price_net,
        so.product_url,
        so.stock_confidence,
        so.price_currency,
        so.price_includes_tax,
        so.stock_vendor_ts
      FROM (
        SELECT DISTINCT ON (transceiver_id, source_vendor_id) *
        FROM stock_observations
        ORDER BY transceiver_id, source_vendor_id, time DESC
      ) so
      JOIN transceivers t ON t.id = so.transceiver_id
      JOIN vendors v ON v.id = so.source_vendor_id
      WHERE 1=1 ${whereClause}
      ORDER BY so.time DESC
      LIMIT $${p++} OFFSET $${p++}
    `;
    params.push(limit, offset);

    const countSql = `
      SELECT COUNT(*) FROM (
        SELECT DISTINCT ON (transceiver_id, source_vendor_id) *
        FROM stock_observations
        ORDER BY transceiver_id, source_vendor_id, time DESC
      ) so
      JOIN transceivers t ON t.id = so.transceiver_id
      JOIN vendors v ON v.id = so.source_vendor_id
      WHERE 1=1 ${whereClause}
    `;

    const [rows, countRow] = await Promise.all([
      pool.query(sql, params),
      pool.query(countSql, params.slice(0, params.length - 2)),
    ]);

    res.json({
      success: true,
      data: rows.rows,
      meta: {
        total: parseInt(countRow.rows[0].count, 10),
        limit,
        offset,
      },
    });
  } catch (err) {
    console.error("GET /api/stock error:", err);
    res.status(500).json({ success: false, error: "Internal server error" });
  }
});

// ─── GET /api/stock/summary ──────────────────────────────────────────────────
/**
 * Aggregate stats across all latest stock observations.
 * Returns totals per warehouse tier, top sellers, and per-vendor breakdown.
 */
stockRouter.get("/summary", async (req: Request, res: Response) => {
  try {
    const [totals, topSellers, vendorBreakdown, recentlyUpdated, priceComparison] = await Promise.all([
      // Overall totals from latest observations
      pool.query(`
        WITH latest AS (
          SELECT DISTINCT ON (transceiver_id, source_vendor_id) *
          FROM stock_observations
          ORDER BY transceiver_id, source_vendor_id, time DESC
        )
        SELECT
          COUNT(*)                                                AS total_observations,
          COUNT(*) FILTER (WHERE in_stock = true)                AS in_stock_count,
          SUM(COALESCE(warehouse_de_qty, 0))                     AS total_de_qty,
          SUM(COALESCE(warehouse_global_qty, 0))                 AS total_global_qty,
          SUM(COALESCE(backorder_qty, 0))                        AS total_backorder_qty,
          COUNT(*) FILTER (WHERE warehouse_de_qty > 0)           AS products_with_de_stock,
          COUNT(*) FILTER (WHERE warehouse_global_qty > 0)       AS products_with_global_stock,
          COUNT(*) FILTER (WHERE backorder_qty > 0)              AS products_with_backorder,
          COUNT(DISTINCT transceiver_id)                         AS unique_transceivers,
          COUNT(DISTINCT source_vendor_id)                       AS unique_vendors,
          -- Data quality breakdown by confidence level
          COUNT(*) FILTER (WHERE stock_confidence = 1)          AS conf_boolean_count,
          COUNT(*) FILTER (WHERE stock_confidence = 2)          AS conf_aggregated_count,
          COUNT(*) FILTER (WHERE stock_confidence = 3)          AS conf_per_warehouse_count,
          -- Multi-vendor coverage (SKUs tracked by 2+ vendors)
          COUNT(DISTINCT transceiver_id) FILTER (WHERE transceiver_id IN (
            SELECT transceiver_id FROM latest GROUP BY transceiver_id HAVING COUNT(DISTINCT source_vendor_id) >= 2
          ))                                                     AS multi_vendor_skus
        FROM latest
      `),

      // Top sellers by units_sold
      pool.query(`
        WITH latest AS (
          SELECT DISTINCT ON (transceiver_id, source_vendor_id) *
          FROM stock_observations
          WHERE units_sold IS NOT NULL
          ORDER BY transceiver_id, source_vendor_id, time DESC
        )
        SELECT
          t.part_number,
          t.form_factor,
          t.speed,
          v.name AS vendor_name,
          so.units_sold,
          so.warehouse_de_qty,
          so.warehouse_global_qty,
          so.price_net,
          so.product_url
        FROM latest so
        JOIN transceivers t ON t.id = so.transceiver_id
        JOIN vendors v ON v.id = so.source_vendor_id
        ORDER BY so.units_sold DESC
        LIMIT 20
      `),

      // Per-vendor stock breakdown (incl. confidence + currency breakdown)
      pool.query(`
        WITH latest AS (
          SELECT DISTINCT ON (transceiver_id, source_vendor_id) *
          FROM stock_observations
          ORDER BY transceiver_id, source_vendor_id, time DESC
        )
        SELECT
          v.name                                                          AS vendor_name,
          v.website                                                       AS vendor_website,
          COUNT(*)                                                        AS product_count,
          COUNT(*) FILTER (WHERE so.in_stock = true)                     AS in_stock_count,
          SUM(COALESCE(so.warehouse_de_qty, 0))                          AS total_de_qty,
          SUM(COALESCE(so.warehouse_global_qty, 0))                      AS total_global_qty,
          SUM(COALESCE(so.backorder_qty, 0))                             AS total_backorder,
          MAX(so.time)                                                    AS last_scraped,
          ROUND(AVG(so.stock_confidence)::NUMERIC, 1)                    AS avg_confidence,
          ARRAY_AGG(DISTINCT so.price_currency)
            FILTER (WHERE so.price_currency IS NOT NULL)                 AS currencies,
          -- Per-confidence breakdown
          COUNT(*) FILTER (WHERE so.stock_confidence = 3)               AS conf_per_warehouse,
          COUNT(*) FILTER (WHERE so.stock_confidence = 2)               AS conf_aggregated,
          COUNT(*) FILTER (WHERE so.stock_confidence = 1
            OR so.stock_confidence IS NULL)                              AS conf_boolean
        FROM latest so
        JOIN vendors v ON v.id = so.source_vendor_id
        GROUP BY v.id, v.name, v.website
        ORDER BY product_count DESC
      `),

      // Recently restocked (stock appeared in last 24h)
      pool.query(`
        SELECT
          t.part_number,
          t.form_factor,
          t.speed,
          v.name AS vendor_name,
          so.warehouse_de_qty,
          so.warehouse_global_qty,
          so.time AS observed_at
        FROM stock_observations so
        JOIN transceivers t ON t.id = so.transceiver_id
        JOIN vendors v ON v.id = so.source_vendor_id
        WHERE so.time >= NOW() - INTERVAL '24 hours'
          AND so.in_stock = true
          AND (so.warehouse_de_qty > 0 OR so.warehouse_global_qty > 0)
        ORDER BY so.time DESC
        LIMIT 10
      `),

      // Price comparison: SKUs tracked by multiple vendors (multi-vendor overlap)
      pool.query(`
        WITH latest AS (
          SELECT DISTINCT ON (transceiver_id, source_vendor_id) *
          FROM stock_observations
          WHERE price_net IS NOT NULL
          ORDER BY transceiver_id, source_vendor_id, time DESC
        )
        SELECT
          t.part_number,
          t.form_factor,
          t.speed,
          COUNT(DISTINCT so.source_vendor_id)        AS vendor_count,
          MIN(so.price_net)                          AS price_min,
          MAX(so.price_net)                          AS price_max,
          ROUND(AVG(so.price_net)::NUMERIC, 2)       AS price_avg,
          ARRAY_AGG(v.name ORDER BY so.price_net)    AS vendor_names,
          ARRAY_AGG(so.price_net ORDER BY so.price_net) AS prices,
          ARRAY_AGG(so.price_currency ORDER BY so.price_net) AS currencies,
          MAX(so.stock_confidence)                   AS best_confidence
        FROM latest so
        JOIN transceivers t ON t.id = so.transceiver_id
        JOIN vendors v ON v.id = so.source_vendor_id
        GROUP BY t.id, t.part_number, t.form_factor, t.speed
        HAVING COUNT(DISTINCT so.source_vendor_id) >= 2
        ORDER BY vendor_count DESC, price_min ASC
        LIMIT 50
      `),
    ]);

    res.json({
      success: true,
      data: {
        totals: totals.rows[0],
        top_sellers: topSellers.rows,
        vendor_breakdown: vendorBreakdown.rows,
        recently_updated: recentlyUpdated.rows,
        price_comparison: priceComparison.rows,
      },
    });
  } catch (err) {
    console.error("GET /api/stock/summary error:", err);
    res.status(500).json({ success: false, error: "Internal server error" });
  }
});

// ─── GET /api/stock/velocity ─────────────────────────────────────────────────
/**
 * Paginated Abverkauf velocity results from the stock_velocity table.
 * Query params:
 *   vendor_id       — filter by vendor UUID
 *   confidence      — "high" | "medium" | "low" | "insufficient"
 *   stockout_days   — only products with estimated_stockout_days <= N (0 = already out)
 *   min_sell_rate   — minimum avg_daily_sell_rate
 *   part_number     — partial match
 *   limit           — default 50, max 200
 *   offset          — default 0
 */
stockRouter.get("/velocity", async (req: Request, res: Response) => {
  try {
    const limit = Math.min(intParam(req, "limit", 50), 200);
    const offset = intParam(req, "offset", 0);
    const vendorId = req.query.vendor_id ? String(req.query.vendor_id) : null;
    const confidence = req.query.confidence ? String(req.query.confidence) : null;
    const stockoutDays = req.query.stockout_days !== undefined
      ? parseInt(String(req.query.stockout_days), 10)
      : null;
    const minSellRate = req.query.min_sell_rate
      ? parseFloat(String(req.query.min_sell_rate))
      : null;
    const partNumber = req.query.part_number ? String(req.query.part_number) : null;

    const conditions: string[] = [];
    const params: unknown[] = [];
    let p = 1;

    if (vendorId) {
      conditions.push(`sv.vendor_id = $${p++}`);
      params.push(vendorId);
    }
    if (confidence) {
      conditions.push(`sv.velocity_confidence = $${p++}`);
      params.push(confidence);
    }
    if (stockoutDays !== null && Number.isFinite(stockoutDays)) {
      conditions.push(`sv.estimated_stockout_days <= $${p++}`);
      params.push(stockoutDays);
    }
    if (minSellRate !== null && Number.isFinite(minSellRate)) {
      conditions.push(`sv.avg_daily_sell_rate >= $${p++}`);
      params.push(minSellRate);
    }
    if (partNumber) {
      conditions.push(`t.part_number ILIKE $${p++}`);
      params.push(`%${partNumber}%`);
    }

    const whereClause = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";

    const sql = `
      SELECT
        sv.transceiver_id,
        sv.vendor_id,
        sv.computed_at,
        sv.window_start,
        sv.window_end,
        sv.obs_count,
        sv.avg_daily_sell_rate,
        sv.peak_daily_sell_rate,
        sv.total_sell_events,
        sv.total_units_sold_implied,
        sv.units_sold_counter_delta,
        sv.units_sold_daily_rate,
        sv.total_zulauf_events,
        sv.total_units_zulauf,
        sv.last_zulauf_at,
        sv.next_expected_delivery,
        sv.current_qty,
        sv.current_backorder_qty,
        sv.current_price_net,
        sv.estimated_stockout_days,
        sv.estimated_stockout_date,
        sv.velocity_confidence,
        t.part_number,
        t.form_factor,
        t.speed,
        v.name     AS vendor_name,
        v.website  AS vendor_website
      FROM stock_velocity sv
      JOIN transceivers t ON t.id = sv.transceiver_id
      JOIN vendors v ON v.id = sv.vendor_id
      ${whereClause}
      ORDER BY
        CASE sv.velocity_confidence
          WHEN 'high'         THEN 1
          WHEN 'medium'       THEN 2
          WHEN 'low'          THEN 3
          WHEN 'insufficient' THEN 4
          ELSE 5
        END,
        sv.avg_daily_sell_rate DESC NULLS LAST
      LIMIT $${p++} OFFSET $${p++}
    `;
    params.push(limit, offset);

    const countSql = `
      SELECT COUNT(*)
      FROM stock_velocity sv
      JOIN transceivers t ON t.id = sv.transceiver_id
      JOIN vendors v ON v.id = sv.vendor_id
      ${whereClause}
    `;

    const [rows, countRow] = await Promise.all([
      pool.query(sql, params),
      pool.query(countSql, params.slice(0, params.length - 2)),
    ]);

    res.json({
      success: true,
      data: rows.rows,
      meta: {
        total: parseInt(countRow.rows[0].count, 10),
        limit,
        offset,
      },
    });
  } catch (err) {
    console.error("GET /api/stock/velocity error:", err);
    res.status(500).json({ success: false, error: "Internal server error" });
  }
});

// ─── GET /api/stock/velocity/:id ─────────────────────────────────────────────
/**
 * Velocity summary + raw event history for one transceiver.
 * :id can be a UUID or part_number (case-insensitive).
 * Query params:
 *   vendor_id   — filter to a specific vendor (optional; returns all vendors if omitted)
 *   event_limit — max events returned per vendor (default 200)
 */
stockRouter.get("/velocity/:id", async (req: Request, res: Response) => {
  try {
    const id = String(req.params.id);
    const vendorId = req.query.vendor_id ? String(req.query.vendor_id) : null;
    const eventLimit = Math.min(intParam(req, "event_limit", 200), 1000);

    // Resolve UUID vs part_number
    let transceiverUuid: string | null = null;
    const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
    if (uuidRegex.test(id)) {
      transceiverUuid = id;
    } else {
      const r = await pool.query(
        `SELECT id FROM transceivers WHERE part_number ILIKE $1 LIMIT 1`,
        [id]
      );
      if (r.rows.length > 0) transceiverUuid = r.rows[0].id;
    }

    if (!transceiverUuid) {
      res.status(404).json({ success: false, error: "Transceiver not found" });
      return;
    }

    const velocityParams: unknown[] = [transceiverUuid];
    let vendorFilter = "";
    if (vendorId) {
      velocityParams.push(vendorId);
      vendorFilter = `AND sv.vendor_id = $${velocityParams.length}`;
    }

    const eventParams: unknown[] = [transceiverUuid, eventLimit];
    let eventVendorFilter = "";
    if (vendorId) {
      eventParams.push(vendorId);
      eventVendorFilter = `AND sve.vendor_id = $${eventParams.length}`;
    }

    const [transceiver, velocity, events] = await Promise.all([
      pool.query(
        `SELECT t.*, v.name AS brand_name
         FROM transceivers t LEFT JOIN vendors v ON v.id = t.brand_vendor_id
         WHERE t.id = $1`,
        [transceiverUuid]
      ),
      pool.query(
        `SELECT
           sv.*,
           v.name    AS vendor_name,
           v.website AS vendor_website
         FROM stock_velocity sv
         JOIN vendors v ON v.id = sv.vendor_id
         WHERE sv.transceiver_id = $1 ${vendorFilter}
         ORDER BY sv.velocity_confidence, sv.avg_daily_sell_rate DESC NULLS LAST`,
        velocityParams
      ),
      pool.query(
        `SELECT
           sve.event_at,
           sve.event_type,
           sve.units_delta,
           sve.daily_rate,
           sve.qty_before,
           sve.qty_after,
           sve.hours_elapsed,
           v.name AS vendor_name
         FROM stock_velocity_events sve
         JOIN vendors v ON v.id = sve.vendor_id
         WHERE sve.transceiver_id = $1 ${eventVendorFilter}
         ORDER BY sve.event_at DESC
         LIMIT $2`,
        eventParams
      ),
    ]);

    if (!transceiver.rows[0]) {
      res.status(404).json({ success: false, error: "Transceiver not found" });
      return;
    }

    res.json({
      success: true,
      data: {
        transceiver: transceiver.rows[0],
        velocity: velocity.rows,
        events: events.rows,
        meta: {
          velocity_count: velocity.rows.length,
          event_count: events.rows.length,
        },
      },
    });
  } catch (err) {
    console.error("GET /api/stock/velocity/:id error:", err);
    res.status(500).json({ success: false, error: "Internal server error" });
  }
});


// ─── GET /api/stock/competitor-by-tech ───────────────────────────────────────
// Competitor stock levels from publicly-scraped data, aggregated by technology.
stockRouter.get("/competitor-by-tech", async (_req: Request, res: Response) => {
  try {
    const result = await pool.query(`
      SELECT
        t.form_factor,
        t.speed_gbps::numeric                                      AS speed_gbps,
        sv.name                                                    AS vendor_name,
        COUNT(DISTINCT so.transceiver_id)::int                    AS skus,
        COALESCE(SUM(so.warehouse_de_qty),0)::int                 AS de_stock,
        COALESCE(SUM(so.warehouse_global_qty),0)::int             AS global_stock,
        COALESCE(SUM(so.quantity_available),0)::int               AS qty_available,
        MAX(so.time)::date                                         AS last_seen
      FROM stock_observations so
      JOIN transceivers  t  ON t.id  = so.transceiver_id
      JOIN vendors       sv ON sv.id = so.source_vendor_id
      WHERE so.time > NOW() - INTERVAL '14 days'
        AND sv.name IN ('FS.COM','ATGBICS','FiberMall','NADDOD','Prolabs','Blue Optics','Skylane Optics')
      GROUP BY t.form_factor, t.speed_gbps, sv.name
      ORDER BY sv.name, global_stock DESC NULLS LAST
    `);

    const byTech: Record<string, Record<string, { de: number; global: number; skus: number; last_seen: string }>> = {};
    const vendors = new Set<string>();
    for (const row of result.rows) {
      const n = parseFloat(row.speed_gbps);
      const spd = n >= 1000
        ? ((n / 1000 * 10) % 10 === 0 ? String(Math.round(n / 1000)) : (n / 1000).toFixed(1)) + "T"
        : ((n * 10) % 10 === 0 ? String(Math.round(n)) : String(n)) + "G";
      const key = spd + " " + (row.form_factor || "?");
      if (!byTech[key]) byTech[key] = {};
      byTech[key][row.vendor_name] = {
        de: parseInt(row.de_stock) || 0,
        global: parseInt(row.global_stock) || parseInt(row.qty_available) || 0,
        skus: parseInt(row.skus) || 0,
        last_seen: row.last_seen,
      };
      vendors.add(row.vendor_name);
    }
    res.json({ success: true, vendors: [...vendors].sort(), by_tech: byTech });
  } catch (err) {
    console.error("stock/competitor-by-tech error:", err);
    res.status(500).json({ success: false, error: String(err) });
  }
});

// ─── GET /api/stock/:id ──────────────────────────────────────────────────────
/**
 * Full observation history for one transceiver.
 * :id can be a UUID or a part_number (case-insensitive).
 * Query params:
 *   vendor_id — filter by vendor UUID
 *   days      — look-back window in days (default 30)
 *   limit     — max observations returned (default 100)
 */
stockRouter.get("/:id", async (req: Request, res: Response) => {
  try {
    const id = String(req.params.id);
    const days = intParam(req, "days", 30);
    const limit = Math.min(intParam(req, "limit", 100), 500);
    const vendorId = req.query.vendor_id ? String(req.query.vendor_id) : null;

    // Resolve UUID vs part_number
    let transceiverUuid: string | null = null;
    const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
    if (uuidRegex.test(id)) {
      transceiverUuid = id;
    } else {
      const r = await pool.query(
        `SELECT id FROM transceivers WHERE part_number ILIKE $1 LIMIT 1`,
        [id]
      );
      if (r.rows.length > 0) transceiverUuid = r.rows[0].id;
    }

    if (!transceiverUuid) {
      res.status(404).json({ success: false, error: "Transceiver not found" });
      return;
    }

    const params: unknown[] = [transceiverUuid, days, limit];
    let vendorFilter = "";
    if (vendorId) {
      params.push(vendorId);
      vendorFilter = `AND so.source_vendor_id = $${params.length}`;
    }

    const [transceiver, observations] = await Promise.all([
      pool.query(
        `SELECT t.*, v.name AS brand_name
         FROM transceivers t LEFT JOIN vendors v ON v.id = t.brand_vendor_id
         WHERE t.id = $1`,
        [transceiverUuid]
      ),
      pool.query(
        `SELECT
           so.time,
           v.name                         AS vendor_name,
           v.website                      AS vendor_website,
           so.in_stock,
           so.quantity_available,
           so.warehouse_de_qty,
           so.warehouse_de_delivery_date,
           so.warehouse_global_qty,
           so.warehouse_global_delivery_date,
           so.backorder_qty,
           so.backorder_estimated_date,
           so.units_sold,
           so.compatible_brands,
           so.price_net,
           so.product_url
         FROM stock_observations so
         JOIN vendors v ON v.id = so.source_vendor_id
         WHERE so.transceiver_id = $1
           AND so.time >= NOW() - ($2 || ' days')::INTERVAL
           ${vendorFilter}
         ORDER BY so.time DESC
         LIMIT $3`,
        params
      ),
    ]);

    if (!transceiver.rows[0]) {
      res.status(404).json({ success: false, error: "Transceiver not found" });
      return;
    }

    res.json({
      success: true,
      data: {
        transceiver: transceiver.rows[0],
        observations: observations.rows,
        meta: {
          count: observations.rows.length,
          days_requested: days,
        },
      },
    });
  } catch (err) {
    console.error("GET /api/stock/:id error:", err);
    res.status(500).json({ success: false, error: "Internal server error" });
  }
});
