/**
 * Equivalences & price-history tools: find_equivalences, get_price_history
 */
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { pool } from "../db.js";

export async function registerEquivalencesTools(server: McpServer): Promise<void> {
  // --- Tool: find_equivalences ---
  server.tool(
    "find_equivalences",
    `Find Flexoptix equivalent transceivers for a competitor product (or vice-versa).
     Uses the TIP equivalences database (63k+ verified cross-brand mappings, 93.9% avg confidence).
     Example: "What Flexoptix alternative exists for Cisco GLC-LH-SMD?" → Returns Flexoptix part numbers, pricing, specs, and confidence.`,
    {
      part_number: z.string().describe("Competitor or Flexoptix part number, e.g. 'GLC-LH-SMD', 'SFP-10G-LR', 'QSFP-100G-PSM4'"),
      vendor: z.string().optional().describe("Vendor filter, e.g. 'Cisco', 'Juniper', 'FS.COM'. Leave empty to search all vendors."),
      min_confidence: z.number().min(0).max(1).default(0.8).describe("Minimum confidence threshold (0–1). Default 0.8."),
      max_results: z.number().default(10).describe("Maximum results to return"),
    },
    async ({ part_number, vendor, min_confidence, max_results }) => {
      const conditions = [
        "e.status IN ('approved', 'auto_approved')",
        `e.confidence >= $1`,
        `(cx.part_number ILIKE $2 OR cx.standard_name ILIKE $2 OR fx.part_number ILIKE $2 OR fx.standard_name ILIKE $2)`,
      ];
      const values: unknown[] = [min_confidence, `%${part_number}%`];
      let idx = 3;

      if (vendor) {
        conditions.push(`cv.name ILIKE $${idx}`);
        values.push(`%${vendor}%`);
        idx++;
      }

      const result = await pool.query(
        `SELECT
          e.confidence,
          e.match_basis,
          e.status,
          -- Flexoptix product
          fx.part_number AS flexoptix_pn,
          fx.standard_name AS flexoptix_std,
          fx.form_factor AS flexoptix_form_factor,
          fx.speed AS flexoptix_speed,
          fx.reach_label AS flexoptix_reach,
          fx.fiber_type AS flexoptix_fiber,
          fx.market_status AS flexoptix_market_status,
          fx.price_verified_eur AS flexoptix_price_eur,
          fx.product_page_url AS flexoptix_url,
          -- Competitor product
          cx.part_number AS competitor_pn,
          cx.standard_name AS competitor_std,
          cx.form_factor AS competitor_form_factor,
          cx.speed AS competitor_speed,
          cx.reach_label AS competitor_reach,
          cx.price_verified_eur AS competitor_price_eur,
          cv.name AS competitor_vendor
        FROM transceiver_equivalences e
        JOIN transceivers fx ON fx.id = e.flexoptix_id
        JOIN transceivers cx ON cx.id = e.competitor_id
        JOIN vendors cv ON cv.id = cx.vendor_id
        WHERE ${conditions.join(" AND ")}
        ORDER BY e.confidence DESC
        LIMIT $${idx}`,
        [...values, max_results]
      );

      if (result.rows.length === 0) {
        return {
          content: [{
            type: "text",
            text: `No equivalences found for "${part_number}"${vendor ? ` from ${vendor}` : ""} with confidence ≥ ${min_confidence}.\n\nTry a broader search term or lower confidence threshold.`,
          }],
        };
      }

      const lines = result.rows.map((r, i) => {
        const conf = `${(parseFloat(r.confidence) * 100).toFixed(0)}%`;
        const basis = Array.isArray(r.match_basis) ? r.match_basis.join(", ") : r.match_basis;
        const fxPrice = r.flexoptix_price_eur ? `€${r.flexoptix_price_eur}` : "—";
        const compPrice = r.competitor_price_eur ? `€${r.competitor_price_eur}` : "—";
        return [
          `${i + 1}. Competitor: ${r.competitor_vendor} **${r.competitor_pn}** (${r.competitor_std || r.competitor_form_factor}, ${r.competitor_speed}, ${r.competitor_reach || "—"}) @ ${compPrice}`,
          `   → Flexoptix: **${r.flexoptix_pn}** (${r.flexoptix_std || r.flexoptix_form_factor}, ${r.flexoptix_speed}, ${r.flexoptix_reach || "—"}) @ ${fxPrice} | Status: ${r.flexoptix_market_status || "—"}`,
          `   Confidence: ${conf} | Match basis: ${basis}`,
          r.flexoptix_url ? `   Product page: ${r.flexoptix_url}` : "",
        ].filter(Boolean).join("\n");
      });

      return {
        content: [{
          type: "text",
          text: `## Equivalences for "${part_number}"\n\nFound ${result.rows.length} match(es):\n\n${lines.join("\n\n")}`,
        }],
      };
    }
  );

  // --- Tool: get_price_history ---
  server.tool(
    "get_price_history",
    `Get price history for a transceiver over time (from 392k+ price observations across 60+ competitors).
     Returns daily min/max/avg prices per source vendor for charting and trend analysis.
     Useful for: price trend analysis, sourcing decisions, identifying cheapest vendor window.`,
    {
      part_number: z.string().describe("Part number, slug, or standard name, e.g. 'QSFP-40G-SR4', '100GBASE-LR4'"),
      days: z.number().default(30).describe("Number of days of history to return (max 365)"),
      vendor: z.string().optional().describe("Filter to specific source vendor, e.g. 'FS.COM', 'Mouser'. Leave empty for all."),
    },
    async ({ part_number, days, vendor }) => {
      const daysLimited = Math.min(days, 365);

      // Resolve transceiver
      const tx = await pool.query(
        `SELECT t.id, t.part_number, t.standard_name, t.form_factor, t.speed, v.name as vendor_name
         FROM transceivers t LEFT JOIN vendors v ON v.id = t.vendor_id
         WHERE t.slug ILIKE $1 OR t.part_number ILIKE $1 OR t.standard_name ILIKE $1
         LIMIT 1`,
        [`%${part_number}%`]
      );

      if (tx.rows.length === 0) {
        return {
          content: [{ type: "text", text: `Transceiver not found: "${part_number}"` }],
        };
      }

      const txRow = tx.rows[0];

      const conditions = [
        `po.transceiver_id = $1`,
        `po.time >= NOW() - INTERVAL '${daysLimited} days'`,
        `po.price > 0`,
        `po.is_anomalous IS NOT TRUE`,
      ];
      const values: unknown[] = [txRow.id];
      let idx = 2;

      if (vendor) {
        conditions.push(`sv.name ILIKE $${idx}`);
        values.push(`%${vendor}%`);
        idx++;
      }

      const series = await pool.query(
        `SELECT
          DATE_TRUNC('day', po.time) AS day,
          sv.name AS source_vendor,
          MIN(po.price)::numeric(12,2) AS price_min,
          MAX(po.price)::numeric(12,2) AS price_max,
          AVG(po.price)::numeric(12,2) AS price_avg,
          po.currency,
          COUNT(*) AS observations
        FROM price_observations po
        LEFT JOIN vendors sv ON sv.id = po.source_vendor_id
        WHERE ${conditions.join(" AND ")}
        GROUP BY DATE_TRUNC('day', po.time), sv.name, po.currency
        ORDER BY day ASC, source_vendor`,
        values
      );

      if (series.rows.length === 0) {
        return {
          content: [{
            type: "text",
            text: `No price history found for "${txRow.part_number}" in the last ${daysLimited} days.`,
          }],
        };
      }

      // Summarize by vendor
      const byVendor = new Map<string, { min: number; max: number; latest: number; currency: string; points: number }>();
      for (const row of series.rows) {
        const key = row.source_vendor || "Unknown";
        const cur = byVendor.get(key);
        if (!cur) {
          byVendor.set(key, { min: parseFloat(row.price_min), max: parseFloat(row.price_max), latest: parseFloat(row.price_avg), currency: row.currency, points: parseInt(row.observations) });
        } else {
          cur.min = Math.min(cur.min, parseFloat(row.price_min));
          cur.max = Math.max(cur.max, parseFloat(row.price_max));
          cur.latest = parseFloat(row.price_avg); // last in order = latest
          cur.points += parseInt(row.observations);
        }
      }

      const vendorLines = [...byVendor.entries()]
        .sort((a, b) => a[1].min - b[1].min)
        .map(([v, d]) =>
          `- **${v}**: ${d.currency} ${d.min}–${d.max} (latest avg: ${d.latest}, ${d.points} observations)`
        );

      const allMins = [...byVendor.values()].map(d => d.min);
      const overallMin = Math.min(...allMins);
      const overallMax = Math.max(...[...byVendor.values()].map(d => d.max));
      const cheapestVendor = [...byVendor.entries()].sort((a, b) => a[1].min - b[1].min)[0];

      return {
        content: [{
          type: "text",
          text: [
            `## Price History: ${txRow.part_number} (${txRow.vendor_name || "—"})`,
            `**Standard:** ${txRow.standard_name || "—"} | **Form factor:** ${txRow.form_factor} | **Speed:** ${txRow.speed}`,
            `**Period:** Last ${daysLimited} days | **Total observations:** ${series.rows.reduce((s, r) => s + parseInt(r.observations), 0)}`,
            ``,
            `### Price Range (all vendors)`,
            `- Overall min: **${overallMin}** | max: **${overallMax}**`,
            `- Cheapest source: **${cheapestVendor[0]}** @ ${cheapestVendor[1].min}`,
            ``,
            `### By Vendor`,
            ...vendorLines,
          ].join("\n"),
        }],
      };
    }
  );
}
