/**
 * market.js — Express router
 *
 * GET /api/market/live                      → all tickers (forex + stocks + crypto)
 * GET /api/market/live/fx                   → all forex tickers
 * GET /api/market/live/stocks               → all stock tickers
 * GET /api/market/live/crypto               → all crypto tickers
 * GET /api/market/live/:symbol              → single ticker (searches all services)
 * POST /api/market/live/symbols             → body: { symbols: ["EURUSD","AAPL"] }
 * GET  /api/market/live/symbols?s=EURUSD,AAPL,BTCUSDT → same via query param
 */

"use strict";

const express    = require("express");
const router     = express.Router();
const forexData  = require("../services/forexMarketData");
const stockData  = require("../services/stockMarketData");
const cryptoData = require("../services/cryptoMarketData");

// Start all services on router load — safe to call even if already started
forexData.start();                             
stockData.start();
cryptoData.start();

// ─── Helpers ──────────────────────────────────────────────────────────────────

/**
 * Look up a single symbol across all three services.
 * Returns the ticker object or null if not found anywhere.
 */
function findTicker(symbol) {
  const sym = String(symbol ?? "").toUpperCase();
  return (
    forexData.getTicker(sym)  ??
    stockData.getTicker(sym)  ??
    cryptoData.getTicker(sym) ??
    null
  );
}

/**
 * Merge all tickers from all services into a single { [symbol]: ticker } map.
 */
function getAllMap() {
  const map = {};
  for (const t of forexData.getAllTickers())  map[t.symbol] = t;
  for (const t of stockData.getAllTickers())  map[t.symbol] = t;
  for (const t of cryptoData.getAllTickers()) map[t.symbol] = t;
  return map;
}

/**
 * Parse a symbol list from either a POST body or GET query param.
 * Accepts:
 *   POST body:  { symbols: ["EURUSD", "AAPL"] }
 *   GET query:  ?s=EURUSD,AAPL,BTCUSDT   or   ?symbols=EURUSD,AAPL
 *
 * Returns a cleaned, de-duped, uppercased string array.
 */
function parseSymbolList(req) {
  // POST body
  const bodyList = req.body?.symbols;
  if (Array.isArray(bodyList) && bodyList.length) {
    return [...new Set(
      bodyList.map(s => String(s).toUpperCase().trim()).filter(Boolean)
    )];
  }

  // GET query — ?s=... or ?symbols=...
  const raw = req.query?.s ?? req.query?.symbols ?? "";
  if (raw) {
    return [...new Set(
      String(raw).split(",").map(s => s.toUpperCase().trim()).filter(Boolean)
    )];
  }

  return [];
}

// ─── Routes ───────────────────────────────────────────────────────────────────

// GET /live — all tickers across all asset classes
router.get("/live", (req, res) => {
  const data = getAllMap();
  res.json({
    success:   true,
    data,
    count:     Object.keys(data).length,
    updatedAt: Date.now(),
  });
});

// GET /live/fx — all forex tickers
router.get("/live/fx", (req, res) => {
  const data = {};
  for (const t of forexData.getAllTickers()) data[t.symbol] = t;
  res.json({
    success:   true,
    data,
    count:     Object.keys(data).length,
    updatedAt: Date.now(),
  });
});

// GET /live/stocks — all stock tickers
router.get("/live/stocks", (req, res) => {
  const data = {};
  for (const t of stockData.getAllTickers()) data[t.symbol] = t;
  res.json({
    success:   true,
    data,
    count:     Object.keys(data).length,
    updatedAt: Date.now(),
  });
});

// GET /live/crypto — all crypto tickers
router.get("/live/crypto", (req, res) => {
  const data = {};
  for (const t of cryptoData.getAllTickers()) data[t.symbol] = t;
  res.json({
    success:   true,
    data,
    count:     Object.keys(data).length,
    updatedAt: Date.now(),
  });
});

// POST /live/symbols  — body: { symbols: ["EURUSD", "AAPL", "BTCUSDT"] }
// GET  /live/symbols  — query: ?s=EURUSD,AAPL,BTCUSDT  or  ?symbols=EURUSD,AAPL
router.get("/live/symbols",  handleSymbolList);
router.post("/live/symbols", handleSymbolList);

function handleSymbolList(req, res) {
  const list = parseSymbolList(req);

  if (!list.length) {
    return res.status(400).json({
      success: false,
      message: "Provide symbols via POST body { symbols: [...] } or GET query ?s=SYM1,SYM2",
    });
  }

  const found   = {};
  const missing = [];

  for (const sym of list) {
    const ticker = findTicker(sym);
    if (ticker) {
      found[sym] = ticker;
    } else {
      missing.push(sym);
    }
  }

  res.json({
    success:   true,
    data:      found,
    count:     Object.keys(found).length,
    missing,              // caller knows exactly which symbols weren't available
    updatedAt: Date.now(),
  });
}

// GET /live/:symbol — single ticker, searches all services
// ⚠ Must be declared AFTER all static sub-routes (/fx, /stocks, /crypto, /symbols)
//   so Express doesn't swallow them as :symbol params.
router.get("/live/:symbol", (req, res) => {
  const symbol = String(req.params.symbol ?? "").toUpperCase();
  const ticker = findTicker(symbol);

  if (!ticker) {
    return res.status(404).json({
      success: false,
      message: `${symbol} not found — check symbol or wait for services to initialise`,
    });
  }

  res.json({ success: true, data: ticker });
});

module.exports = router;