/**
 * Win/Loss Intelligence — /api/win-loss
 *
 * Record and analyze deal outcomes: who won, who lost, at what price, in which segment.
 *
 * Routes:
 *   POST /api/win-loss              — Record a win/loss event
 *   GET  /api/win-loss              — List events (filterable)
 *   GET  /api/win-loss/summary      — Aggregate win rate, avg price delta, segments
 *   GET  /api/win-loss/competitors  — Ranking by competitor vendor (loss analysis)
 */
import { Router, Request, Response } from "express";
import { pool } from "../db/client";
import { sendCSV } from "../utils/csv";

export const winLossRouter = Router();

// ── POST /api/win-loss — Record a deal outcome ──────────────────────────────
winLossRouter.post("/", async (req: Request, res: Response) => {
  const {
    outcome, transceiver_id, competitor_vendor,
    our_price, competitor_price, currency = "USD",
    quantity, customer_segment, deal_source,
    form_factor, speed_gbps, notes, deal_date,
  } = req.body as Record<string, any>;

  if (!outcome || !["won","lost","unknown"].includes(outcome)) {
    return res.status(400).json({ success: false, error: "outcome must be: won | lost | unknown" });
  }

  try {
    const result = await pool.query(
      `INSERT INTO win_loss_events
         (outcome, transceiver_id, competitor_vendor, our_price, competitor_price,
          currency, quantity, customer_segment, deal_source, form_factor, speed_gbps, notes, deal_date)
       VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,
               COALESCE($13::date, CURRENT_DATE))
       RETURNING *`,
      [
        outcome,
        transceiver_id || null,
        competitor_vendor || null,
        our_price ? parseFloat(our_price) : null,
        competitor_price ? parseFloat(competitor_price) : null,
        currency,
        quantity ? parseInt(quantity) : null,
        customer_segment || null,
        deal_source || null,
        form_factor || null,
        speed_gbps ? parseFloat(speed_gbps) : null,
        notes || null,
        deal_date || null,
      ]
    );
    return res.status(201).json({ success: true, event: result.rows[0] });
  } catch (err) {
    return res.status(500).json({ success: false, error: String(err) });
  }
});

// ── GET /api/win-loss — List events ─────────────────────────────────────────
winLossRouter.get("/", async (req: Request, res: Response) => {
  const outcome   = req.query.outcome as string | undefined;
  const segment   = req.query.customer_segment as string | undefined;
  const days      = Math.min(parseInt(req.query.days as string) || 90, 730);
  const limit     = Math.min(parseInt(req.query.limit as string) || 50, 200);
  const fmt       = req.query.format as string | undefined;

  try {
    const result = await pool.query(`
      SELECT wl.*,
             t.standard_name, t.form_factor AS tx_form_factor, t.speed_gbps AS tx_speed
      FROM win_loss_events wl
      LEFT JOIN transceivers t ON t.id = wl.transceiver_id
      WHERE wl.deal_date >= CURRENT_DATE - INTERVAL '${days} days'
        ${outcome ? `AND wl.outcome = '${outcome.replace(/'/g,"''")}'` : ""}
        ${segment ? `AND wl.customer_segment = '${segment.replace(/'/g,"''")}'` : ""}
      ORDER BY wl.deal_date DESC
      LIMIT ${limit}
    `);

    if (fmt === "csv") {
      return sendCSV(res, result.rows, `tip-win-loss-${new Date().toISOString().slice(0,10)}.csv`);
    }
    return res.json({ success: true, events: result.rows, count: result.rows.length });
  } catch (err) {
    return res.status(500).json({ success: false, error: String(err) });
  }
});

// ── GET /api/win-loss/summary — Aggregate analytics ─────────────────────────
winLossRouter.get("/summary", async (req: Request, res: Response) => {
  const days = Math.min(parseInt(req.query.days as string) || 90, 730);

  try {
    const [overall, bySegment, byFormFactor, priceDeltas] = await Promise.all([
      pool.query(`
        SELECT
          COUNT(*)                                            AS total_events,
          COUNT(*) FILTER (WHERE outcome = 'won')            AS won,
          COUNT(*) FILTER (WHERE outcome = 'lost')           AS lost,
          ROUND(
            COUNT(*) FILTER (WHERE outcome = 'won')::numeric
            / NULLIF(COUNT(*) FILTER (WHERE outcome IN ('won','lost')), 0) * 100, 1
          )                                                   AS win_rate_pct,
          ROUND(AVG(our_price) FILTER (WHERE outcome = 'won')::numeric, 2)  AS avg_win_price,
          ROUND(AVG(our_price) FILTER (WHERE outcome = 'lost')::numeric, 2) AS avg_loss_price
        FROM win_loss_events
        WHERE deal_date >= CURRENT_DATE - INTERVAL '${days} days'
      `),
      pool.query(`
        SELECT customer_segment,
          COUNT(*)                                            AS total,
          COUNT(*) FILTER (WHERE outcome = 'won')            AS won,
          COUNT(*) FILTER (WHERE outcome = 'lost')           AS lost,
          ROUND(COUNT(*) FILTER (WHERE outcome = 'won')::numeric
            / NULLIF(COUNT(*) FILTER (WHERE outcome IN ('won','lost')),0)*100,1) AS win_rate_pct
        FROM win_loss_events
        WHERE deal_date >= CURRENT_DATE - INTERVAL '${days} days'
          AND customer_segment IS NOT NULL
        GROUP BY customer_segment
        ORDER BY total DESC
      `),
      pool.query(`
        SELECT COALESCE(wl.form_factor, tx.form_factor) AS form_factor,
          COUNT(*)                                   AS total,
          COUNT(*) FILTER (WHERE outcome = 'won')    AS won,
          COUNT(*) FILTER (WHERE outcome = 'lost')   AS lost
        FROM win_loss_events wl
        LEFT JOIN transceivers tx ON tx.id = wl.transceiver_id
        WHERE deal_date >= CURRENT_DATE - INTERVAL '${days} days'
        GROUP BY COALESCE(wl.form_factor, tx.form_factor)
        HAVING COALESCE(wl.form_factor, tx.form_factor) IS NOT NULL
        ORDER BY total DESC
      `),
      // Price delta analysis: where we lost — how far off were we?
      pool.query(`
        SELECT
          ROUND(AVG(competitor_price - our_price)::numeric, 2)   AS avg_price_gap,
          ROUND(AVG((competitor_price - our_price) / NULLIF(our_price,0) * 100)::numeric, 1) AS avg_gap_pct,
          COUNT(*)                                                 AS events_with_prices
        FROM win_loss_events
        WHERE outcome = 'lost'
          AND our_price IS NOT NULL AND competitor_price IS NOT NULL
          AND deal_date >= CURRENT_DATE - INTERVAL '${days} days'
      `),
    ]);

    return res.json({
      success: true,
      days,
      overall: overall.rows[0],
      by_segment: bySegment.rows,
      by_form_factor: byFormFactor.rows,
      price_delta: priceDeltas.rows[0],
    });
  } catch (err) {
    return res.status(500).json({ success: false, error: String(err) });
  }
});

// ── GET /api/win-loss/competitors — Competitor ranking ───────────────────────
winLossRouter.get("/competitors", async (req: Request, res: Response) => {
  const days = Math.min(parseInt(req.query.days as string) || 90, 730);

  try {
    const result = await pool.query(`
      SELECT
        competitor_vendor,
        COUNT(*)                                         AS encounters,
        COUNT(*) FILTER (WHERE outcome = 'lost')        AS losses_to,
        COUNT(*) FILTER (WHERE outcome = 'won')         AS wins_against,
        ROUND(AVG(competitor_price - our_price)
          FILTER (WHERE outcome = 'lost' AND our_price IS NOT NULL AND competitor_price IS NOT NULL)
          ::numeric, 2)                                  AS avg_price_advantage,  -- negative = they beat us on price
        ROUND(AVG(competitor_price)::numeric, 2)         AS avg_competitor_price
      FROM win_loss_events
      WHERE deal_date >= CURRENT_DATE - INTERVAL '${days} days'
        AND competitor_vendor IS NOT NULL
      GROUP BY competitor_vendor
      ORDER BY losses_to DESC, encounters DESC
      LIMIT 30
    `);

    return res.json({ success: true, competitors: result.rows });
  } catch (err) {
    return res.status(500).json({ success: false, error: String(err) });
  }
});
