/**
 * The listings whose canonical url KEEPS its dex prefix, lowercased.
 *
 * SanDisk is listed live on BOTH `xyz` and `io`, so `/trade/sndk` names two
 * markets. The bare url stays with `xyz` — it is the deeper market and the one
 * already indexed and shared — and the `io` listing takes `/trade/io:sndk`
 * rather than being unreachable behind whichever listing `getPerpsAsset`
 * happened to rank first. Both keep the ticker they actually trade under; only
 * the url disambiguates, because a display name is the exchange's to set and a
 * renamed SanDisk would be wrong on every surface, not just this one.
 *
 * Keys are the FULL `dex:symbol` name, which is also the value this returns —
 * that is what keeps the function idempotent for a prefixed listing:
 * re-applying it finds `io:sndk` in here and hands it straight back.
 */
const PREFIXED_URL_SYMBOLS: ReadonlySet<string> = new Set(['io:sndk'])

/**
 * The canonical name `/trade/[...urlSymbol]` resolves WITHOUT a redirect: the
 * market's DISPLAY name, lowercased, with no dex prefix at all.
 *
 * This is the single definition of that rule, and it exists as its own export
 * for one reason: every place that needed the rule used to restate it. Call it
 * rather than interpolating a symbol into a path — `ROUTES.TRADE_SYMBOL` does,
 * so most callers get it for free.
 *
 * WHY NO DEX PREFIX. Urls used to carry one for external dexes (`xyz:PLTR`),
 * because a ticker could in principle name a listing on more than one dex. In
 * practice the dexes we surface (main Hyperliquid, our `mkts`, and `xyz`) share
 * no live ticker, so the prefix bought nothing and cost every reader, every
 * share link and every bot a piece of Hyperliquid trivia. If a real collision
 * ever ships, re-introduce the prefix HERE for that one listing — not as a
 * blanket rule.
 *
 * ONE COLLISION HAS SINCE SHIPPED, and it is handled exactly that way — see
 * `PREFIXED_URL_SYMBOLS`. Everything else still resolves bare.
 *
 * Two things that follow from the shape, both of which have already shipped
 * bugs in the prefixed version of this rule:
 *
 * 1. IT IS IDEMPOTENT, AND IT ACCEPTS RAW HYPERLIQUID NAMES. `hyperliquidSymbol`
 *    is prefixed for every HIP-3 dex INCLUDING our own (`mkts:US500`), so
 *    passing one is the common case at the call sites that only have the raw
 *    name to hand; it is stripped here rather than at each of them.
 *
 *    Idempotence is REQUIRED, not incidental: `resolveCanonicalRedirect`
 *    compares this output against the url it is already on and redirects when
 *    they differ, so an output this function would change again is a url that
 *    redirects forever. That is why the split is on the LAST colon and not the
 *    first — the dex is what precedes the first one, but taking that split
 *    leaves any remaining colon in the result, and a second pass would strip
 *    more. Splitting last is the same answer for every real name (they carry
 *    at most one colon) and is the only one that cannot move twice.
 * 2. THE URL IS THE DISPLAY NAME, NOT THE SYMBOL. The listing whose symbol is
 *    `CL` displays as `WTIOIL`, so its canonical url is `/trade/wtioil`.
 *    `/trade/cl` still resolves — `getPerpsAsset` matches the raw symbol as a
 *    last resort — but only through a canonical redirect.
 */
export const toTradeUrlSymbol = ({
  dex,
  symbol,
}: {
  /**
   * The dex the listing trades on (`''` for main Hyperliquid). Only consulted
   * to spot a `PREFIXED_URL_SYMBOLS` entry, so callers holding an
   * already-canonical `tradeUrlSymbol` can leave it off.
   */
  dex?: string
  /**
   * The DISPLAY name (override, then live annotation, then clean symbol), or a
   * raw `dex:`-prefixed Hyperliquid name — the prefix is stripped either way.
   */
  symbol: string
}): string => {
  const colon = symbol.lastIndexOf(':')
  const bare = symbol.slice(colon + 1).toLowerCase()
  // The dex the caller named, else the one already carried by `symbol` — which
  // is what makes a second pass over `io:sndk` land on the same answer.
  const prefix = (
    dex ?? (colon === -1 ? '' : symbol.slice(0, colon))
  ).toLowerCase()
  const prefixed = `${prefix}:${bare}`
  return PREFIXED_URL_SYMBOLS.has(prefixed) ? prefixed : bare
}
