// Coin risk classification.
//
// Tags every symbol with one of three flags so operators can see, at a glance,
// how established the underlying asset is before approving a trade. The
// classification is heuristic (based on well-known majors and mid-caps) and
// lives entirely on the client — no backend round-trip.
//
// - safe:       BTC, ETH — deepest liquidity, tightest spreads
// - moderate:   Established layer-1s / top-30 majors
// - vulnerable: Everything else (memes, low-caps, illiquid alts)

import { useEffect, useState } from "react";

export type CoinRisk = "safe" | "moderate" | "vulnerable";

export const COIN_RISK_LEVELS: readonly CoinRisk[] = ["safe", "moderate", "vulnerable"];

const SAFE = new Set(["BTC", "ETH", "XBT"]);

const MODERATE = new Set([
  "SOL", "BNB", "XRP", "ADA", "AVAX", "DOT", "LINK", "MATIC", "POL",
  "LTC", "TRX", "DOGE", "ATOM", "NEAR", "ARB", "OP", "TON", "UNI",
  "ICP", "XLM", "BCH", "FIL", "APT", "SUI", "HBAR", "INJ", "AAVE",
  "ETC", "XMR", "TAO", "SEI", "RUNE", "IMX", "LDO", "MKR", "RENDER",
  "PEPE", "SHIB", "WLD", "STX", "FTM", "ALGO", "VET", "GRT",
]);

/** Extract the base asset from Delta perpetual/spot symbols. */
export function baseAsset(symbol: string): string {
  const s = String(symbol ?? "").toUpperCase();
  // Delta perp/futures use forms like BTCUSD, BTCUSDT, BTC-25JAN-C-45000
  const stripped = s.replace(/[-_/].*$/, "");
  for (const q of ["USDT", "USDC", "USD", "BUSD", "INR"]) {
    if (stripped.endsWith(q) && stripped.length > q.length) {
      return stripped.slice(0, -q.length);
    }
  }
  return stripped;
}

export function getCoinRisk(symbol: string): CoinRisk {
  const base = baseAsset(symbol);
  if (SAFE.has(base)) return "safe";
  if (MODERATE.has(base)) return "moderate";
  return "vulnerable";
}

export const RISK_META: Record<
  CoinRisk,
  { label: string; short: string; tone: string; dot: string; description: string }
> = {
  safe: {
    label: "Safe",
    short: "S",
    tone: "border-emerald-400/50 bg-emerald-500/10 text-emerald-300",
    dot: "bg-emerald-400",
    description: "Deep liquidity, tight spreads (BTC, ETH).",
  },
  moderate: {
    label: "Moderate",
    short: "M",
    tone: "border-amber-400/50 bg-amber-500/10 text-amber-300",
    dot: "bg-amber-400",
    description: "Established majors — normal volatility.",
  },
  vulnerable: {
    label: "Vulnerable",
    short: "V",
    tone: "border-rose-400/50 bg-rose-500/10 text-rose-300",
    dot: "bg-rose-400",
    description: "Low-cap / illiquid — higher slippage and gap risk.",
  },
};

// ---------------------------------------------------------------------------
// User preference: which risk tiers are visible / tradable.

const KEY = "delta-terminal:allowed-risk-levels";
const DEFAULT: CoinRisk[] = ["safe", "moderate", "vulnerable"];

function read(): CoinRisk[] {
  if (typeof window === "undefined") return DEFAULT;
  try {
    const raw = window.localStorage.getItem(KEY);
    if (!raw) return DEFAULT;
    const arr = JSON.parse(raw);
    if (!Array.isArray(arr)) return DEFAULT;
    const filtered = arr.filter((x): x is CoinRisk =>
      x === "safe" || x === "moderate" || x === "vulnerable",
    );
    return filtered.length ? filtered : DEFAULT;
  } catch {
    return DEFAULT;
  }
}

export function getAllowedRiskLevels(): CoinRisk[] {
  return read();
}

export function isRiskAllowed(symbol: string): boolean {
  return read().includes(getCoinRisk(symbol));
}

export function useAllowedRiskLevels(): {
  levels: CoinRisk[];
  toggle: (l: CoinRisk) => void;
  set: (l: CoinRisk[]) => void;
} {
  const [levels, setLevels] = useState<CoinRisk[]>(() => read());
  useEffect(() => {
    const sync = () => setLevels(read());
    window.addEventListener("storage", sync);
    window.addEventListener("delta-terminal:prefs-changed", sync);
    return () => {
      window.removeEventListener("storage", sync);
      window.removeEventListener("delta-terminal:prefs-changed", sync);
    };
  }, []);
  const write = (next: CoinRisk[]) => {
    const uniq = Array.from(new Set(next));
    // Never persist an empty list — that would hide everything and
    // confuse users; fall back to "all".
    const value = uniq.length ? uniq : DEFAULT;
    window.localStorage.setItem(KEY, JSON.stringify(value));
    window.dispatchEvent(new Event("delta-terminal:prefs-changed"));
    setLevels(value);
  };
  return {
    levels,
    toggle: (l) => write(levels.includes(l) ? levels.filter((x) => x !== l) : [...levels, l]),
    set: write,
  };
}
