/* ═══════════════════════════════════════════════════════════════
   FOXBOT PRO — MOBILE SCREENS (Trading, Signaux, Charts, More)
   Phase 2 — implémentés côté coding (cohérent avec mobile-shell/dashboard)
   ═══════════════════════════════════════════════════════════════ */

const { useState: useStateS, useEffect: useEffectS, useRef: useRefS, useMemo: useMemoS } = React;

/* ─────────────────────────────────────────────────────────────────
   MobileSignaux — liste compacte de signaux
   ───────────────────────────────────────────────────────────────── */
function MobileSignaux({ onAction }) {
  const store    = window.useStore ? window.useStore() : (window.MOCK || {});
  const SIGNALS  = Array.isArray(store.SIGNALS) ? store.SIGNALS : [];
  const [filter, setFilter] = useStateS("all");
  const [scanning, setScanning] = useStateS(false);
  const [expanded, setExpanded] = useStateS(null);

  const filtered = SIGNALS.filter(s => {
    if (filter === "all")     return true;
    if (filter === "long")    return s.direction === "LONG";
    if (filter === "short")   return s.direction === "SHORT";
    if (filter === "premium") return s.score >= 8;
    return true;
  });

  async function doScan() {
    setScanning(true);
    window.HAPTIC && window.HAPTIC.toggle();
    try { await window.fbScan(); } catch {}
    window.HAPTIC && window.HAPTIC.success();
    setScanning(false);
    emitToast({ type: "success", msg: "Scan terminé" });
  }

  return (
    <div className="m-page">
      <button className="m-scan-btn" onClick={doScan} disabled={scanning}>
        {scanning ? <span className="spinner"></span> : <Icon.Zap size={18}/>}
        <span>{scanning ? "SCANNING..." : "Scanner BTC · ETH · SOL · XAU"}</span>
      </button>

      <div className="chips" style={{ paddingBottom: 4 }}>
        {[
          { id:"all",     l:"Tous",     n: SIGNALS.length },
          { id:"long",    l:"LONG",     n: SIGNALS.filter(s=>s.direction==="LONG").length },
          { id:"short",   l:"SHORT",    n: SIGNALS.filter(s=>s.direction==="SHORT").length },
          { id:"premium", l:"≥ 8/10",   n: SIGNALS.filter(s=>s.score>=8).length },
        ].map(c => (
          <div key={c.id} className={`chip ${filter===c.id?"active":""}`} onClick={()=>{ window.HAPTIC&&window.HAPTIC.tap(); setFilter(c.id); }}>
            {c.l} <span className="count">{c.n}</span>
          </div>
        ))}
      </div>

      {filtered.length === 0 ? (
        <MEmpty icon={Icon.Search} title="Aucun signal" desc="Le scanner n'a rien détecté qui passe les filtres FoxBot Pro. Patiente ou ajuste tes critères."/>
      ) : (
        <div className="m-sig-stack">
          {filtered.map(s => (
            <MSignalExpandable
              key={s.id} signal={s}
              expanded={expanded === s.id}
              onToggle={()=>{ window.HAPTIC&&window.HAPTIC.tap(); setExpanded(expanded === s.id ? null : s.id); }}
              onAction={onAction}
            />
          ))}
        </div>
      )}
    </div>
  );
}

function MSignalExpandable({ signal, expanded, onToggle, onAction }) {
  const up = signal.direction === "LONG";
  return (
    <div className={`m-sig-card ${expanded ? "expanded" : ""}`}>
      <div className="m-sig-card-head" onClick={onToggle}>
        <PairLogo pair={signal.pair} size={32}/>
        <div className="sym-name">
          <b>{signal.pair}/USDT</b>
          <div style={{ display:"flex", alignItems:"center", gap:6, marginTop:2 }}>
            <DirBadge dir={signal.direction}/>
            <span style={{ fontSize:11, color: signal.chg24h>=0?"var(--bull)":"var(--bear)", fontFamily:"var(--font-mono)" }}>{fmtPct(signal.chg24h)}</span>
          </div>
        </div>
        <div className="sig-side">
          <ScoreBadge score={signal.score}/>
          <Icon.ChevronDown size={14} className="muted" style={{ transition:"transform 200ms", transform: expanded ? "rotate(180deg)" : "none" }}/>
        </div>
      </div>

      {expanded && (
        <div className="m-sig-card-body">
          {/* Plan de trade compact */}
          <div className="m-sig-plan">
            <div className="row"><span>Entrée</span><span className="mono accent">{fmtNum(signal.entry)}</span></div>
            <div className="row"><span>SL</span><span className="mono bear">{fmtNum(signal.sl)}</span></div>
            <div className="row"><span>TP1</span><span className="mono bull">{fmtNum(signal.tp1)}</span></div>
            <div className="row"><span>TP2</span><span className="mono bull">{fmtNum(signal.tp2)}</span></div>
            <div className="row"><span>R/R net</span><span className="mono accent">{signal.rr}</span></div>
          </div>

          {/* Pills risque/gain */}
          <div className="m-sig-pills">
            <div className="pill bear"><span className="caption">Perte max</span><b>−€{(signal.riskEur||0).toFixed(2)}</b></div>
            <div className="pill bull"><span className="caption">Gain TP1</span><b>+€{(signal.gainEur||0).toFixed(2)}</b></div>
            <div className="pill bull"><span className="caption">Gain TP2</span><b>+€{(signal.gainTp2Eur||0).toFixed(2)}</b></div>
          </div>

          {/* Tech (compact) + Risque */}
          <div className="m-sig-tech">
            <span>RSI <b>{(signal.rsi||0).toFixed(1)}</b></span>
            <span>VOL <b>{Math.round(signal.volume||0)}%</b></span>
            <span>ATR <b>{(signal.atr||0).toFixed(2)}%</b></span>
            <span>MACD <b className={signal.macd?.dir==="up"?"bull":"bear"}>{signal.macd?.dir==="up"?"▲":"▼"}</b></span>
          </div>
          <div style={{ display:"flex", justifyContent:"center", marginTop:-4 }}>
            <RiskBadge signal={signal}/>
          </div>

          {/* Actions 2x2 */}
          <div className="m-sig-actions">
            <button className="act paper-long" onClick={()=>{ window.HAPTIC&&window.HAPTIC.press(); onAction&&onAction("paper-long", signal); }}>
              <Icon.Edit size={12}/> PAPER ▲
            </button>
            <button className="act paper-short" onClick={()=>{ window.HAPTIC&&window.HAPTIC.press(); onAction&&onAction("paper-short", signal); }}>
              <Icon.Edit size={12}/> PAPER ▼
            </button>
            <button className="act real-long" onClick={()=>{ if(confirm("Ouvrir RÉEL LONG ?")) { window.HAPTIC&&window.HAPTIC.success(); onAction&&onAction("real-long", signal); } }}>
              <Icon.Flash size={12}/> RÉEL ▲
            </button>
            <button className="act real-short" onClick={()=>{ if(confirm("Ouvrir RÉEL SHORT ?")) { window.HAPTIC&&window.HAPTIC.success(); onAction&&onAction("real-short", signal); } }}>
              <Icon.Flash size={12}/> RÉEL ▼
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────
   MobileTrading — cockpit positions
   ───────────────────────────────────────────────────────────────── */
function MobileTrading({ onAction }) {
  const store     = window.useStore ? window.useStore() : (window.MOCK || {});
  const positions = Array.isArray(store.POSITIONS) ? store.POSITIONS : [];
  const [filter, setFilter] = useStateS("all");

  const filtered = positions.filter(p => {
    if (filter === "all")    return true;
    if (filter === "paper")  return !p.isReal;
    if (filter === "real")   return p.isReal;
    return true;
  });
  const totalPnl = positions.reduce((s, p) => s + (p.pnlEur || 0), 0);

  return (
    <div className="m-page">
      <div className="m-trading-hero">
        <div>
          <div className="caption">P&L OUVERT</div>
          <div className={`mono hero-num ${totalPnl>=0?"bull":"bear"}`}>{totalPnl>=0?"+":""}{totalPnl.toFixed(2)}€</div>
        </div>
        <div style={{ textAlign:"right" }}>
          <div className="caption">POSITIONS</div>
          <div className="mono primary" style={{ fontSize:22, fontWeight:600 }}>{positions.length}</div>
        </div>
      </div>

      <div className="chips">
        {[
          { id:"all",   l:"Toutes", n: positions.length },
          { id:"paper", l:"PAPER",  n: positions.filter(p=>!p.isReal).length },
          { id:"real",  l:"RÉEL",   n: positions.filter(p=> p.isReal).length },
        ].map(c => (
          <div key={c.id} className={`chip ${filter===c.id?"active":""}`} onClick={()=>{ window.HAPTIC&&window.HAPTIC.tap(); setFilter(c.id); }}>
            {c.l} <span className="count">{c.n}</span>
          </div>
        ))}
      </div>

      {filtered.length === 0 ? (
        <MEmpty icon={Icon.Activity} title="Aucune position active" desc="Quand un trade sera ouvert (auto ou manuel), il apparaîtra ici." cta="Voir les signaux" onCta={()=>window.location.hash="#/signaux"}/>
      ) : (
        <div style={{ display:"flex", flexDirection:"column", gap:14 }}>
          {filtered.map(p => <MTradingCard key={p.id} p={p} onAction={onAction}/>)}
        </div>
      )}
    </div>
  );
}

function MTradingCard({ p }) {
  const animPnl  = useCountUp(p.pnlEur);
  const animPct  = useCountUp(p.pnlPct);
  const up       = p.pnlEur >= 0;
  const store    = window.useStore ? window.useStore() : {};
  const livePx   = (store.PRICES && store.PRICES[p.pair]) || p.current;
  const [now, setNow] = useStateS(Date.now());
  useEffectS(() => { const t = setInterval(()=>setNow(Date.now()), 1000); return ()=>clearInterval(t); }, []);
  const duration = p.raw?.entry_ts_ms ? (now - p.raw.entry_ts_ms) : 0;
  const isLong   = p.direction === "LONG";

  const sparkData = useMemoS(() => {
    const out = [], start = p.entry, end = livePx || p.current;
    for (let i = 0; i < 24; i++) {
      const t = i / 23;
      const wobble = Math.sin(i * 0.8 + (p.id||"x").charCodeAt(0)) * (Math.abs(end - start) * 0.4);
      out.push(start + (end - start) * t + wobble);
    }
    return out;
  }, [p.entry, livePx, p.id]);

  async function closeAll() {
    if (!confirm(`Fermer ${p.pair} ${p.direction} ?`)) return;
    window.HAPTIC && window.HAPTIC.warn();
    await window.fbClosePos(p);
    emitToast({ type:"success", msg:`Position ${p.pair} fermée` });
  }
  async function closeHalf() {
    if (!p.isReal) { emitToast({ type:"warn", msg:"50% dispo en RÉEL uniquement" }); return; }
    if (!confirm(`Fermer 50% de ${p.pair} ?`)) return;
    window.HAPTIC && window.HAPTIC.toggle();
    const K = new URLSearchParams(location.search).get("key");
    try { await fetch(`/api/close_real_partial/${p.raw.instId}/50`, { method:"POST", credentials:"include" }); emitToast({ type:"success", msg:"50% fermé" }); }
    catch (e) { emitToast({ type:"error", msg:e.message }); }
  }
  async function breakEven() {
    if (p.isReal) { emitToast({ type:"warn", msg:"BE dispo en PAPER uniquement" }); return; }
    window.HAPTIC && window.HAPTIC.toggle();
    const K = new URLSearchParams(location.search).get("key");
    try { const j = await fetch(`/api/move_sl_be/${p.id}`, { method:"POST", credentials:"include" }).then(r=>r.json()); emitToast({ type: j.ok?"success":"error", msg: j.ok?"SL → BE" : (j.msg||"erreur") }); }
    catch (e) { emitToast({ type:"error", msg:e.message }); }
  }

  const slPct  = p.sl  ? ((p.sl  - livePx) / livePx * 100) : 0;
  const tp1Pct = p.tp1 ? ((p.tp1 - livePx) / livePx * 100) : 0;

  return (
    <div className={`m-trade-card ${up?"":"bear"}`}>
      <div className="m-trade-head">
        <PairLogo pair={p.pair} size={28}/>
        <div className="meta">
          <div className="row1">
            <b>{p.pair}/USDT</b>
            <DirBadge dir={p.direction}/>
          </div>
          <div className="row2">
            <span className="lev">×{p.lev}</span>
            <span className={`mode ${p.isReal?"real":"paper"}`}>{p.isReal?"RÉEL":"PAPER"}</span>
            <span className="muted dur">{fmtDur(duration)}</span>
          </div>
        </div>
        <div className="pnl">
          <span className={`val ${up?"bull":"bear"}`}>{up?"+":"−"}€{Math.abs(animPnl).toFixed(2)}</span>
          <span className={`pct ${up?"bull":"bear"}`}>{fmtPct(animPct)}</span>
        </div>
      </div>

      <div className="m-trade-spark">
        <MiniLiveSpark2 data={sparkData} up={up}/>
      </div>

      <div className="m-trade-info">
        <div><span className="k">Prix</span><span className="v mono primary">{fmtNum(livePx)}</span></div>
        <div><span className="k">Distance SL</span><span className={`v mono ${Math.abs(slPct)<0.3?"bear":"muted"}`}>{slPct>=0?"+":""}{slPct.toFixed(2)}%</span></div>
        <div><span className="k">Distance TP1</span><span className={`v mono ${Math.abs(tp1Pct)<0.3?"bull":"muted"}`}>{tp1Pct>=0?"+":""}{tp1Pct.toFixed(2)}%</span></div>
      </div>

      <div className="m-trade-actions">
        <button className="primary danger" onClick={closeAll}><Icon.X size={14}/> FERMER 100%</button>
        <div className="row2">
          <button className="ghost" onClick={closeHalf} disabled={!p.isReal}><Icon.X size={12}/> 50%</button>
          <button className="ghost" onClick={breakEven} disabled={p.isReal}><Icon.Shield size={12}/> BE</button>
          <button className="ghost" onClick={()=>window.location.hash="#/charts"}><Icon.Chart size={12}/> Chart</button>
        </div>
      </div>
    </div>
  );
}

function MiniLiveSpark2({ data, up }) {
  const path = useMemoS(() => {
    if (!data || data.length < 2) return "";
    const min = Math.min(...data), max = Math.max(...data);
    const range = max - min || 1;
    const w = 300, h = 70;
    return data.map((v, i) => {
      const x = (i / (data.length - 1)) * w;
      const y = h - 3 - ((v - min) / range) * (h - 6);
      return (i === 0 ? "M" : "L") + x.toFixed(1) + "," + y.toFixed(1);
    }).join(" ");
  }, [data]);
  const c = up ? "#10B981" : "#EF4444";
  const id = useMemoS(() => "mlsp-" + Math.random().toString(36).slice(2, 8), []);
  return (
    <svg viewBox="0 0 300 70" preserveAspectRatio="none" width="100%" height="70" style={{ display:"block" }}>
      <defs>
        <linearGradient id={id} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={c} stopOpacity="0.32"/>
          <stop offset="100%" stopColor={c} stopOpacity="0"/>
        </linearGradient>
      </defs>
      <path d={path + " L300,70 L0,70 Z"} fill={`url(#${id})`}/>
      <path d={path} stroke={c} strokeWidth="1.8" fill="none" strokeLinecap="round"/>
    </svg>
  );
}

/* ─────────────────────────────────────────────────────────────────
   MobileCharts — chart plein écran TradingView
   ───────────────────────────────────────────────────────────────── */
const M_TF_BAR = { M1:"1m", M5:"5m", M15:"15m", H1:"1H", H4:"4H", D1:"1D" };
function MobileCharts() {
  const containerRef    = useRefS(null);
  const candleSeriesRef = useRefS(null);
  const [pair, setPair] = useStateS("BTC");
  const [tf, setTf]     = useStateS("M15");
  const [candles, setCandles] = useStateS([]);
  const [info, setInfo] = useStateS({ price: 0, chg: 0 });
  const KEY             = new URLSearchParams(location.search).get("key");
  const store           = window.useStore ? window.useStore() : {};
  const livePx          = store.PRICES && store.PRICES[pair];
  const fullPair        = pair + "/USDT:USDT";

  useEffectS(() => {
    const bar = M_TF_BAR[tf] || "15m";
    fetch(`/api/candles?pair=${encodeURIComponent(fullPair)}&bar=${bar}&limit=200`, { credentials: "include" })
      .then(r => r.json())
      .then(j => {
        const arr = (j.candles || []).map(c => ({
          time: Math.floor(c.t / 1000), open: c.open, high: c.high, low: c.low, close: c.close
        }));
        setCandles(arr);
        if (arr.length > 0) {
          const last = arr[arr.length-1], first = arr[0];
          setInfo({ price: last.close, chg: ((last.close - first.open) / first.open) * 100 });
        }
      }).catch(()=>{});
  }, [pair, tf]);

  useEffectS(() => {
    if (!containerRef.current || !window.LightweightCharts || candles.length < 2) return;
    const { createChart } = window.LightweightCharts;
    const chart = createChart(containerRef.current, {
      width: containerRef.current.clientWidth,
      height: containerRef.current.clientHeight,
      layout: { background:{ type:"solid", color:"transparent" }, textColor:"#6B678F", fontFamily:"Geist Mono, monospace" },
      grid: { vertLines:{ color:"#1F1F3A" }, horzLines:{ color:"#1F1F3A" } },
      crosshair: { mode:0 },
      rightPriceScale: { borderColor:"#2A2A4D", textColor:"#6B678F" },
      timeScale: { borderColor:"#2A2A4D", timeVisible:true, secondsVisible:false },
    });
    const cs = chart.addCandlestickSeries({
      upColor:"#10B981", downColor:"#EF4444",
      wickUpColor:"#10B981", wickDownColor:"#EF4444",
      borderVisible: false,
    });
    cs.setData(candles);
    candleSeriesRef.current = cs;
    chart.timeScale().fitContent();
    const ro = new ResizeObserver(() => {
      if (containerRef.current) chart.applyOptions({ width: containerRef.current.clientWidth, height: containerRef.current.clientHeight });
    });
    ro.observe(containerRef.current);
    return () => { ro.disconnect(); candleSeriesRef.current = null; chart.remove(); };
  }, [candles]);

  // Live tick
  useEffectS(() => {
    if (!livePx || !candleSeriesRef.current || candles.length === 0) return;
    const last = candles[candles.length - 1];
    candleSeriesRef.current.update({
      time: last.time, open: last.open,
      high: Math.max(last.high, livePx), low: Math.min(last.low, livePx),
      close: livePx,
    });
    setInfo(prev => candles.length > 0 ? { ...prev, price: livePx, chg: ((livePx - candles[0].open) / candles[0].open) * 100 } : prev);
  }, [livePx]);

  const up = info.chg >= 0;
  const pairs = ["BTC","ETH","SOL","XAU","DOGE","XRP","ADA","SUI","LTC"];

  return (
    <div className="m-page m-chart-page">
      <div className="m-chart-header">
        <div className="m-chart-info">
          <PairLogo pair={pair} size={28}/>
          <div>
            <div style={{ fontSize:14, fontWeight:600 }}>{pair}/USDT</div>
            <div className="muted mono" style={{ fontSize:10 }}>OKX · {M_TF_BAR[tf]}</div>
          </div>
        </div>
        <div className="m-chart-price">
          <span className="mono" style={{ fontSize:18, fontWeight:600, color:"var(--text-primary)" }}>{fmtNum(info.price)}</span>
          <span className={`mono ${up?"bull":"bear"}`} style={{ fontSize:11 }}>{fmtPct(info.chg)}</span>
        </div>
      </div>

      <div className="chips" style={{ paddingBottom:4 }}>
        {pairs.map(p => (
          <div key={p} className={`chip ${pair===p?"active":""}`} onClick={()=>{ window.HAPTIC&&window.HAPTIC.tap(); setPair(p); }}>
            <PairLogo pair={p} size={16}/> {p}
          </div>
        ))}
      </div>

      <div className="chips" style={{ paddingBottom:4 }}>
        {Object.keys(M_TF_BAR).map(t => (
          <div key={t} className={`chip ${tf===t?"active":""}`} onClick={()=>{ window.HAPTIC&&window.HAPTIC.tap(); setTf(t); }}>{t}</div>
        ))}
      </div>

      <div className="m-chart-stage">
        <div ref={containerRef} style={{ width:"100%", height:"100%" }}></div>
      </div>
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────
   MobileMore — container Journal / Stats / Settings / Volatile
   ───────────────────────────────────────────────────────────────── */
function MobileMore({ subpage, onAction }) {
  if (subpage === "journal")  return <MMoreJournal/>;
  if (subpage === "stats")    return <MMoreStats/>;
  if (subpage === "settings") return <MMoreSettings/>;
  if (subpage === "volatile") return <MMoreVolatile onAction={onAction}/>;
  return <MobileSoon name="Page"/>;
}

function MMoreJournal() {
  const store    = window.useStore ? window.useStore() : (window.MOCK || {});
  const JOURNAL  = Array.isArray(store.JOURNAL) ? store.JOURNAL : [];
  const wins     = JOURNAL.filter(j => j && j.result === "win").length;
  const losses   = JOURNAL.filter(j => j && j.result === "loss").length;
  const totalPnl = JOURNAL.reduce((acc, j) => acc + (Number(j && j.pnlEur) || 0), 0);
  const wr       = (wins + losses) > 0 ? (wins / (wins + losses) * 100) : 0;
  return (
    <div className="m-page">
      <div className="m-stat-grid">
        <div className="m-stat-card"><span className="caption">P&L PÉRIODE</span><b className={`mono ${totalPnl>=0?"bull":"bear"}`}>{totalPnl>=0?"+":""}{totalPnl.toFixed(2)}€</b></div>
        <div className="m-stat-card"><span className="caption">WIN RATE</span><b className="mono primary">{wr.toFixed(0)}%</b><span className="muted">{wins}W · {losses}L</span></div>
      </div>
      <h2 className="m-subhead">Historique</h2>
      {JOURNAL.length === 0 ? (
        <MEmpty icon={Icon.Book} title="Aucun trade" desc="L'historique apparaîtra ici quand un trade sera clôturé."/>
      ) : (
        <div style={{ display:"flex", flexDirection:"column", gap:10 }}>
          {JOURNAL.map(j => j && <MJournalRow key={j.id||Math.random()} entry={j}/>)}
        </div>
      )}
    </div>
  );
}

function MJournalRow({ entry }) {
  if (!entry) return null;
  const isOpen = entry.result === "open";
  const isWin  = entry.result === "win";
  const pnlEur = Number(entry.pnlEur) || 0;
  const color  = isOpen ? "var(--info)" : isWin ? "var(--bull)" : "var(--bear)";
  return (
    <div className="m-j-row">
      <span className="rail" style={{ background: color }}></span>
      <div className="meta">
        <div className="line1">
          <PairLogo pair={entry.pair} size={22}/>
          <b>{entry.pair}/USDT</b>
          <DirBadge dir={entry.direction || "LONG"}/>
          <span className={`tag ${isOpen?"open":isWin?"win":"loss"}`}>{isOpen?"OPEN":isWin?"WIN":"LOSS"}</span>
        </div>
        <div className="muted line2">{entry.date || "—"} · {entry.duration || "—"}</div>
      </div>
      <div className="pnl">
        <span className={`mono ${pnlEur>=0?"bull":"bear"}`}>{pnlEur>=0?"+":"−"}€{Math.abs(pnlEur).toFixed(2)}</span>
      </div>
    </div>
  );
}

function MMoreStats() {
  const store = window.useStore ? window.useStore() : {};
  const s     = store.DBSTATS || {};
  return (
    <div className="m-page">
      <div className="m-stat-grid">
        <div className="m-stat-card"><span className="caption">SIGNAUX 24H</span><b className="mono primary">{s.signals_24h ?? "—"}</b></div>
        <div className="m-stat-card"><span className="caption">TRADES 7J</span><b className="mono primary">{s.trades_7d ?? "—"}</b></div>
        <div className="m-stat-card"><span className="caption">WIN RATE</span><b className="mono primary">{s.winrate_pct != null ? s.winrate_pct.toFixed(1)+"%" : "—"}</b></div>
        <div className="m-stat-card"><span className="caption">PnL TOTAL</span><b className={`mono ${(s.pnl_total||0)>=0?"bull":"bear"}`}>{s.pnl_total != null ? (s.pnl_total>=0?"+":"")+s.pnl_total.toFixed(2)+"€" : "—"}</b></div>
        <div className="m-stat-card"><span className="caption">WINS / LOSSES</span><b className="mono primary">{(s.wins ?? 0)} / {(s.losses ?? 0)}</b></div>
        <div className="m-stat-card"><span className="caption">DRAWDOWN MAX</span><b className="mono bear">{s.drawdown_max != null ? s.drawdown_max.toFixed(2)+"%" : "—"}</b></div>
      </div>
    </div>
  );
}

function MMoreSettings() {
  const store    = window.useStore ? window.useStore() : {};
  const st       = store.STATUS || {};
  const scanMode = st.scan_mode || "NORMAL";
  return (
    <div className="m-page">
      <div className="m-settings-section">
        <h2 className="m-subhead">Scanner</h2>
        <div className="m-setting-row">
          <span className="lbl">Mode</span>
          <div className="seg">
            {["SAFE","NORMAL","AVANCE"].map(m => (
              <button key={m} className={scanMode===m?"active":""} onClick={()=>{ window.HAPTIC&&window.HAPTIC.toggle(); window.fbSetScanMode(m); }}>{m}</button>
            ))}
          </div>
        </div>
      </div>
      <div className="m-settings-section">
        <h2 className="m-subhead">Trading</h2>
        <div className="m-setting-row">
          <span className="lbl">Levier</span>
          <div className="seg">
            {[5,10,0].map(v => (
              <button key={v} className={(st.levier===v||(v===0&&!st.levier))?"active":""} onClick={()=>{ window.HAPTIC&&window.HAPTIC.toggle(); window.fbSetLevier(v); }}>{v===0?"Auto":`x${v}`}</button>
            ))}
          </div>
        </div>
        <div className="m-setting-row toggle">
          <span className="lbl">Paper trading<br/><span className="muted">Trades simulés</span></span>
          <span className={`m-toggle ${st.paper_trade?"on":""}`} onClick={()=>{ window.HAPTIC&&window.HAPTIC.toggle(); window.fbToggle("paper"); }}><i></i></span>
        </div>
        <div className="m-setting-row toggle">
          <span className="lbl">Auto-trade<br/><span className="muted">Bot ouvre seul</span></span>
          <span className={`m-toggle ${st.auto_trade?"on":""}`} onClick={()=>{ window.HAPTIC&&window.HAPTIC.toggle(); window.fbToggle("auto"); }}><i></i></span>
        </div>
      </div>
      <div className="m-settings-section">
        <h2 className="m-subhead">Statut</h2>
        <div className="m-setting-row info"><span className="lbl">USDC réel</span><span className="mono primary">{(st.usdc||0).toFixed(2)}$</span></div>
        <div className="m-setting-row info"><span className="lbl">Trades aujourd'hui</span><span className="mono">{st.trades_today||0} / {st.max_trades||5}</span></div>
        <div className="m-setting-row info"><span className="lbl">Daily P&L</span><span className={`mono ${(st.daily_pnl||0)>=0?"bull":"bear"}`}>{(st.daily_pnl||0)>=0?"+":""}{(st.daily_pnl||0).toFixed(2)}€</span></div>
      </div>
      <div className="m-settings-section">
        <h2 className="m-subhead">🔗 Connexion OKX</h2>
        <MOkxSection/>
      </div>

      <div className="m-settings-section">
        <h2 className="m-subhead">🔔 Telegram</h2>
        <MTelegramSection/>
      </div>

      <div className="m-settings-section">
        <h2 className="m-subhead">🆔 Face ID / Touch ID</h2>
        <MWebauthnSection/>
      </div>

      <div className="m-settings-section">
        <h2 className="m-subhead">👤 Compte</h2>
        <div className="m-setting-row info">
          <span className="lbl">Email<br/><span className="muted">{store.AUTH?.user?.email || "—"}</span></span>
          <button className="btn ghost sm" onClick={()=>{ if(confirm("Se déconnecter ?")) window.fbLogout(); }}>Logout</button>
        </div>
      </div>

      <div className="m-settings-section">
        <button className="m-emergency" onClick={()=>{ if(confirm("Stopper auto + fermer toutes positions réelles ?")) { window.HAPTIC&&window.HAPTIC.err(); window.fbEmergencyStop().then(()=>emitToast({type:"warn",msg:"Emergency stop déclenché"})); } }}>
          🛑 Stop auto + fermer tous les réels
        </button>
      </div>
    </div>
  );
}

/* ─── Mobile OKX section ─── */
function MOkxSection() {
  const [status, setStatus]   = useStateS(null);
  const [show, setShow]       = useStateS(false);
  const [apiKey, setApiKey]   = useStateS("");
  const [secret, setSecret]   = useStateS("");
  const [pass, setPass]       = useStateS("");
  const [isDemo, setIsDemo]   = useStateS(false);
  const [busy, setBusy]       = useStateS(false);

  async function load() {
    try { setStatus(await fetch("/api/okx/credentials/status", { credentials:"include" }).then(r=>r.json())); }
    catch {}
  }
  useEffectS(() => { load(); }, []);

  async function save() {
    setBusy(true);
    try {
      const j = await fetch("/api/okx/credentials", {
        method:"POST", credentials:"include",
        headers:{ "Content-Type":"application/json" },
        body: JSON.stringify({ api_key:apiKey, secret, passphrase:pass, is_demo:isDemo })
      }).then(r=>r.json());
      if (j.ok) { emitToast({ type:"success", msg:"OKX connecté" }); setApiKey(""); setSecret(""); setPass(""); setShow(false); load(); }
      else emitToast({ type:"error", msg: j.msg || "Erreur" });
    } catch(e) { emitToast({ type:"error", msg:e.message }); }
    setBusy(false);
  }
  async function del() {
    if (!confirm("Supprimer tes clés OKX ?")) return;
    await fetch("/api/okx/credentials", { method:"DELETE", credentials:"include" });
    load();
  }

  if (status?.connected) {
    return (
      <div className="m-setting-row" style={{ flexDirection:"column", alignItems:"stretch", gap:8 }}>
        <div style={{ display:"flex", justifyContent:"space-between", width:"100%" }}>
          <span style={{ display:"flex", alignItems:"center", gap:6 }}>
            <span style={{ width:7, height:7, borderRadius:"50%", background:"var(--bull)" }}></span>
            <span style={{ fontWeight:500 }}>{status.is_demo?"DEMO":"LIVE"} · {status.api_key_masked}</span>
          </span>
          <button className="btn ghost sm" onClick={del}>Délier</button>
        </div>
      </div>
    );
  }
  if (!show) {
    return <div className="m-setting-row toggle">
      <span className="lbl">Clés OKX<br/><span className="muted">Non configurées</span></span>
      <button className="btn primary sm" onClick={()=>setShow(true)}>Connecter</button>
    </div>;
  }
  return (
    <div className="m-setting-row" style={{ flexDirection:"column", alignItems:"stretch", gap:8 }}>
      <input type="password" placeholder="API Key" value={apiKey} onChange={e=>setApiKey(e.target.value)} style={mInput}/>
      <input type="password" placeholder="Secret Key" value={secret} onChange={e=>setSecret(e.target.value)} style={mInput}/>
      <input type="password" placeholder="Passphrase" value={pass} onChange={e=>setPass(e.target.value)} style={mInput}/>
      <label style={{ display:"flex", alignItems:"center", gap:6, fontSize:12 }}>
        <input type="checkbox" checked={isDemo} onChange={e=>setIsDemo(e.target.checked)}/> Mode DEMO
      </label>
      <div style={{ display:"flex", gap:6 }}>
        <button className="btn ghost sm" onClick={()=>setShow(false)}>Annuler</button>
        <button className="btn primary sm" onClick={save} disabled={busy || !apiKey || !secret || !pass}>{busy?"…":"Sauvegarder"}</button>
      </div>
    </div>
  );
}

/* ─── Mobile Telegram section ─── */
function MTelegramSection() {
  const [status, setStatus] = useStateS(null);
  const [code, setCode]     = useStateS(null);
  const [cd, setCd]         = useStateS(0);

  async function load() {
    try { setStatus(await fetch("/api/telegram/link/status", { credentials:"include" }).then(r=>r.json())); }
    catch {}
  }
  useEffectS(() => { load(); }, []);
  useEffectS(() => {
    if (!code) return;
    setCd(600);
    const t = setInterval(() => setCd(c => Math.max(0, c-1)), 1000);
    const poll = setInterval(load, 3000);
    return () => { clearInterval(t); clearInterval(poll); };
  }, [code]);
  useEffectS(() => { if (status?.linked && code) { setCode(null); emitToast({type:"success",msg:"Telegram lié !"}); } }, [status?.linked]);
  useEffectS(() => { if (cd === 0 && code) setCode(null); }, [cd, code]);

  async function gen() {
    const j = await fetch("/api/telegram/link/generate", { method:"POST", credentials:"include" }).then(r=>r.json());
    if (j.ok) setCode({ value: j.code, bot: j.bot_username });
  }
  async function unlink() {
    if (!confirm("Délier Telegram ?")) return;
    await fetch("/api/telegram/link", { method:"DELETE", credentials:"include" });
    load();
  }

  if (status?.linked) {
    return <div className="m-setting-row">
      <span className="lbl">Lié{status.username?` à @${status.username}`:""}<br/><span className="muted">{status.notifications_enabled?"Notifs ON":"Pause"}</span></span>
      <button className="btn ghost sm" onClick={unlink}>Délier</button>
    </div>;
  }
  if (code) {
    const mm = String(Math.floor(cd/60)).padStart(2,"0"), ss = String(cd%60).padStart(2,"0");
    return <div className="m-setting-row" style={{ flexDirection:"column", alignItems:"stretch", gap:10, padding:14 }}>
      <span className="caption" style={{ textAlign:"center" }}>EXPIRE DANS {mm}:{ss}</span>
      <div className="mono" style={{ fontSize:30, fontWeight:600, color:"var(--accent-400)", letterSpacing:5, textAlign:"center" }}>{code.value}</div>
      <ol style={{ margin:0, paddingLeft:20, fontSize:11, lineHeight:1.6, color:"var(--text-muted)" }}>
        <li>Telegram → <b className="mono">@{code.bot}</b></li>
        <li>Envoie : <code>/link {code.value}</code></li>
      </ol>
      <button className="btn ghost sm" onClick={()=>setCode(null)}>Annuler</button>
    </div>;
  }
  return <div className="m-setting-row">
    <span className="lbl">Non lié<br/><span className="muted">Notifs trading</span></span>
    <button className="btn primary sm" onClick={gen}>Lier</button>
  </div>;
}

/* ─── Mobile WebAuthn section ─── */
function MWebauthnSection() {
  const [creds, setCreds] = useStateS([]);
  const isHttps  = window.location.protocol === "https:" || window.location.hostname === "localhost";
  const isSupp   = typeof window.PublicKeyCredential !== "undefined";

  async function load() {
    try { setCreds((await fetch("/api/webauthn/credentials", { credentials:"include" }).then(r=>r.json())).credentials || []); }
    catch {}
  }
  useEffectS(() => { load(); }, []);

  async function enroll() {
    if (!isHttps) { emitToast({ type:"warn", msg:"Face ID nécessite HTTPS" }); return; }
    try {
      const nick = prompt("Nom de cet appareil ?", "iPhone Face ID") || "Device";
      const j = await window.fbWebauthnRegister(nick);
      if (j.ok) { emitToast({ type:"success", msg:"Biométrie OK" }); load(); }
      else emitToast({ type:"error", msg: j.msg });
    } catch(e) { emitToast({ type:"error", msg:e.message }); }
  }
  async function remove(id) {
    if (!confirm("Supprimer ?")) return;
    await fetch(`/api/webauthn/credentials/${id}`, { method:"DELETE", credentials:"include" });
    load();
  }

  return <div className="m-setting-row" style={{ flexDirection:"column", alignItems:"stretch", gap:8 }}>
    {!isHttps && <span className="muted" style={{ fontSize:11, color:"var(--warn)" }}>⚠️ Requiert HTTPS</span>}
    {!isSupp && <span className="muted" style={{ fontSize:11, color:"var(--bear)" }}>❌ Non supporté par ce navigateur</span>}
    {creds.length === 0
      ? <span className="muted" style={{ fontSize:12 }}>Aucun appareil</span>
      : creds.map(c => <div key={c.id} style={{ display:"flex", justifyContent:"space-between", alignItems:"center", fontSize:12 }}>
          <span>{c.nickname}</span>
          <button className="btn ghost sm" onClick={()=>remove(c.id)}>×</button>
        </div>)}
    <button className="btn primary sm" onClick={enroll} disabled={!isSupp || !isHttps} style={{ alignSelf:"flex-start" }}>
      🆔 Ajouter Face ID
    </button>
  </div>;
}

const mInput = {
  background:"var(--bg-base)", color:"var(--text-primary)",
  border:"1px solid var(--border-base)", borderRadius:8,
  padding:"10px 12px", fontSize:14, outline:"none",
  fontFamily:"var(--font-mono)", width:"100%",
};

function MMoreVolatile({ onAction }) {
  const store    = window.useStore ? window.useStore() : {};
  const VOLATILE = Array.isArray(store.VOLATILE) ? store.VOLATILE : [];
  const [expanded, setExpanded] = useStateS(null);
  const [filter, setFilter]     = useStateS("all");
  const [scanning, setScanning] = useStateS(false);

  const filtered = VOLATILE.filter(s => {
    if (filter === "all")  return true;
    if (filter === "hot")  return s.hot;
    if (filter === "long") return s.direction === "LONG";
    if (filter === "short") return s.direction === "SHORT";
    return true;
  });

  async function doScan() {
    setScanning(true);
    window.HAPTIC && window.HAPTIC.toggle();
    try { await window.fbScan(); } catch {}
    window.HAPTIC && window.HAPTIC.success();
    setScanning(false);
    emitToast({ type:"success", msg:"Scan volatile terminé" });
  }

  const atrAvg = VOLATILE.length ? (VOLATILE.reduce((s,v)=>s+(v.atr||0),0)/VOLATILE.length) : 0;

  return (
    <div className="m-page">
      <div className="m-trading-hero">
        <div>
          <div className="caption">ATR MOYEN</div>
          <div className="mono primary" style={{ fontSize:30, fontWeight:600, letterSpacing:"-0.025em", color: atrAvg>2 ? "var(--bear)" : atrAvg>1 ? "var(--warn)" : "var(--bull)" }}>{atrAvg.toFixed(2)}%</div>
        </div>
        <div style={{ textAlign:"right" }}>
          <div className="caption">PAIRES</div>
          <div className="mono primary" style={{ fontSize:22, fontWeight:600 }}>{VOLATILE.length}</div>
        </div>
      </div>

      <button className="m-scan-btn" onClick={doScan} disabled={scanning}>
        {scanning ? <span className="spinner"></span> : <Icon.Flame size={18}/>}
        <span>{scanning ? "SCANNING..." : "Scanner volatiles"}</span>
      </button>

      <div className="chips" style={{ paddingBottom: 4 }}>
        {[
          { id:"all",   l:"Toutes", n: VOLATILE.length },
          { id:"hot",   l:"🔥 HOT", n: VOLATILE.filter(s=>s.hot).length },
          { id:"long",  l:"LONG",   n: VOLATILE.filter(s=>s.direction==="LONG").length },
          { id:"short", l:"SHORT",  n: VOLATILE.filter(s=>s.direction==="SHORT").length },
        ].map(c => (
          <div key={c.id} className={`chip ${filter===c.id?"active":""}`} onClick={()=>{ window.HAPTIC&&window.HAPTIC.tap(); setFilter(c.id); }}>
            {c.l} <span className="count">{c.n}</span>
          </div>
        ))}
      </div>

      {filtered.length === 0 ? (
        <MEmpty icon={Icon.Flame} title="Aucune paire volatile" desc="Lance un scan pour détecter les paires à fort ATR."/>
      ) : (
        <div className="m-sig-stack">
          {filtered.map(s => (
            <MVolatileExpandable
              key={s.id} signal={s}
              expanded={expanded === s.id}
              onToggle={()=>{ window.HAPTIC&&window.HAPTIC.tap(); setExpanded(expanded === s.id ? null : s.id); }}
              onAction={onAction}
            />
          ))}
        </div>
      )}
    </div>
  );
}

function MVolatileExpandable({ signal, expanded, onToggle, onAction }) {
  const isWait = signal.state === "wait" || !signal.entry;
  return (
    <div className={`m-sig-card ${expanded ? "expanded" : ""} ${signal.hot ? "hot" : ""}`}>
      <div className="m-sig-card-head" onClick={onToggle}>
        <PairLogo pair={signal.pair} size={32}/>
        <div className="sym-name">
          <b style={{ display:"flex", alignItems:"center", gap:6 }}>
            {signal.pair}/USDT
            {signal.hot && <span style={{ background:"rgba(245,158,11,0.18)", color:"var(--warn)", fontSize:9, padding:"2px 6px", borderRadius:4, fontFamily:"var(--font-mono)", letterSpacing:"0.08em", fontWeight:700 }}>🔥 HOT</span>}
          </b>
          <div style={{ display:"flex", alignItems:"center", gap:6, marginTop:2, flexWrap:"wrap" }}>
            <DirBadge dir={signal.direction}/>
            <span style={{ fontSize:11, color: signal.chg24h>=0?"var(--bull)":"var(--bear)", fontFamily:"var(--font-mono)" }}>{fmtPct(signal.chg24h)}</span>
            <span style={{ fontSize:11, color: signal.atr>2 ? "var(--bear)" : signal.atr>1 ? "var(--warn)" : "var(--text-muted)", fontFamily:"var(--font-mono)" }}>ATR {signal.atr?.toFixed(2)}%</span>
          </div>
        </div>
        <div className="sig-side">
          <ScoreBadge score={signal.score}/>
          <Icon.ChevronDown size={14} className="muted" style={{ transition:"transform 200ms", transform: expanded ? "rotate(180deg)" : "none" }}/>
        </div>
      </div>

      {expanded && (
        <div className="m-sig-card-body">
          {isWait ? (
            <div style={{ padding:"10px 12px", background:"rgba(245,158,11,0.10)", border:"1px solid rgba(245,158,11,0.3)", borderRadius:10, fontSize:12, color:"var(--warn)" }}>
              <Icon.Clock size={12} style={{ verticalAlign:"-2px", marginRight:6 }}/>
              WAIT — {signal.waitReason || "filtres pas tous validés, scénario en cours"}
            </div>
          ) : null}

          <div className="m-sig-plan">
            <div className="row"><span>Entrée</span><span className="mono accent">{fmtNum(signal.entry)}</span></div>
            <div className="row"><span>SL</span><span className="mono bear">{fmtNum(signal.sl)}</span></div>
            <div className="row"><span>TP1</span><span className="mono bull">{fmtNum(signal.tp1)}</span></div>
            <div className="row"><span>TP2</span><span className="mono bull">{fmtNum(signal.tp2)}</span></div>
            <div className="row"><span>R/R net</span><span className="mono accent">{signal.rr}</span></div>
          </div>

          <div className="m-sig-pills">
            <div className="pill bear"><span className="caption">Perte max</span><b>−€{(signal.riskEur||0).toFixed(2)}</b></div>
            <div className="pill bull"><span className="caption">Gain TP1</span><b>+€{(signal.gainEur||0).toFixed(2)}</b></div>
            <div className="pill bull"><span className="caption">Gain TP2</span><b>+€{(signal.gainTp2Eur||0).toFixed(2)}</b></div>
          </div>

          <div className="m-sig-tech">
            <span>RSI <b>{(signal.rsi||0).toFixed(1)}</b></span>
            <span>VOL <b>{Math.round(signal.volume||0)}%</b></span>
            <span>ATR <b className={signal.atr>2?"bear":signal.atr>1?"warn":""}>{(signal.atr||0).toFixed(2)}%</b></span>
            <span>MACD <b className={signal.macd?.dir==="up"?"bull":"bear"}>{signal.macd?.dir==="up"?"▲":"▼"}</b></span>
          </div>
          <div style={{ display:"flex", justifyContent:"center", marginTop:-4 }}>
            <RiskBadge signal={signal}/>
          </div>

          {/* Actions toujours visibles : même en WAIT, l'user peut trader manuel (Entry/SL/TP restent valides). */}
          {signal.entry > 0 && (
            <div className="m-sig-actions">
              <button className="act paper-long" onClick={()=>{ window.HAPTIC&&window.HAPTIC.press(); onAction&&onAction("paper-long", signal); }}>
                <Icon.Edit size={12}/> PAPER ▲
              </button>
              <button className="act paper-short" onClick={()=>{ window.HAPTIC&&window.HAPTIC.press(); onAction&&onAction("paper-short", signal); }}>
                <Icon.Edit size={12}/> PAPER ▼
              </button>
              <button className="act real-long" onClick={()=>{
                const warn = isWait ? "⚠️ Signal WAIT (score <7). Ouvrir RÉEL LONG quand même ?" : "Ouvrir RÉEL LONG ?";
                if(confirm(warn)) { window.HAPTIC&&window.HAPTIC.success(); onAction&&onAction("real-long", signal); }
              }}>
                <Icon.Flash size={12}/> RÉEL ▲
              </button>
              <button className="act real-short" onClick={()=>{
                const warn = isWait ? "⚠️ Signal WAIT (score <7). Ouvrir RÉEL SHORT quand même ?" : "Ouvrir RÉEL SHORT ?";
                if(confirm(warn)) { window.HAPTIC&&window.HAPTIC.success(); onAction&&onAction("real-short", signal); }
              }}>
                <Icon.Flash size={12}/> RÉEL ▼
              </button>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────
   Helpers partagés
   ───────────────────────────────────────────────────────────────── */
function MEmpty({ icon: I, title, desc, cta, onCta }) {
  return (
    <div className="m-empty">
      <div className="ico"><I size={26}/></div>
      <h3>{title}</h3>
      <p>{desc}</p>
      {cta && <button className="m-cta" onClick={onCta}>{cta}</button>}
    </div>
  );
}
function fmtDur(ms) {
  if (!ms || ms <= 0) return "—";
  const s = Math.floor(ms / 1000);
  if (s < 60)    return `${s}s`;
  if (s < 3600)  return `${Math.floor(s/60)}m`;
  if (s < 86400) return `${Math.floor(s/3600)}h ${Math.floor((s%3600)/60)}m`;
  return `${Math.floor(s/86400)}j`;
}

Object.assign(window, { MobileSignaux, MobileTrading, MobileCharts, MobileMore });
