/* ═══════════════════════════════════════════════════════════════
   FOXBOT PRO — MOBILE SHELL
   App container · Header · Bottom Nav · Bottom Sheet · Haptic
   ═══════════════════════════════════════════════════════════════ */

const { useState: useStateM, useEffect: useEffectM, useRef: useRefM, useCallback: useCallbackM } = React;

/* ─── Haptic helper (silently noop on unsupported) ─── */
function haptic(pattern = 10) {
  try {
    if (navigator.vibrate) navigator.vibrate(pattern);
  } catch (e) { /* noop */ }
}
const HAPTIC = {
  tap:      () => haptic(8),
  press:    () => haptic(18),
  toggle:   () => haptic(12),
  snap:     () => haptic([8, 4, 8]),
  success:  () => haptic([22, 14, 22]),
  warn:     () => haptic([35, 22, 35]),
  err:      () => haptic([50, 30, 50, 30, 50]),
};
window.HAPTIC = HAPTIC;

/* ─── Mobile detection hook ─── */
function useIsMobile(breakpoint = 768) {
  const [is, setIs] = useStateM(() =>
    typeof window !== "undefined" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
  );
  useEffectM(() => {
    const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
    const onChange = (e) => setIs(e.matches);
    mq.addEventListener("change", onChange);
    return () => mq.removeEventListener("change", onChange);
  }, [breakpoint]);
  useEffectM(() => {
    document.documentElement.dataset.mobile = is ? "true" : "false";
  }, [is]);
  return is;
}
window.useIsMobile = useIsMobile;

/* ─── Brand mark (small fox glyph) ─── */
function MBrandMark() {
  return (
    <img src="/static/icon-192.png" alt="FoxBot Pro" width="32" height="32"
      style={{ display:"block", borderRadius:7, flexShrink:0 }}/>
  );
}

/* ─── Header ─── */
const ROUTE_TITLES = {
  dashboard: "Dashboard",
  trading:   "Trading",
  signaux:   "Signaux",
  charts:    "Charts",
  more:      "Plus",
  journal:   "Journal",
  stats:     "Statistiques",
  settings:  "Paramètres",
  volatile:  "Volatiles",
};

function MobileHeader({ route, mode, onToggleMode, onNotif }) {
  const [scrolled, setScrolled] = useStateM(false);
  useEffectM(() => {
    const onScroll = () => setScrolled(window.scrollY > 6);
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  // Notif-dot uniquement si vraie raison de l'allumer :
  // - un signal éligible récent (≥ 7/10 actif)
  // - une position dont SL/TP est proche (< 0.5%)
  const store = window.useStore ? window.useStore() : (window.MOCK || {});
  const hasNotif = (() => {
    const sigs = Array.isArray(store.SIGNALS) ? store.SIGNALS : [];
    if (sigs.some(s => s && s.state === "active" && (s.score || 0) >= 8)) return true;
    const pos = Array.isArray(store.POSITIONS) ? store.POSITIONS : [];
    return pos.some(p => {
      if (!p) return false;
      const px = (store.PRICES && store.PRICES[p.pair]) || p.current;
      const slDist  = p.sl  ? Math.abs((p.sl  - px) / px * 100) : 99;
      const tp1Dist = p.tp1 ? Math.abs((p.tp1 - px) / px * 100) : 99;
      return slDist < 0.5 || tp1Dist < 0.5;
    });
  })();
  return (
    <header className={`m-header ${scrolled ? "scrolled" : ""}`}>
      <div className="m-header-inner">
        <MBrandMark />
        <div className="m-header-title">
          <span className="crumb">FOXBOT PRO</span>
          <h1>{ROUTE_TITLES[route] || route}</h1>
        </div>
        <div className="m-header-actions">
          <button className={`m-mode-pill ${mode === "LIVE" ? "live" : "paper"}`}
            onClick={() => { HAPTIC.toggle(); onToggleMode(); }}>
            <span className={`live-dot ${mode === "PAPER" ? "paper-dot" : ""}`}></span>
            {mode}
          </button>
          <button className="m-icon-btn" onClick={() => { HAPTIC.tap(); onNotif && onNotif(); }} aria-label="Notifications">
            <Icon.Bell size={16}/>
            {hasNotif && <span className="notif-dot"></span>}
          </button>
        </div>
      </div>
    </header>
  );
}

/* ─── Bottom Nav ─── */
function MobileBottomNav({ route, onRoute, onMore }) {
  // Compteurs RÉELS depuis le store
  const store        = window.useStore ? window.useStore() : (window.MOCK || {});
  const posCount     = Array.isArray(store.POSITIONS) ? store.POSITIONS.length : 0;
  const signalsCount = Array.isArray(store.SIGNALS)
    ? store.SIGNALS.filter(s => s && (s.state === "active" || (s.score >= 7 && s.direction))).length
    : 0;
  const items = [
    { id: "dashboard", i: Icon.Home,     l: "Home" },
    { id: "trading",   i: Icon.Activity, l: "Trading", badge: posCount || null },
    { id: "signaux",   i: Icon.Zap,      l: "Signaux", badge: signalsCount || null },
    { id: "charts",    i: Icon.Chart,    l: "Charts" },
    { id: "more",      i: MoreIcon,      l: "Plus" },
  ];
  return (
    <nav className="m-nav">
      <div className="m-nav-inner">
        {items.map(it => {
          const active = route === it.id || (it.id === "more" && ["journal","stats","settings","volatile"].includes(route));
          return (
            <div key={it.id}
              className={`m-nav-item ${active ? "active" : ""}`}
              onClick={() => {
                HAPTIC.tap();
                if (it.id === "more") onMore();
                else onRoute(it.id);
              }}>
              <span className="m-nav-pill"></span>
              <div className="m-nav-icon-wrap">
                <it.i size={22}/>
                {it.badge && !active && <span className="m-nav-badge">{it.badge}</span>}
              </div>
              <span className="m-nav-label">{it.l}</span>
            </div>
          );
        })}
      </div>
    </nav>
  );
}

function MoreIcon({ size = 22 }) {
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill="none"
         stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="5" cy="12" r="1.6" fill="currentColor"/>
      <circle cx="12" cy="12" r="1.6" fill="currentColor"/>
      <circle cx="19" cy="12" r="1.6" fill="currentColor"/>
    </svg>
  );
}

/* ─── Bottom Sheet ─── */
function BottomSheet({ open, onClose, title, children, height }) {
  const [closing, setClosing] = useStateM(false);
  const [mounted, setMounted] = useStateM(open);

  useEffectM(() => {
    if (open) { setMounted(true); setClosing(false); }
    else if (mounted) {
      setClosing(true);
      const t = setTimeout(() => { setMounted(false); setClosing(false); }, 200);
      return () => clearTimeout(t);
    }
  }, [open]);

  useEffectM(() => {
    if (!mounted) return;
    document.body.style.overflow = "hidden";
    return () => { document.body.style.overflow = ""; };
  }, [mounted]);

  if (!mounted) return null;

  return (
    <React.Fragment>
      <div className={`m-sheet-backdrop ${closing ? "closing" : ""}`} onClick={() => { HAPTIC.tap(); onClose(); }}></div>
      <div className={`m-sheet ${closing ? "closing" : ""}`} style={height ? { maxHeight: height } : undefined}>
        <div className="m-sheet-handle"></div>
        {title && <h3>{title}</h3>}
        <div style={{ overflow: "auto", flex: 1 }} className="m-scrollable">
          {children}
        </div>
      </div>
    </React.Fragment>
  );
}
window.BottomSheet = BottomSheet;

/* ─── More Sheet ─── */
function MoreSheet({ open, onClose, onRoute }) {
  const items = [
    { id: "journal",  i: Icon.Book,     l: "Journal de trading" },
    { id: "stats",    i: Icon.Stats,    l: "Statistiques" },
    { id: "volatile", i: Icon.Flame,    l: "Cryptos volatiles" },
    { id: "settings", i: Icon.Settings, l: "Paramètres" },
    { id: "alerts",   i: Icon.Bell,     l: "Notifications" },
    { id: "help",     i: Icon.AlertTriangle, l: "Aide & Support" },
  ];
  return (
    <BottomSheet open={open} onClose={onClose} title="Plus d'options">
      <div className="m-sheet-list">
        {items.map(it => (
          <div key={it.id} className="m-sheet-item"
            onClick={() => { HAPTIC.tap(); onRoute(it.id); onClose(); }}>
            <span className="ic"><it.i size={14}/></span>
            <span className="lbl">{it.l}</span>
            <span className="chev"><Icon.ChevronRight size={14}/></span>
          </div>
        ))}
      </div>
    </BottomSheet>
  );
}
window.MoreSheet = MoreSheet;

/* ─── MobileApp — main shell ─── */
function MobileApp({ tweaks, setTweak, onAction }) {
  const [route, setRoute] = useStateM(() => {
    const h = (window.location.hash || "").replace("#/", "");
    return ROUTE_TITLES[h] ? h : "dashboard";
  });
  const [moreOpen, setMoreOpen] = useStateM(false);

  useEffectM(() => { window.location.hash = "#/" + route; }, [route]);

  function handleRoute(id) {
    if (id === route) return;
    HAPTIC.tap();
    setRoute(id);
  }

  return (
    <div className="m-app" data-screen-label={"M " + (ROUTE_TITLES[route] || route)}>
      <MobileHeader
        route={route}
        mode={tweaks.mode}
        onToggleMode={() => setTweak({ mode: tweaks.mode === "LIVE" ? "PAPER" : "LIVE" })}
      />

      <main className="m-screen" key={route}>
        {route === "dashboard" && window.MobileDashboard && <MobileDashboard onAction={onAction} onRoute={handleRoute}/>}
        {route === "trading"   && window.MobileTrading   && <MobileTrading onAction={onAction}/>}
        {route === "trading"   && !window.MobileTrading  && <MobileSoon name="Trading"/>}
        {route === "signaux"   && window.MobileSignaux   && <MobileSignaux onAction={onAction}/>}
        {route === "signaux"   && !window.MobileSignaux  && <MobileSoon name="Signaux"/>}
        {route === "charts"    && window.MobileCharts    && <MobileCharts/>}
        {route === "charts"    && !window.MobileCharts   && <MobileSoon name="Charts"/>}
        {(route === "journal" || route === "stats" || route === "settings" || route === "volatile") && (
          window.MobileMore ? <MobileMore subpage={route} onAction={onAction}/> : <MobileSoon name={ROUTE_TITLES[route]}/>
        )}
      </main>

      <MobileBottomNav route={route} onRoute={handleRoute} onMore={() => { HAPTIC.tap(); setMoreOpen(true); }}/>
      <MoreSheet open={moreOpen} onClose={() => setMoreOpen(false)} onRoute={handleRoute}/>
    </div>
  );
}

function MobileSoon({ name }) {
  return (
    <div className="m-page">
      <div style={{
        background: "var(--bg-elevated)",
        border: "1px dashed var(--border-base)",
        borderRadius: "20px",
        padding: "60px 24px",
        textAlign: "center",
        display: "flex", flexDirection: "column", alignItems: "center", gap: 12
      }}>
        <div style={{
          width: 56, height: 56, borderRadius: 14,
          background: "var(--accent-soft)",
          color: "var(--accent-400)",
          display: "grid", placeItems: "center",
          boxShadow: "0 0 32px var(--accent-glow)",
        }}>
          <Icon.Sparkles size={24}/>
        </div>
        <div style={{ fontSize: 16, fontWeight: 600, color: "var(--text-primary)" }}>{name} arrive</div>
        <div style={{ fontSize: 13, color: "var(--text-muted)", maxWidth: 260, lineHeight: 1.5 }}>
          Cet écran sera refait dans l'étape suivante. Tu peux valider le shell (header, nav, sheets) en attendant.
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { MobileApp, MobileHeader, MobileBottomNav, MoreSheet, MBrandMark, HAPTIC });
