const { useState, useEffect, useCallback } = React;

const API = "/api";
let ADMIN_TOKEN = (typeof window !== "undefined" && window.localStorage)
  ? (window.localStorage.getItem("ASTER_ADMIN_TOKEN") || "")
  : "";

function ensureAdminToken() {
  if (!ADMIN_TOKEN && typeof window !== "undefined") {
    const t = window.prompt("请输入 Dashboard Admin Token（一次保存）", "");
    if (t && t.trim()) {
      ADMIN_TOKEN = t.trim();
      try { window.localStorage.setItem("ASTER_ADMIN_TOKEN", ADMIN_TOKEN); } catch {}
    }
  }
  return ADMIN_TOKEN;
}

// ─── Palette: dark terminal aesthetic ───
const C = {
  bg: "#0a0e17",
  card: "#111827",
  cardHover: "#1a2236",
  border: "#1e293b",
  borderActive: "#334155",
  text: "#e2e8f0",
  textDim: "#64748b",
  textMuted: "#475569",
  accent: "#22d3ee",
  accentDim: "#0891b2",
  green: "#10b981",
  greenDim: "#065f46",
  red: "#ef4444",
  redDim: "#7f1d1d",
  yellow: "#f59e0b",
  yellowDim: "#78350f",
  purple: "#a78bfa",
};

// ─── Utility ───
const fmt = (n, d = 2) => (n !== null && n !== undefined ? Number(n).toFixed(d) : "—");
const fmtUsd = (n) => (n !== null && n !== undefined ? `$${Number(n).toFixed(2)}` : "—");

async function api(path, opts = {}) {
  try {
    const token = ensureAdminToken();
    const authHeaders = token ? { Authorization: `Bearer ${token}` } : {};
    const res = await fetch(`${API}${path}`, {
      headers: { "Content-Type": "application/json", ...authHeaders, ...(opts.headers || {}) },
      ...opts,
    });
    if (!res.ok) {
      const err = await res.json().catch(() => ({}));
      if (res.status === 401) {
        ADMIN_TOKEN = "";
        try { window.localStorage.removeItem("ASTER_ADMIN_TOKEN"); } catch {}
      }
      throw new Error(err.detail || `HTTP ${res.status}`);
    }
    return await res.json();
  } catch (e) {
    console.error(`API Error [${path}]:`, e);
    throw e;
  }
}

// ─── Components ───

function StatusDot({ active, color }) {
  const c = color || (active ? C.green : C.textMuted);
  return (
    <span
      style={{
        display: "inline-block",
        width: 8,
        height: 8,
        borderRadius: "50%",
        background: c,
        boxShadow: active ? `0 0 6px ${c}` : "none",
        marginRight: 6,
      }}
    />
  );
}

function Badge({ children, color = C.accent }) {
  return (
    <span
      style={{
        display: "inline-block",
        padding: "2px 8px",
        borderRadius: 4,
        fontSize: 11,
        fontWeight: 600,
        background: `${color}22`,
        color: color,
        border: `1px solid ${color}44`,
        letterSpacing: "0.03em",
      }}
    >
      {children}
    </span>
  );
}

function Card({ title, children, action, style = {} }) {
  return (
    <div
      style={{
        background: C.card,
        border: `1px solid ${C.border}`,
        borderRadius: 10,
        padding: "16px 20px",
        ...style,
      }}
    >
      {(title || action) && (
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
          {title && (
            <h3
              style={{
                margin: 0,
                fontSize: 13,
                fontWeight: 600,
                color: C.textDim,
                textTransform: "uppercase",
                letterSpacing: "0.08em",
              }}
            >
              {title}
            </h3>
          )}
          {action}
        </div>
      )}
      {children}
    </div>
  );
}

function Btn({ children, onClick, color = C.accent, small, disabled, style = {} }) {
  const [hover, setHover] = useState(false);
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        background: disabled ? C.textMuted : hover ? color : `${color}22`,
        color: disabled ? C.bg : hover ? C.bg : color,
        border: `1px solid ${disabled ? C.textMuted : color}`,
        borderRadius: 6,
        padding: small ? "4px 10px" : "8px 16px",
        fontSize: small ? 11 : 13,
        fontWeight: 600,
        cursor: disabled ? "not-allowed" : "pointer",
        transition: "all 0.15s",
        letterSpacing: "0.02em",
        ...style,
      }}
    >
      {children}
    </button>
  );
}

function Input({ label, value, onChange, placeholder, type = "text", style = {} }) {
  return (
    <div style={{ marginBottom: 10, ...style }}>
      {label && <label style={{ display: "block", fontSize: 11, color: C.textDim, marginBottom: 4, fontWeight: 500 }}>{label}</label>}
      <input
        type={type}
        value={value}
        onChange={(e) => onChange(e.target.value)}
        placeholder={placeholder}
        style={{
          width: "100%",
          background: C.bg,
          border: `1px solid ${C.border}`,
          borderRadius: 6,
          padding: "8px 12px",
          color: C.text,
          fontSize: 13,
          outline: "none",
          boxSizing: "border-box",
          fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
        }}
      />
    </div>
  );
}

function Select({ label, value, onChange, options, style = {} }) {
  return (
    <div style={{ marginBottom: 10, ...style }}>
      {label && <label style={{ display: "block", fontSize: 11, color: C.textDim, marginBottom: 4, fontWeight: 500 }}>{label}</label>}
      <select
        value={value}
        onChange={(e) => onChange(e.target.value)}
        style={{
          width: "100%",
          background: C.bg,
          border: `1px solid ${C.border}`,
          borderRadius: 6,
          padding: "8px 12px",
          color: C.text,
          fontSize: 13,
          outline: "none",
          boxSizing: "border-box",
        }}
      >
        {options.map((o) => (
          <option key={o.value || o} value={o.value || o}>
            {o.label || o}
          </option>
        ))}
      </select>
    </div>
  );
}

// ─── Setup Panel ───
function SetupPanel({ onConnected }) {
  const [apiKey, setApiKey] = useState("");
  const [apiSecret, setApiSecret] = useState("");
  const [baseUrl, setBaseUrl] = useState("https://fapi.asterdex.com");
  const [chain, setChain] = useState("bnb");
  const [status, setStatus] = useState(null);
  const [loading, setLoading] = useState(false);

  const connect = async () => {
    setLoading(true);
    try {
      const res = await api("/account/configure", {
        method: "POST",
        body: JSON.stringify({ api_key: apiKey, api_secret: apiSecret, base_url: baseUrl, chain }),
      });
      setStatus(res);
      if (res.status === "connected") {
        setTimeout(() => onConnected(), 500);
      }
    } catch (e) {
      setStatus({ status: "error", message: e.message });
    }
    setLoading(false);
  };

  return (
    <div style={{ maxWidth: 480, margin: "80px auto", padding: 20 }}>
      <div style={{ textAlign: "center", marginBottom: 40 }}>
        <div style={{ fontSize: 32, fontWeight: 700, color: C.accent, letterSpacing: "-0.02em" }}>⬡ ASTER</div>
        <div style={{ fontSize: 14, color: C.textDim, marginTop: 4 }}>Trading System Configuration</div>
      </div>
      <Card>
        <Input label="API Key" value={apiKey} onChange={setApiKey} placeholder="Your Aster API key" />
        <Input label="API Secret" value={apiSecret} onChange={setApiSecret} placeholder="Your Aster API secret" type="password" />
        <Input label="Base URL" value={baseUrl} onChange={setBaseUrl} />
        <Select label="Chain" value={chain} onChange={setChain} options={["bnb", "eth", "sol", "arb"]} />
        <Btn onClick={connect} disabled={!apiKey || !apiSecret || loading} style={{ width: "100%", marginTop: 10 }}>
          {loading ? "Connecting..." : "Connect to Aster"}
        </Btn>
        {status && (
          <div
            style={{
              marginTop: 12,
              padding: "8px 12px",
              borderRadius: 6,
              fontSize: 12,
              background: status.status === "connected" ? C.greenDim : C.redDim,
              color: status.status === "connected" ? C.green : C.red,
              border: `1px solid ${status.status === "connected" ? C.green : C.red}44`,
            }}
          >
            {status.message}
          </div>
        )}
      </Card>
    </div>
  );
}

// ─── Stats Row ───
function StatsRow({ stats, positions }) {
  const totalUnrealizedPnl = positions.reduce((sum, p) => sum + (p.unrealized_pnl || 0), 0);
  const items = [
    { label: "Total PnL", value: fmtUsd(stats.total_pnl), color: (stats.total_pnl || 0) >= 0 ? C.green : C.red },
    { label: "Unrealized PnL", value: fmtUsd(totalUnrealizedPnl), color: totalUnrealizedPnl >= 0 ? C.green : C.red },
    { label: "Open Positions", value: positions.length, color: C.accent },
    { label: "Total Orders", value: stats.total_orders || 0, color: C.text },
    { label: "Total Trades", value: stats.total_trades || 0, color: C.text },
    { label: "Active Alerts", value: stats.active_alerts || 0, color: (stats.active_alerts || 0) > 0 ? C.yellow : C.textDim },
  ];

  return (
    <div style={{ display: "grid", gridTemplateColumns: "repeat(6, 1fr)", gap: 12, marginBottom: 16 }}>
      {items.map((item) => (
        <div
          key={item.label}
          style={{
            background: C.card,
            border: `1px solid ${C.border}`,
            borderRadius: 8,
            padding: "12px 16px",
          }}
        >
          <div style={{ fontSize: 11, color: C.textDim, marginBottom: 4, textTransform: "uppercase", letterSpacing: "0.06em" }}>{item.label}</div>
          <div style={{ fontSize: 20, fontWeight: 700, color: item.color, fontFamily: "'JetBrains Mono', monospace" }}>{item.value}</div>
        </div>
      ))}
    </div>
  );
}

// ─── Positions Table ───
function PositionsTable({ positions }) {
  if (!positions.length) {
    return (
      <Card title="Positions">
        <div style={{ color: C.textDim, fontSize: 13, textAlign: "center", padding: 20 }}>No open positions</div>
      </Card>
    );
  }
  return (
    <Card title="Positions">
      <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13 }}>
        <thead>
          <tr style={{ borderBottom: `1px solid ${C.border}` }}>
            {["Symbol", "Side", "Size", "Entry", "Mark", "PnL", "Leverage"].map((h) => (
              <th key={h} style={{ textAlign: "left", padding: "6px 8px", color: C.textDim, fontWeight: 500, fontSize: 11, textTransform: "uppercase" }}>{h}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {positions.map((p, i) => (
            <tr key={i} style={{ borderBottom: `1px solid ${C.border}15` }}>
              <td style={{ padding: "8px" }}><span style={{ fontWeight: 600, color: C.accent }}>{p.symbol}</span></td>
              <td><Badge color={p.quantity > 0 ? C.green : C.red}>{p.quantity > 0 ? "LONG" : "SHORT"}</Badge></td>
              <td style={{ fontFamily: "monospace" }}>{fmt(Math.abs(p.quantity), 4)}</td>
              <td style={{ fontFamily: "monospace" }}>{fmt(p.entry_price)}</td>
              <td style={{ fontFamily: "monospace" }}>{fmt(p.mark_price)}</td>
              <td style={{ fontFamily: "monospace", color: p.unrealized_pnl >= 0 ? C.green : C.red, fontWeight: 600 }}>
                {fmtUsd(p.unrealized_pnl)}
              </td>
              <td><Badge color={C.purple}>{p.leverage}x</Badge></td>
            </tr>
          ))}
        </tbody>
      </table>
    </Card>
  );
}

// ─── Strategy Panel ───
function StrategyPanel({ strategies, onRefresh }) {
  const [showCreate, setShowCreate] = useState(false);
  const [types, setTypes] = useState([]);
  const [form, setForm] = useState({ type: "twap", name: "", symbol: "BTCUSDT", params: "{}" });

  const [twap, setTwap] = useState({
    total_quantity: "0.01",
    num_slices: "5",
    duration_minutes: "10",
    side: "BUY",
    order_type: "MARKET",
  });

  const [iceberg, setIceberg] = useState({
    side: "BUY",
    total_quantity: "0.01",
    min_qty: "0.001",
    max_qty: "0.002",
    min_interval: "8",
    max_interval: "25",
    price_offset_ticks: "0",
    max_offset_ticks: "2",
    duration_minutes: "30",
    pause_on_spread_bps: "30",
    max_deviation_bps: "80",
    buy_ceiling_price: "",
    sell_floor_price: "",
    leverage: "3",
    margin_type: "ISOLATED",
    use_post_only: true,
    use_binance_anchor: false,
    binance_symbol: "UAIUSDT",
    binance_offset_pct: "-0.3",
  });

  useEffect(() => {
    api("/strategies/types").then((d) => setTypes(d.types || [])).catch(() => {});
  }, []);

  const twapPreview = (() => {
    const tq = parseFloat(twap.total_quantity || "0") || 0;
    const ns = Math.max(1, parseInt(twap.num_slices || "1", 10));
    const dm = parseFloat(twap.duration_minutes || "0") || 0;
    const per = ns > 0 ? tq / ns : 0;
    const every = ns > 0 ? (dm / ns) : 0;
    return "将" + twap.side + " " + tq + "（" + form.symbol + "），共 " + ns + " 笔，每笔约 " + per.toFixed(6) + "，约每 " + every.toFixed(2) + " 分钟一笔";
  })();

  const icebergPreview = (() => {
    const tq = parseFloat(iceberg.total_quantity || "0") || 0;
    const q1 = parseFloat(iceberg.min_qty || "0") || 0;
    const q2 = parseFloat(iceberg.max_qty || "0") || 0;
    const i1 = parseFloat(iceberg.min_interval || "0") || 0;
    const i2 = parseFloat(iceberg.max_interval || "0") || 0;
    const band = iceberg.side === "BUY" ? (iceberg.buy_ceiling_price || "未设") : (iceberg.sell_floor_price || "未设");
    return "将" + iceberg.side + " " + tq + "（" + form.symbol + "），每次随机挂 " + q1 + "~" + q2 + "，间隔 " + i1 + "~" + i2 + " 秒，杠杆 " + iceberg.leverage + "x，价格边界=" + band;
  })();

  const buildParams = () => {
    if (form.type === "twap") {
      return {
        total_quantity: parseFloat(twap.total_quantity || "0"),
        num_slices: parseInt(twap.num_slices || "1", 10),
        duration_minutes: parseFloat(twap.duration_minutes || "0"),
        side: twap.side,
        order_type: twap.order_type,
      };
    }

    if (form.type === "iceberg") {
      return {
        side: iceberg.side,
        total_quantity: parseFloat(iceberg.total_quantity || "0"),
        min_qty: parseFloat(iceberg.min_qty || "0"),
        max_qty: parseFloat(iceberg.max_qty || "0"),
        min_interval: parseFloat(iceberg.min_interval || "0"),
        max_interval: parseFloat(iceberg.max_interval || "0"),
        price_offset_ticks: parseInt(iceberg.price_offset_ticks || "0", 10),
        max_offset_ticks: parseInt(iceberg.max_offset_ticks || "0", 10),
        duration_minutes: parseFloat(iceberg.duration_minutes || "0"),
        pause_on_spread_bps: parseFloat(iceberg.pause_on_spread_bps || "30"),
        max_deviation_bps: parseFloat(iceberg.max_deviation_bps || "80"),
        buy_ceiling_price: iceberg.buy_ceiling_price ? parseFloat(iceberg.buy_ceiling_price) : 0,
        sell_floor_price: iceberg.sell_floor_price ? parseFloat(iceberg.sell_floor_price) : 0,
        leverage: parseInt(iceberg.leverage || "3", 10),
        margin_type: iceberg.margin_type,
        use_post_only: !!iceberg.use_post_only,
        use_binance_anchor: !!iceberg.use_binance_anchor,
        binance_symbol: iceberg.binance_symbol || form.symbol,
        binance_offset_pct: parseFloat(iceberg.binance_offset_pct || "0"),
      };
    }

    let params = {};
    try { params = JSON.parse(form.params || "{}"); } catch {}
    return params;
  };

  const createStrategy = async () => {
    try {
      const params = buildParams();
      await api("/strategies", {
        method: "POST",
        body: JSON.stringify({ strategy_type: form.type, name: form.name, symbol: form.symbol, params }),
      });
      setShowCreate(false);
      setForm({ type: "twap", name: "", symbol: "BTCUSDT", params: "{}" });
      onRefresh();
    } catch (e) {
      alert(e.message);
    }
  };

  const applyTwapPreset = (preset) => {
    if (preset === "safe") setTwap({ total_quantity: "0.005", num_slices: "10", duration_minutes: "30", side: "BUY", order_type: "MARKET" });
    else if (preset === "normal") setTwap({ total_quantity: "0.01", num_slices: "5", duration_minutes: "10", side: "BUY", order_type: "MARKET" });
    else if (preset === "fast") setTwap({ total_quantity: "0.01", num_slices: "3", duration_minutes: "3", side: "BUY", order_type: "MARKET" });
  };

  const applyIcebergPreset = (preset) => {
    if (preset === "safe") setIceberg({ side: "BUY", total_quantity: "0.005", min_qty: "0.0005", max_qty: "0.001", min_interval: "12", max_interval: "30", price_offset_ticks: "0", max_offset_ticks: "2", duration_minutes: "45", pause_on_spread_bps: "25", max_deviation_bps: "60", buy_ceiling_price: "", sell_floor_price: "", leverage: "2", margin_type: "ISOLATED", use_post_only: true });
    else if (preset === "normal") setIceberg({ side: "BUY", total_quantity: "0.01", min_qty: "0.001", max_qty: "0.002", min_interval: "8", max_interval: "25", price_offset_ticks: "0", max_offset_ticks: "2", duration_minutes: "30", pause_on_spread_bps: "30", max_deviation_bps: "80", buy_ceiling_price: "", sell_floor_price: "", leverage: "3", margin_type: "ISOLATED", use_post_only: true });
    else if (preset === "fast") setIceberg({ side: "BUY", total_quantity: "0.01", min_qty: "0.0015", max_qty: "0.003", min_interval: "3", max_interval: "10", price_offset_ticks: "0", max_offset_ticks: "1", duration_minutes: "10", pause_on_spread_bps: "40", max_deviation_bps: "120", buy_ceiling_price: "", sell_floor_price: "", leverage: "5", margin_type: "ISOLATED", use_post_only: true });
    else if (preset === "uai_short") setIceberg({ side: "SELL", total_quantity: "8000", min_qty: "120", max_qty: "360", min_interval: "6", max_interval: "18", price_offset_ticks: "0", max_offset_ticks: "2", duration_minutes: "90", pause_on_spread_bps: "12", max_deviation_bps: "35", buy_ceiling_price: "", sell_floor_price: "0.1976", leverage: "3", margin_type: "ISOLATED", use_post_only: true, use_binance_anchor: false, binance_symbol: "UAIUSDT", binance_offset_pct: "-0.3" });
    else if (preset === "uai_bn_short") setIceberg({ side: "SELL", total_quantity: "8000", min_qty: "120", max_qty: "360", min_interval: "6", max_interval: "18", price_offset_ticks: "0", max_offset_ticks: "2", duration_minutes: "90", pause_on_spread_bps: "12", max_deviation_bps: "35", buy_ceiling_price: "", sell_floor_price: "0.1970", leverage: "3", margin_type: "ISOLATED", use_post_only: true, use_binance_anchor: true, binance_symbol: "UAIUSDT", binance_offset_pct: "-0.3" });
  };

  const toggleStrategy = async (sid, state) => {
    try {
      if (state === "running") await api("/strategies/" + sid + "/stop", { method: "POST" });
      else await api("/strategies/" + sid + "/start", { method: "POST" });
      onRefresh();
    } catch (e) { alert(e.message); }
  };

  const deleteStrategy = async (sid) => {
    try { await api("/strategies/" + sid, { method: "DELETE" }); onRefresh(); }
    catch (e) { alert(e.message); }
  };

  return (
    <Card title="Strategies" action={<Btn small onClick={() => setShowCreate(!showCreate)}>{showCreate ? "Cancel" : "+ New"}</Btn>}>
      {showCreate && (
        <div style={{ background: C.bg, borderRadius: 8, padding: 14, marginBottom: 14, border: "1px solid " + C.border }}>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
            <Select label="Type" value={form.type} onChange={(v) => setForm({ ...form, type: v })} options={types.length ? types : ["twap", "iceberg", "grid", "momentum"]} />
            <Input label="Name" value={form.name} onChange={(v) => setForm({ ...form, name: v })} placeholder="strategy-01" />
            <Input label="Symbol" value={form.symbol} onChange={(v) => setForm({ ...form, symbol: v })} placeholder="BTCUSDT" />
          </div>

          {form.type === "twap" ? (
            <div style={{ marginTop: 10, border: "1px solid " + C.border, borderRadius: 8, padding: 10 }}>
              <div style={{ fontSize: 12, color: C.textDim, marginBottom: 8 }}>TWAP 简单模式</div>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8 }}>
                <Input label="总数量" value={twap.total_quantity} onChange={(v) => setTwap({ ...twap, total_quantity: v })} type="number" />
                <Input label="切片数" value={twap.num_slices} onChange={(v) => setTwap({ ...twap, num_slices: v })} type="number" />
                <Input label="总时长(分钟)" value={twap.duration_minutes} onChange={(v) => setTwap({ ...twap, duration_minutes: v })} type="number" />
                <Select label="方向" value={twap.side} onChange={(v) => setTwap({ ...twap, side: v })} options={["BUY", "SELL"]} />
                <Select label="订单类型" value={twap.order_type} onChange={(v) => setTwap({ ...twap, order_type: v })} options={["MARKET", "LIMIT"]} />
              </div>
              <div style={{ display: "flex", gap: 6, marginTop: 8 }}>
                <Btn small onClick={() => applyTwapPreset("safe")}>保守模板</Btn>
                <Btn small onClick={() => applyTwapPreset("normal")}>标准模板</Btn>
                <Btn small onClick={() => applyTwapPreset("fast")}>快速模板</Btn>
              </div>
              <div style={{ marginTop: 8, fontSize: 12, color: C.accent }}>{twapPreview}</div>
            </div>
          ) : form.type === "iceberg" ? (
            <div style={{ marginTop: 10, border: "1px solid " + C.border, borderRadius: 8, padding: 10 }}>
              <div style={{ fontSize: 12, color: C.textDim, marginBottom: 8 }}>Iceberg 简单模式（隐藏式 maker 执行）</div>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8 }}>
                <Select label="方向" value={iceberg.side} onChange={(v) => setIceberg({ ...iceberg, side: v })} options={["BUY", "SELL"]} />
                <Input label="总数量" value={iceberg.total_quantity} onChange={(v) => setIceberg({ ...iceberg, total_quantity: v })} type="number" />
                <Input label="总时长(分钟)" value={iceberg.duration_minutes} onChange={(v) => setIceberg({ ...iceberg, duration_minutes: v })} type="number" />
                <Input label="单笔最小量" value={iceberg.min_qty} onChange={(v) => setIceberg({ ...iceberg, min_qty: v })} type="number" />
                <Input label="单笔最大量" value={iceberg.max_qty} onChange={(v) => setIceberg({ ...iceberg, max_qty: v })} type="number" />
                <Input label="最小间隔(秒)" value={iceberg.min_interval} onChange={(v) => setIceberg({ ...iceberg, min_interval: v })} type="number" />
                <Input label="最大间隔(秒)" value={iceberg.max_interval} onChange={(v) => setIceberg({ ...iceberg, max_interval: v })} type="number" />
                <Input label="盘口偏移tick(最小)" value={iceberg.price_offset_ticks} onChange={(v) => setIceberg({ ...iceberg, price_offset_ticks: v })} type="number" />
                <Input label="盘口偏移tick(最大)" value={iceberg.max_offset_ticks} onChange={(v) => setIceberg({ ...iceberg, max_offset_ticks: v })} type="number" />
                <Input label="最大价差(bps)" value={iceberg.pause_on_spread_bps} onChange={(v) => setIceberg({ ...iceberg, pause_on_spread_bps: v })} type="number" />
                <Input label="最大偏离(bps)" value={iceberg.max_deviation_bps} onChange={(v) => setIceberg({ ...iceberg, max_deviation_bps: v })} type="number" />
                <Input label="买入上限价(可选)" value={iceberg.buy_ceiling_price} onChange={(v) => setIceberg({ ...iceberg, buy_ceiling_price: v })} type="number" />
                <Input label="卖出下限价(可选)" value={iceberg.sell_floor_price} onChange={(v) => setIceberg({ ...iceberg, sell_floor_price: v })} type="number" />
                <Input label="杠杆倍数" value={iceberg.leverage} onChange={(v) => setIceberg({ ...iceberg, leverage: v })} type="number" />
                <Select label="保证金模式" value={iceberg.margin_type} onChange={(v) => setIceberg({ ...iceberg, margin_type: v })} options={["ISOLATED", "CROSSED"]} />
                <Select label="跟随BN价格" value={iceberg.use_binance_anchor ? "yes" : "no"} onChange={(v) => setIceberg({ ...iceberg, use_binance_anchor: v === "yes" })} options={[{label:"否", value:"no"}, {label:"是", value:"yes"}]} />
                <Input label="BN合约符号" value={iceberg.binance_symbol} onChange={(v) => setIceberg({ ...iceberg, binance_symbol: v })} />
                <Input label="相对BN偏移(%)" value={iceberg.binance_offset_pct} onChange={(v) => setIceberg({ ...iceberg, binance_offset_pct: v })} type="number" />
              </div>
              <div style={{ display: "flex", gap: 6, marginTop: 8 }}>
                <Btn small onClick={() => applyIcebergPreset("safe")}>保守模板</Btn>
                <Btn small onClick={() => applyIcebergPreset("normal")}>标准模板</Btn>
                <Btn small onClick={() => applyIcebergPreset("fast")}>快速模板</Btn>
                <Btn small onClick={() => applyIcebergPreset("uai_short")}>UAI做空3x</Btn>
                <Btn small onClick={() => applyIcebergPreset("uai_bn_short")}>UAI-BN(-0.3%)空3x</Btn>
              </div>
              <div style={{ marginTop: 8, fontSize: 12, color: C.accent }}>{icebergPreview}</div>
            </div>
          ) : (
            <Input label="Params (JSON)" value={form.params} onChange={(v) => setForm({ ...form, params: v })} placeholder='{"quantity": 0.001}' style={{ marginTop: 10 }} />
          )}

          <Btn onClick={createStrategy} disabled={!form.name} style={{ marginTop: 10 }}>Create Strategy</Btn>
        </div>
      )}

      {strategies.length === 0 ? (
        <div style={{ color: C.textDim, fontSize: 13, textAlign: "center", padding: 20 }}>No strategies created yet. Click "+ New" to create one.</div>
      ) : (
        strategies.map((s) => (
          <div key={s.strategy_id} style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "10px 12px", marginBottom: 8, background: C.bg, borderRadius: 8, border: "1px solid " + (s.state === "running" ? (C.green + "44") : C.border) }}>
            <div style={{ flex: 1 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <StatusDot active={s.state === "running"} />
                <span style={{ fontWeight: 600, fontSize: 14 }}>{s.name}</span>
                <Badge>{s.symbol}</Badge>
                <Badge color={C.purple}>{s.strategy_id}</Badge>
              </div>
              <div style={{ fontSize: 11, color: C.textDim, marginTop: 4, fontFamily: "monospace" }}>{Object.entries(s.params || {}).slice(0, 4).map(([k, v]) => k + "=" + v).join(" · ")}</div>
            </div>
            <div style={{ display: "flex", gap: 6 }}>
              <Btn small onClick={() => toggleStrategy(s.strategy_id, s.state)} color={s.state === "running" ? C.red : C.green}>{s.state === "running" ? "Stop" : "Start"}</Btn>
              <Btn small onClick={() => deleteStrategy(s.strategy_id)} color={C.textDim}>✕</Btn>
            </div>
          </div>
        ))
      )}
    </Card>
  );
}


// ─── Orders Table ───
function OrdersTable({ orders }) {
  return (
    <Card title="Recent Orders">
      {orders.length === 0 ? (
        <div style={{ color: C.textDim, fontSize: 13, textAlign: "center", padding: 20 }}>No orders yet</div>
      ) : (
        <div style={{ maxHeight: 300, overflowY: "auto" }}>
          <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 12 }}>
            <thead>
              <tr style={{ borderBottom: `1px solid ${C.border}` }}>
                {["Time", "Strategy", "Symbol", "Side", "Type", "Qty", "Price", "Status"].map((h) => (
                  <th key={h} style={{ textAlign: "left", padding: "6px 6px", color: C.textDim, fontWeight: 500, fontSize: 10, textTransform: "uppercase" }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {orders.slice(0, 50).map((o, i) => (
                <tr key={i} style={{ borderBottom: `1px solid ${C.border}10` }}>
                  <td style={{ padding: "6px", fontFamily: "monospace", fontSize: 11, color: C.textDim }}>{o.created_at?.slice(5, 19)}</td>
                  <td><Badge color={C.purple}>{o.strategy_id?.slice(0, 6) || "manual"}</Badge></td>
                  <td style={{ fontWeight: 500 }}>{o.symbol}</td>
                  <td><Badge color={o.side === "BUY" ? C.green : C.red}>{o.side}</Badge></td>
                  <td style={{ color: C.textDim }}>{o.order_type}</td>
                  <td style={{ fontFamily: "monospace" }}>{fmt(o.quantity, 4)}</td>
                  <td style={{ fontFamily: "monospace" }}>{fmt(o.price)}</td>
                  <td><Badge color={o.status === "FILLED" ? C.green : o.status === "CANCELED" ? C.textMuted : C.yellow}>{o.status}</Badge></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </Card>
  );
}

// ─── Alerts Panel ───
function AlertsPanel({ alerts }) {
  const levelColor = { CRITICAL: C.red, WARNING: C.yellow, INFO: C.accent };
  return (
    <Card title="Risk Alerts">
      {alerts.length === 0 ? (
        <div style={{ color: C.textDim, fontSize: 13, textAlign: "center", padding: 20 }}>No alerts — system healthy</div>
      ) : (
        <div style={{ maxHeight: 250, overflowY: "auto" }}>
          {alerts.map((a, i) => (
            <div
              key={i}
              style={{
                display: "flex",
                alignItems: "flex-start",
                gap: 8,
                padding: "8px 10px",
                marginBottom: 6,
                background: `${levelColor[a.level] || C.textDim}11`,
                borderRadius: 6,
                border: `1px solid ${levelColor[a.level] || C.textDim}33`,
              }}
            >
              <Badge color={levelColor[a.level]}>{a.level}</Badge>
              <div style={{ flex: 1, fontSize: 12 }}>
                <div style={{ color: C.text }}>{a.message}</div>
                <div style={{ color: C.textDim, fontSize: 10, marginTop: 2 }}>{a.category} · {a.timestamp?.slice(0, 19)}</div>
              </div>
            </div>
          ))}
        </div>
      )}
    </Card>
  );
}

// ─── Risk Config Panel ───
function RiskPanel({ riskStatus }) {
  if (!riskStatus) return null;
  const config = riskStatus.config || {};
  const items = [
    { label: "Max Order Value", value: fmtUsd(config.max_order_value_usd) },
    { label: "Max Daily Loss", value: fmtUsd(config.max_daily_loss_usd) },
    { label: "Max Drawdown", value: `${config.max_drawdown_pct}%` },
    { label: "Max Orders/min", value: config.max_orders_per_minute },
    { label: "Daily PnL", value: fmtUsd(riskStatus.daily_pnl), color: (riskStatus.daily_pnl || 0) >= 0 ? C.green : C.red },
    { label: "Enabled", value: config.enabled ? "YES" : "NO", color: config.enabled ? C.green : C.red },
  ];

  return (
    <Card title="Risk Control">
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
        {items.map((item) => (
          <div key={item.label} style={{ padding: "6px 10px", background: C.bg, borderRadius: 6, border: `1px solid ${C.border}` }}>
            <div style={{ fontSize: 10, color: C.textDim, textTransform: "uppercase" }}>{item.label}</div>
            <div style={{ fontSize: 14, fontWeight: 600, color: item.color || C.text, fontFamily: "monospace" }}>{item.value}</div>
          </div>
        ))}
      </div>
    </Card>
  );
}

// ─── Manual Trade Panel ───
function ManualTradePanel() {
  const [symbol, setSymbol] = useState("BTCUSDT");
  const [side, setSide] = useState("BUY");
  const [qty, setQty] = useState("");
  const [price, setPrice] = useState("");
  const [orderType, setOrderType] = useState("MARKET");
  const [result, setResult] = useState(null);

  const placeTrade = async () => {
    try {
      const body = { symbol, side, order_type: orderType, quantity: parseFloat(qty) };
      if (orderType === "LIMIT" && price) body.price = parseFloat(price);
      if (orderType === "LIMIT") body.time_in_force = "GTC";
      const res = await api("/trading/order", { method: "POST", body: JSON.stringify(body) });
      setResult({ ok: true, msg: `Order placed: ${res.order_id} ${res.status}` });
    } catch (e) {
      setResult({ ok: false, msg: e.message });
    }
  };

  return (
    <Card title="Manual Trade">
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
        <Input label="Symbol" value={symbol} onChange={setSymbol} />
        <Select label="Type" value={orderType} onChange={setOrderType} options={["MARKET", "LIMIT"]} />
        <div>
          <label style={{ display: "block", fontSize: 11, color: C.textDim, marginBottom: 4, fontWeight: 500 }}>Side</label>
          <div style={{ display: "flex", gap: 4 }}>
            <Btn small onClick={() => setSide("BUY")} color={side === "BUY" ? C.green : C.textMuted} style={{ flex: 1 }}>BUY</Btn>
            <Btn small onClick={() => setSide("SELL")} color={side === "SELL" ? C.red : C.textMuted} style={{ flex: 1 }}>SELL</Btn>
          </div>
        </div>
        <Input label="Quantity" value={qty} onChange={setQty} type="number" />
        {orderType === "LIMIT" && <Input label="Price" value={price} onChange={setPrice} type="number" />}
      </div>
      <Btn onClick={placeTrade} disabled={!qty} color={side === "BUY" ? C.green : C.red} style={{ width: "100%", marginTop: 10 }}>
        {side} {symbol}
      </Btn>
      {result && (
        <div style={{ marginTop: 8, fontSize: 12, color: result.ok ? C.green : C.red }}>{result.msg}</div>
      )}
    </Card>
  );
}

// ─── Main Dashboard ───
function Dashboard() {
  const [connected, setConnected] = useState(null); // null = checking, true, false
  const [strategies, setStrategies] = useState([]);
  const [positions, setPositions] = useState([]);
  const [orders, setOrders] = useState([]);
  const [alerts, setAlerts] = useState([]);
  const [stats, setStats] = useState({});
  const [riskStatus, setRiskStatus] = useState(null);
  const [tab, setTab] = useState("overview");
  const [error, setError] = useState(null);

  const checkHealth = useCallback(async () => {
    try {
      const h = await api("/health");
      setConnected(h.connected);
      setError(null);
    } catch {
      setError("Cannot reach trading server. Make sure it's running on port 8888.");
      setConnected(false);
    }
  }, []);

  const fetchAll = useCallback(async () => {
    try {
      const [strats, pos, ords, alrts, sts, risk] = await Promise.allSettled([
        api("/strategies"),
        api("/account/positions"),
        api("/data/orders?limit=50"),
        api("/risk/alerts?limit=20"),
        api("/data/stats"),
        api("/risk/status"),
      ]);
      if (strats.status === "fulfilled") setStrategies(strats.value || []);
      if (pos.status === "fulfilled") setPositions(pos.value || []);
      if (ords.status === "fulfilled") setOrders(ords.value || []);
      if (alrts.status === "fulfilled") setAlerts(alrts.value || []);
      if (sts.status === "fulfilled") setStats(sts.value || {});
      if (risk.status === "fulfilled") setRiskStatus(risk.value);
    } catch {}
  }, []);

  useEffect(() => {
    checkHealth();
    const interval = setInterval(checkHealth, 10000);
    return () => clearInterval(interval);
  }, [checkHealth]);

  useEffect(() => {
    if (connected) {
      fetchAll();
      const interval = setInterval(fetchAll, 5000);
      return () => clearInterval(interval);
    }
  }, [connected, fetchAll]);

  // Server unreachable
  if (error) {
    return (
      <div style={{ background: C.bg, minHeight: "100vh", color: C.text, fontFamily: "'Inter', 'Segoe UI', sans-serif", display: "flex", alignItems: "center", justifyContent: "center" }}>
        <Card style={{ maxWidth: 460, textAlign: "center" }}>
          <div style={{ fontSize: 40, marginBottom: 16 }}>⚠</div>
          <div style={{ fontSize: 16, fontWeight: 600, marginBottom: 8 }}>Server Unreachable</div>
          <div style={{ fontSize: 13, color: C.textDim, lineHeight: 1.6 }}>{error}</div>
          <div style={{ marginTop: 16, padding: 12, background: C.bg, borderRadius: 6, fontFamily: "monospace", fontSize: 12, color: C.accent }}>
            cd aster-trading && python main.py
          </div>
        </Card>
      </div>
    );
  }

  // Not connected to Aster
  if (connected === false) {
    return (
      <div style={{ background: C.bg, minHeight: "100vh", color: C.text, fontFamily: "'Inter', 'Segoe UI', sans-serif" }}>
        <SetupPanel onConnected={() => { setConnected(true); fetchAll(); }} />
      </div>
    );
  }

  // Loading
  if (connected === null) {
    return (
      <div style={{ background: C.bg, minHeight: "100vh", color: C.text, display: "flex", alignItems: "center", justifyContent: "center", fontFamily: "'Inter', sans-serif" }}>
        <div style={{ textAlign: "center" }}>
          <div style={{ fontSize: 28, color: C.accent, marginBottom: 8 }}>⬡</div>
          <div style={{ color: C.textDim }}>Connecting...</div>
        </div>
      </div>
    );
  }

  const tabs = [
    { id: "overview", label: "Overview" },
    { id: "strategies", label: "Strategies" },
    { id: "trade", label: "Manual Trade" },
    { id: "risk", label: "Risk" },
  ];

  return (
    <div style={{ background: C.bg, minHeight: "100vh", color: C.text, fontFamily: "'Inter', 'Segoe UI', sans-serif" }}>
      {/* Header */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          padding: "12px 24px",
          borderBottom: `1px solid ${C.border}`,
          background: C.card,
        }}
      >
        <div style={{ display: "flex", alignItems: "center", gap: 16 }}>
          <span style={{ fontSize: 20, fontWeight: 700, color: C.accent, letterSpacing: "-0.02em" }}>⬡ ASTER</span>
          <span style={{ fontSize: 12, color: C.textDim, borderLeft: `1px solid ${C.border}`, paddingLeft: 12 }}>Trading System</span>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 16 }}>
          {tabs.map((t) => (
            <button
              key={t.id}
              onClick={() => setTab(t.id)}
              style={{
                background: "none",
                border: "none",
                color: tab === t.id ? C.accent : C.textDim,
                fontSize: 13,
                fontWeight: tab === t.id ? 600 : 400,
                cursor: "pointer",
                padding: "6px 12px",
                borderBottom: tab === t.id ? `2px solid ${C.accent}` : "2px solid transparent",
                transition: "all 0.15s",
              }}
            >
              {t.label}
            </button>
          ))}
          <StatusDot active={true} color={C.green} />
          <span style={{ fontSize: 11, color: C.green }}>Connected</span>
        </div>
      </div>

      {/* Content */}
      <div style={{ padding: "20px 24px", maxWidth: 1400, margin: "0 auto" }}>
        <StatsRow stats={stats} positions={positions} />

        {tab === "overview" && (
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
            <PositionsTable positions={positions} />
            <AlertsPanel alerts={alerts} />
            <div style={{ gridColumn: "1 / -1" }}>
              <OrdersTable orders={orders} />
            </div>
          </div>
        )}

        {tab === "strategies" && (
          <div style={{ display: "grid", gridTemplateColumns: "1fr", gap: 16 }}>
            <StrategyPanel strategies={strategies} onRefresh={fetchAll} />
            <OrdersTable orders={orders} />
          </div>
        )}

        {tab === "trade" && (
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
            <ManualTradePanel />
            <PositionsTable positions={positions} />
            <div style={{ gridColumn: "1 / -1" }}>
              <OrdersTable orders={orders} />
            </div>
          </div>
        )}

        {tab === "risk" && (
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
            <RiskPanel riskStatus={riskStatus} />
            <AlertsPanel alerts={alerts} />
          </div>
        )}
      </div>
    </div>
  );
}


window.Dashboard = Dashboard;
