// Spot tab — UI для спотового трейдинга (Binance / Bybit / OKX).
// Стиль: тот же что Futures (consistency §4 из ui-ux-pro-max).
// Skeleton на загрузках (§3 performance), tabular-numbers для финансов (§6).

const SpotTab = ({ activeEx, period, periodParams, rangeStr, setPeriod, applyCustom }) => {
  const { t } = useLang();
  const [balances, setBalances] = useState([]);
  const [analytics, setAnalytics] = useState(null);
  const [fills, setFills] = useState([]);
  const [loading, setLoading] = useState(false);
  const [loadingHeavy, setLoadingHeavy] = useState(false);
  const [error, setError] = useState("");

  // Fetch baланса
  const loadLight = useCallback(async () => {
    if (!window.creds.hasActive()) return;
    setLoading(true);
    try {
      const r = await fetch(`/api/ex/${activeEx}/spot/balance`, { headers: window.creds.headers() });
      if (!r.ok) {
        const text = await r.text();
        throw new Error(`HTTP ${r.status}: ${text}`);
      }
      const data = await r.json();
      setBalances(Array.isArray(data) ? data : []);
      setError("");
    } catch (e) {
      setError(e.message || String(e));
    } finally {
      setLoading(false);
    }
  }, [activeEx]);

  // Fetch тяжёлых: fills + analytics
  const loadHeavy = useCallback(async () => {
    if (!window.creds.hasActive()) return;
    setFills([]); setAnalytics(null);
    setLoadingHeavy(true);
    try {
      const base = "/api/ex/" + activeEx + "/spot";
      const [fillsResp, analyticsResp] = await Promise.allSettled([
        fetch(base + "/fills?" + periodParams.toString(), { headers: window.creds.headers() }).then(r => r.json()),
        fetch(base + "/analytics?" + periodParams.toString(), { headers: window.creds.headers() }).then(r => r.json()),
      ]);
      if (fillsResp.status === "fulfilled") {
        setFills(fillsResp.value?.fills || []);
      }
      if (analyticsResp.status === "fulfilled") {
        setAnalytics(analyticsResp.value);
      }
    } finally {
      setLoadingHeavy(false);
    }
  }, [activeEx, periodParams]);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      await loadLight();
      if (cancelled) return;
      await loadHeavy();
    })();
    return () => { cancelled = true; };
  }, [activeEx, periodParams, loadLight, loadHeavy]);

  if (error) {
    return (
      <div style={{ padding: "60px 16px" }}>
        <div className="empty" style={{ padding: "30px 24px", maxWidth: 520, margin: "0 auto" }}>
          <div className="empty-icon"><Icon name="alert" size={20} /></div>
          <div className="empty-title">Spot недоступен</div>
          <div className="empty-msg">{error.substring(0, 300)}</div>
          <button className="btn" onClick={loadLight} style={{ marginTop: 12 }}>
            <Icon name="refresh" size={12} /> {t("retry")}
          </button>
        </div>
      </div>
    );
  }

  const totalValue = balances.reduce((s, b) => s + (b.valueUSDT || 0), 0);
  const totalBalance = balances.length;

  return (
    <>
      {/* Hero: общая стоимость кошелька */}
      <div className="section">
        <div className="hero-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))" }}>
          <div className="hero-tile">
            <div className="tile-label"><Icon name="wallet" size={12} /> {t("spot_balances")}</div>
            <div className="tile-value">
              {loading ? <span className="skel-bar" style={{ width: 120, height: 24 }} /> : (
                <>{fmtMoney(totalValue)} <span className="ccy">USDT</span></>
              )}
            </div>
            <div className="tile-sub">{totalBalance} {totalBalance === 1 ? "asset" : "assets"}</div>
          </div>
          {analytics && (
            <>
              <div className="hero-tile">
                <div className="tile-label"><Icon name="activity" size={12} /> {t("spot_volume")}</div>
                <div className="tile-value">{fmtMoney(analytics.total_volume_usdt)} <span className="ccy">USDT</span></div>
                <div className="tile-sub">{analytics.fills_total} fills</div>
              </div>
              <div className="hero-tile">
                <div className="tile-label"><Icon name="coins" size={12} /> {t("spot_fees")}</div>
                <div className="tile-value neg">{fmtMoney(analytics.total_fees, 4)}</div>
                <div className="tile-sub">approx. {((analytics.total_fees / Math.max(analytics.total_volume_usdt, 1)) * 100).toFixed(3)}%</div>
              </div>
              <div className="hero-tile">
                <div className="tile-label"><Icon name="grid" size={12} /> Buy / Sell</div>
                <div className="tile-value">
                  <span className="pos">{analytics.buys_count}</span>
                  <span style={{ color: "var(--text-4)", fontSize: 14 }}> / </span>
                  <span className="neg">{analytics.sells_count}</span>
                </div>
                <div className="tile-sub">
                  <span className="pos mono">{fmtMoney(analytics.buy_volume)}$</span>
                  <span style={{ color: "var(--text-4)" }}> · </span>
                  <span className="neg mono">{fmtMoney(analytics.sell_volume)}$</span>
                </div>
              </div>
            </>
          )}
        </div>
      </div>

      {/* Балансы */}
      <div className="section">
        <div className="section-head">
          <div className="section-title">
            <Icon name="coins" size={11} /> {t("spot_balances")}
            <span className="count">{balances.length}</span>
          </div>
        </div>
        <SpotBalancesTable balances={balances} loading={loading} />
      </div>

      {/* Период */}
      <div className="section">
        <PeriodBar period={period} setPeriod={setPeriod} range={rangeStr} onApplyCustom={applyCustom} />
      </div>

      {/* Top symbols + daily volume */}
      {loadingHeavy ? <div className="section"><SkeletonCards count={2} /></div> : analytics && (
        <>
          {analytics.top_symbols.length > 0 && (
            <div className="section">
              <div className="section-head">
                <div className="section-title"><Icon name="barchart" size={11} /> {t("spot_top_symbols")}</div>
              </div>
              <SpotTopSymbolsTable symbols={analytics.top_symbols} />
            </div>
          )}
          {analytics.daily.length > 0 && (
            <div className="section">
              <SpotDailyVolume daily={analytics.daily} />
            </div>
          )}
        </>
      )}

      {/* История */}
      <div className="section">
        <div className="section-head">
          <div className="section-title">
            <Icon name="list" size={11} /> {t("spot_history")}
            <span className="count">{fills.length}</span>
          </div>
        </div>
        {loadingHeavy ? <SkeletonRows rows={6} cols={7} /> : <SpotFillsTable fills={fills} />}
      </div>
    </>
  );
};

// ---------- Balances table ----------
const SpotBalancesTable = ({ balances, loading }) => {
  const { t } = useLang();
  if (loading) return <SkeletonRows rows={4} cols={4} />;
  if (!balances.length) {
    return <EmptyCard title={t("spot_no_balances")} msg={t("spot_no_balances_msg")} icon="wallet" />;
  }
  const sorted = [...balances].sort((a, b) => (b.valueUSDT || b.total) - (a.valueUSDT || a.total));
  return (
    <div className="card" style={{ overflow: "auto" }}>
      <table className="tbl">
        <thead>
          <tr>
            <th>{t("symbol")}</th>
            <th className="num">{t("free")}</th>
            <th className="num">{t("locked_short")}</th>
            <th className="num">{t("total")}</th>
            <th className="num">{t("value_usdt")}</th>
          </tr>
        </thead>
        <tbody>
          {sorted.map((b, i) => {
            // Бейджи: где лежат монеты (TON в Earn, BTC в Funding и т.д.)
            const badges = [];
            if (b.earnAmt > 0) badges.push({ label: "EARN", color: "var(--long)", amt: b.earnAmt });
            if (b.fundingAmt > 0) badges.push({ label: "FUND", color: "var(--warn)", amt: b.fundingAmt });
            return (
              <tr key={b.asset + i} title={badges.length ? badges.map(x => `${x.label}: ${x.amt}`).join(" · ") : ""}>
                <td>
                  <span className="sym" style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
                    <CoinIcon sym={b.asset} /> {b.asset}
                    {badges.map(bd => (
                      <span key={bd.label} style={{
                        fontSize: 9.5, fontWeight: 600, letterSpacing: "0.06em",
                        padding: "1px 5px", borderRadius: 3,
                        border: "1px solid " + bd.color, color: bd.color,
                        fontFamily: "var(--font-mono)",
                      }}>{bd.label}</span>
                    ))}
                  </span>
                </td>
                <td className="num mono">{fmtMoney(b.free, 6)}</td>
                <td className="num mono muted">{b.locked > 0 ? fmtMoney(b.locked, 6) : "—"}</td>
                <td className="num mono">{fmtMoney(b.total, 6)}</td>
                <td className="num mono" style={{ fontWeight: 500 }}>
                  {b.valueUSDT > 0 ? fmtMoney(b.valueUSDT, 2) : "—"}
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

// ---------- Top symbols ----------
const SpotTopSymbolsTable = ({ symbols }) => {
  const { t } = useLang();
  return (
    <div className="card" style={{ overflow: "auto" }}>
      <table className="tbl">
        <thead>
          <tr>
            <th>{t("symbol")}</th>
            <th className="num">Fills</th>
            <th className="num">B / S</th>
            <th className="num">Volume USDT</th>
            <th className="num">Fees</th>
          </tr>
        </thead>
        <tbody>
          {symbols.map((s, i) => (
            <tr key={s.symbol + i}>
              <td><span className="sym"><CoinIcon sym={s.symbol.replace(/USDT$/, "").replace(/USDC$/, "")} /> {s.symbol}</span></td>
              <td className="num mono">{s.fills}</td>
              <td className="num mono">
                <span className="pos">{s.buys}</span>
                <span style={{ color: "var(--text-4)" }}> / </span>
                <span className="neg">{s.sells}</span>
              </td>
              <td className="num mono">{fmtMoney(s.volume)}</td>
              <td className="num mono muted">{fmtMoney(s.fees, 4)}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

// ---------- Daily volume bars ----------
const SpotDailyVolume = ({ daily }) => {
  const { t } = useLang();
  const wrapRef = useRef(null);
  const [hover, setHover] = useState(null);
  if (!daily || daily.length === 0) return null;
  const max = Math.max(1, ...daily.map(d => d.volume));
  const total = daily.reduce((s, d) => s + d.volume, 0);
  const barWidth = 100 / daily.length;

  const onMove = (e) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
    const i = Math.min(daily.length - 1, Math.floor(ratio * daily.length));
    const wrapRect = wrapRef.current.getBoundingClientRect();
    setHover({ i, x: e.clientX - wrapRect.left, y: e.clientY - wrapRect.top });
  };

  return (
    <div className="daily-bars" ref={wrapRef} style={{ position: "relative" }}>
      <div className="daily-bars-head">
        <div className="section-title" style={{ margin: 0 }}><Icon name="barchart" size={11} /> {t("spot_daily_volume")}</div>
        <div className="mono muted" style={{ fontSize: 11 }}>{daily.length} days · {fmtMoney(total)} USDT total</div>
      </div>
      <svg className="daily-bars-svg" viewBox="0 0 100 60" preserveAspectRatio="none" style={{ height: 60 }}
        onMouseMove={onMove} onMouseLeave={() => setHover(null)}>
        {daily.map((d, i) => {
          const h = (d.volume / max) * 56;
          const x = i * barWidth;
          const y = 60 - h;
          const isHover = hover && hover.i === i;
          return (
            <rect key={d.date}
              x={x + barWidth * 0.1} y={y}
              width={barWidth * 0.8} height={Math.max(0.5, h)}
              fill="var(--accent)" opacity={isHover ? 1 : 0.75}
            />
          );
        })}
      </svg>
      {hover && daily[hover.i] && (
        <div className="crosshair-tip" style={{
          left: Math.min((wrapRef.current?.clientWidth || 500) - 180, Math.max(8, hover.x + 12)),
          top: Math.max(8, hover.y - 60),
        }}>
          <div style={{ fontSize: 10, color: "var(--text-3)", marginBottom: 2 }}>{daily[hover.i].date}</div>
          <div style={{ fontSize: 13, fontWeight: 500 }} className="mono">{fmtMoney(daily[hover.i].volume)} <span style={{ color: "var(--text-3)", fontSize: 10 }}>USDT</span></div>
          <div style={{ fontSize: 10.5, color: "var(--text-3)" }}>
            {daily[hover.i].fills} fills · <span className="pos">{daily[hover.i].buys}B</span> / <span className="neg">{daily[hover.i].sells}S</span>
          </div>
        </div>
      )}
    </div>
  );
};

// ---------- Fills table (с пагинацией как у Futures Closed Trades) ----------
const SpotFillsTable = ({ fills }) => {
  const { t } = useLang();
  const PAGE = 30;
  const [shown, setShown] = useState(PAGE);
  useEffect(() => { setShown(PAGE); }, [fills]);

  if (!fills.length) {
    return <EmptyCard title={t("spot_no_history")} msg={t("spot_no_history_msg")} />;
  }
  // Новые сверху
  const sorted = [...fills].sort((a, b) => (b.time || 0) - (a.time || 0));
  const visible = sorted.slice(0, shown);
  const remaining = sorted.length - visible.length;

  return (
    <div className="card" style={{ overflow: "auto" }}>
      <table className="tbl">
        <thead>
          <tr>
            <th>Time</th>
            <th>{t("symbol")}</th>
            <th>{t("side")}</th>
            <th className="num">{t("qty")}</th>
            <th className="num">{t("price")}</th>
            <th className="num">Quote</th>
            <th className="num">{t("fee")}</th>
            <th>M/T</th>
          </tr>
        </thead>
        <tbody>
          {visible.map((f, i) => {
            const sym = String(f.symbol || "");
            const base = sym.replace(/USDT$/, "").replace(/USDC$/, "").replace(/BUSD$/, "");
            const side = String(f.side || "").toUpperCase();
            return (
              <tr key={f.id + ":" + i}>
                <td className="mono muted" style={{ fontSize: 11.5 }}>{fmtTime(f.time)}</td>
                <td><span className="sym"><CoinIcon sym={base} /> {sym}</span></td>
                <td>
                  <span className={"pill " + (side === "BUY" ? "long" : "short")}>{side}</span>
                </td>
                <td className="num mono">{fmtMoney(f.qty, 6)}</td>
                <td className="num mono">{fmtPrice(f.price)}</td>
                <td className="num mono">{fmtMoney(f.quoteQty, 2)}</td>
                <td className="num mono muted">{fmtMoney(f.commission, 6)} {f.commissionAsset}</td>
                <td className="mono muted" style={{ fontSize: 10.5 }}>{f.isMaker ? "M" : "T"}</td>
              </tr>
            );
          })}
          {remaining > 0 && (
            <tr className="load-more-row">
              <td colSpan={8}>
                <button className="load-more-btn" onClick={() => setShown(s => s + PAGE)}>
                  {t("load_more")} (+{Math.min(PAGE, remaining)})
                </button>
                <div className="muted mono" style={{ fontSize: 10.5, marginTop: 6 }}>
                  {visible.length} {t("shown_of")} {sorted.length}
                </div>
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </div>
  );
};

Object.assign(window, { SpotTab });
