// portfolio-atoms.jsx — shared themeable atoms (CSS-var driven)
// Each screen wrapper defines: --bg --card --card2 --border --border-soft
//   --text --muted --dim --accent --accent-soft --pos --neg --pos-soft --neg-soft
// Exports to window: Dot, Pnl, ShareBar, RangeBadge, Ticker, Sparkdots, signClass

const { useState } = React;

function signClass(v) {
  return v >= 0 ? "pos" : "neg";
}

// colored status dot
function Dot({ color, size = 8, glow }) {
  return (
    <span
      style={{
        display: "inline-block",
        width: size,
        height: size,
        borderRadius: 999,
        background: color,
        boxShadow: glow ? `0 0 0 3px ${glow}` : "none",
        flex: "none",
      }}
    />
  );
}

// PnL value text, colored
function Pnl({ children, v, weight = 600, size }) {
  const pos = v >= 0;
  return (
    <span
      style={{
        color: pos ? "var(--pos)" : "var(--neg)",
        fontWeight: weight,
        fontSize: size,
        fontVariantNumeric: "tabular-nums",
        whiteSpace: "nowrap",
      }}
    >
      {children}
    </span>
  );
}

// mini share-of-portfolio bar with number
function ShareBar({ pct, width = 56, accent = "var(--bar, var(--accent))", showNum = true, max = 50 }) {
  const w = Math.max(2, Math.min(100, (pct / max) * 100));
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 8 }}>
      <span
        style={{
          position: "relative",
          width,
          height: 5,
          borderRadius: 999,
          background: "var(--border)",
          overflow: "hidden",
          flex: "none",
        }}
      >
        <span
          style={{
            position: "absolute",
            inset: 0,
            width: w + "%",
            background: accent,
            borderRadius: 999,
          }}
        />
      </span>
      {showNum && (
        <span style={{ color: "var(--muted)", fontVariantNumeric: "tabular-nums", fontSize: 12.5 }}>
          {window.fmt.pct(pct)}
        </span>
      )}
    </span>
  );
}

// LP range status badge
function RangeBadge({ inRange }) {
  return (
    <span
      style={{
        display: "inline-flex",
        alignItems: "center",
        gap: 6,
        padding: "3px 9px 3px 7px",
        borderRadius: 999,
        fontSize: 11.5,
        fontWeight: 600,
        letterSpacing: 0.1,
        color: inRange ? "var(--pos)" : "var(--neg)",
        background: inRange ? "var(--pos-soft)" : "var(--neg-soft)",
        border: `1px solid ${inRange ? "var(--pos-line, transparent)" : "var(--neg-line, transparent)"}`,
        whiteSpace: "nowrap",
      }}
    >
      <Dot color={inRange ? "var(--pos)" : "var(--neg)"} size={6} />
      {inRange ? "в диапазоне" : "вне диапазона"}
    </span>
  );
}

// real crypto coin logos — crisp inline SVG brand marks
function Glyph({ ch, dx = 16, dy = 21.5, fs = 17 }) {
  return (
    <text x={dx} y={dy} textAnchor="middle" fontSize={fs} fontWeight="700" fill="#fff"
      fontFamily="'Helvetica Neue', Arial, sans-serif">{ch}</text>
  );
}

const LOGOS = {
  BTC: () => (
    <g><circle cx="16" cy="16" r="16" fill="#F7931A" /><Glyph ch="₿" fs="18" dy="22" /></g>
  ),
  cbBTC: () => (
    <g>
      <circle cx="16" cy="16" r="16" fill="#F7931A" />
      <Glyph ch="₿" fs="18" dy="22" />
      <circle cx="25" cy="25" r="6" fill="#0052FF" stroke="var(--card)" strokeWidth="1.5" />
      <circle cx="25" cy="25" r="2.1" fill="#fff" />
    </g>
  ),
  ETH: () => (
    <g>
      <circle cx="16" cy="16" r="16" fill="#627EEA" />
      <polygon points="16,5 23.5,16.3 16,20.7 8.5,16.3" fill="#fff" fillOpacity="0.95" />
      <polygon points="16,22.1 23.5,17.8 16,27 8.5,17.8" fill="#fff" fillOpacity="0.6" />
    </g>
  ),
  SOL: () => (
    <g>
      <defs>
        <linearGradient id="solg" x1="4" y1="24" x2="28" y2="8" gradientUnits="userSpaceOnUse">
          <stop offset="0" stopColor="#9945FF" /><stop offset="1" stopColor="#14F195" />
        </linearGradient>
      </defs>
      <circle cx="16" cy="16" r="16" fill="url(#solg)" />
      <polygon points="8.5,10 25,10 23.5,12.6 7,12.6" fill="#fff" />
      <polygon points="7,15 23.5,15 25,17.6 8.5,17.6" fill="#fff" />
      <polygon points="8.5,20 25,20 23.5,22.6 7,22.6" fill="#fff" />
    </g>
  ),
  USDC: () => (
    <g><circle cx="16" cy="16" r="16" fill="#2775CA" /><Glyph ch="$" fs="18" dy="22" /></g>
  ),
  USDT: () => (
    <g><circle cx="16" cy="16" r="16" fill="#26A17B" /><Glyph ch="₮" fs="17" dy="22" /></g>
  ),
};

// Логотипы остальных монет — настоящие иконки CoinGecko (для тех, у кого нет
// рисованного SVG выше). Грузятся как <img>. Новую монету достаточно добавить сюда.
const LOGO_URLS = {
  APT: "https://coin-images.coingecko.com/coins/images/26455/large/Aptos-Network-Symbol-Black-RGB-1x.png?1761789140",
  ARB: "https://coin-images.coingecko.com/coins/images/16547/large/arb.jpg?1721358242",
  CFG: "https://coin-images.coingecko.com/coins/images/15380/large/centrifuge.PNG?1696515027",
  DAI: "https://coin-images.coingecko.com/coins/images/9956/large/Badge_Dai.png?1696509996",
  EYWA: "https://coin-images.coingecko.com/coins/images/51242/large/Eywa.png?1730449129",
  FDUSD: "https://coin-images.coingecko.com/coins/images/31079/large/FDUSD_icon_black.png?1731097953",
  FRAX: "https://coin-images.coingecko.com/coins/images/13422/large/LFRAX.png?1751911193",
  GHO: "https://coin-images.coingecko.com/coins/images/30663/large/gho-token-logo.png?1720517092",
  GUSD: "https://coin-images.coingecko.com/coins/images/5992/large/gemini-dollar-gusd.png?1696506408",
  HBAR: "https://coin-images.coingecko.com/coins/images/3688/large/hbar.png?1696504364",
  LUSD: "https://coin-images.coingecko.com/coins/images/14666/large/Group_3.png?1696514341",
  ONDO: "https://coin-images.coingecko.com/coins/images/26580/large/ONDO.png?1696525656",
  PYUSD: "https://coin-images.coingecko.com/coins/images/31212/large/PYUSD_Token_Logo_2x.png?1765987788",
  RLUSD: "https://coin-images.coingecko.com/coins/images/39651/large/RLUSD_200x200_%281%29.png?1727376633",
  STRK: "https://coin-images.coingecko.com/coins/images/26433/large/starknet.png?1696525507",
  TUSD: "https://coin-images.coingecko.com/coins/images/3449/large/tusd.png?1696504140",
  USD0: "https://coin-images.coingecko.com/coins/images/38272/large/USD0LOGO.png?1716962811",
  USDD: "https://coin-images.coingecko.com/coins/images/25380/large/UUSD.jpg?1696524513",
  USDE: "https://coin-images.coingecko.com/coins/images/33613/large/usde.png?1733810059",
  USDP: "https://coin-images.coingecko.com/coins/images/6013/large/Pax_Dollar.png?1696506427",
  USDS: "https://coin-images.coingecko.com/coins/images/39926/large/usds.webp?1726666683",
  ZK: "https://coin-images.coingecko.com/coins/images/38043/large/ZKTokenBlack.png?1718614502",
  crvUSD: "https://coin-images.coingecko.com/coins/images/30118/large/crvusd.jpg?1746670973",
};

function Ticker({ sym, size = 28 }) {
  const draw = LOGOS[sym];
  if (draw) {
    return (
      <svg width={size} height={size} viewBox="0 0 32 32" style={{ flex: "none", display: "block" }}>
        {draw()}
      </svg>
    );
  }
  // настоящая иконка CoinGecko на белой подложке (чтобы чёрные логотипы вроде
  // APT/ZK были видны и на тёмной теме); при ошибке загрузки — fallback на букву
  const url = LOGO_URLS[sym];
  if (url) {
    return (
      <React.Fragment>
        <img
          src={url}
          alt={sym}
          width={size}
          height={size}
          loading="lazy"
          style={{ width: size, height: size, borderRadius: 999, flex: "none", display: "block", objectFit: "cover", background: "#fff" }}
          onError={(e) => {
            e.currentTarget.style.display = "none";
            if (e.currentTarget.nextSibling) e.currentTarget.nextSibling.style.display = "inline-flex";
          }}
        />
        <span style={{ width: size, height: size, borderRadius: 999, background: "var(--card2)", color: "var(--muted)", display: "none", alignItems: "center", justifyContent: "center", fontWeight: 700, fontSize: size * 0.42, flex: "none", border: "1px solid var(--border)" }}>
          {sym.slice(0, 1)}
        </span>
      </React.Fragment>
    );
  }
  // fallback: neutral circle with first letter
  return (
    <span style={{ width: size, height: size, borderRadius: 999, background: "var(--card2)", color: "var(--muted)", display: "inline-flex", alignItems: "center", justifyContent: "center", fontWeight: 700, fontSize: size * 0.42, flex: "none", border: "1px solid var(--border)" }}>
      {sym.slice(0, 1)}
    </span>
  );
}

Object.assign(window, { Dot, Pnl, ShareBar, RangeBadge, Ticker, signClass });
