/* Admin, mobile, UX features 41-50 */

/* ─── 42. ASIN Scanner (camera) ───────────────────────────────────── */
const AsinScanner = () => {
  const toast = (typeof useToastX === "function") ? useToastX() : null;
  const LS_SCANS = "kcc:asin-scans";
  const SEED = [
    { ts: "il y a 2min", asin: "B0CXYZ1234", from: "Caméra mobile (Carly)", matched: true,  product: "Diffuseur ambré 700ml" },
    { ts: "il y a 8min", asin: "B0CABC4567", from: "Caméra mobile (Kevin)", matched: true,  product: "Lampe USB dimmable" },
    { ts: "il y a 14min",asin: "B0NEW00001", from: "Caméra mobile (Carly)", matched: false, product: "Non répertorié · à ajouter" },
  ];
  const load = () => { try { const s = localStorage.getItem(LS_SCANS); return s ? JSON.parse(s) : SEED; } catch { return SEED; } };
  const [scanning, setScanning] = useState(false);
  const [scanned, _setScanned] = useState(load);
  const persist = (next) => { _setScanned(next); try { localStorage.setItem(LS_SCANS, JSON.stringify(next)); } catch {} };
  const manualScan = async () => {
    const asin = (prompt("Saisir l'ASIN (ou code-barre) :", "B0") || "").trim().toUpperCase();
    if (!asin) return;
    setScanning(true);
    // Try Keepa lookup if API client is present
    let product = "Recherche…";
    let matched = false;
    try {
      if (typeof window.keepa?.lookup === "function") {
        const r = await window.keepa.lookup(asin);
        product = r?.title || "ASIN inconnu";
        matched = !!r?.title;
      } else {
        const r = await fetch("/api/keepa?asin=" + encodeURIComponent(asin)).then(res => res.ok ? res.json() : null);
        product = r?.title || r?.product?.title || "ASIN non trouvé";
        matched = !!product && product !== "ASIN non trouvé";
      }
    } catch (e) { product = "Échec lookup · ajouter manuellement"; }
    setScanning(false);
    const entry = { ts: new Date().toLocaleTimeString("fr-CA"), asin, from: "Saisie manuelle", matched, product };
    persist([entry, ...scanned].slice(0, 50));
    toast?.push?.({ tone: matched ? "good" : "warn", title: matched ? "ASIN trouvé" : "ASIN inconnu", body: product });
  };
  const addToCatalog = (entry) => {
    try {
      const cat = JSON.parse(localStorage.getItem("kcc:products") || "[]");
      cat.unshift({ id: entry.asin, asin: entry.asin, name: entry.product, addedAt: new Date().toISOString() });
      localStorage.setItem("kcc:products", JSON.stringify(cat));
      persist(scanned.map(s => s.asin === entry.asin ? { ...s, matched: true } : s));
      toast?.push?.({ tone: "good", title: "Ajouté au catalogue", body: entry.asin });
    } catch (e) { toast?.push?.({ tone: "danger", title: "Erreur ajout" }); }
  };
  return (
    <div className="page" style={{ maxWidth: 1000 }}>
      <div className="page-head">
        <div>
          <div className="page-title">Scanner ASIN</div>
          <div className="page-sub">Caméra mobile · scan code-barre Amazon depuis l'app PWA · ajout au catalogue en 1 tap</div>
        </div>
      </div>
      <div className="grid" style={{ gridTemplateColumns: "320px 1fr", gap: 14 }}>
        <div className="card" style={{ padding: 0, overflow: "hidden" }}>
          <div style={{ background: "#000", aspectRatio: "9/16", maxHeight: 500, position: "relative", display: "grid", placeItems: "center" }}>
            <div style={{ position: "absolute", inset: 24, border: "2px solid oklch(0.78 0.18 248 / 0.7)", borderRadius: 16, animation: scanning ? "scan-pulse 1.4s ease-in-out infinite" : "none" }}/>
            <div style={{ position: "absolute", left: 0, right: 0, height: 2, top: "50%", background: "var(--accent)", boxShadow: "0 0 16px var(--accent)" }}/>
            <div style={{ position: "absolute", bottom: 18, left: 0, right: 0, textAlign: "center", color: "#fff", fontSize: 11.5 }}>
              {scanning ? "Recherche d'un code-barre…" : "Pointez la caméra vers le code-barre"}
            </div>
            <div style={{ position: "absolute", top: 14, left: 14, right: 14, display: "flex", justifyContent: "space-between", color: "#fff", fontSize: 10.5 }}>
              <span>← Annuler</span>
              <span>🔦</span>
            </div>
          </div>
          <div style={{ padding: 12 }}>
            <button onClick={manualScan} className="btn" data-variant="primary" style={{ width: "100%", justifyContent: "center" }}>
              <Icon name="search" size={13}/> {scanning ? "Recherche…" : "Scanner / saisir ASIN"}
            </button>
          </div>
        </div>
        <div className="card" style={{ padding: 0 }}>
          <div className="card-head"><div><div className="card-title">Scans récents</div><div className="card-sub">Synchronisé entre tous les téléphones de l'équipe</div></div></div>
          <table className="table">
            <thead><tr><th>Quand</th><th>ASIN</th><th>Source</th><th>Produit</th><th></th></tr></thead>
            <tbody>
              {scanned.map((s, i) => (
                <tr key={i}>
                  <td className="mono muted">{s.ts}</td>
                  <td className="mono">{s.asin}</td>
                  <td className="muted">{s.from}</td>
                  <td>{s.product}</td>
                  <td>
                    {s.matched
                      ? <Badge tone="green" dot>déjà en catalogue</Badge>
                      : <button onClick={() => addToCatalog(s)} className="btn" data-size="sm" data-variant="primary">Ajouter</button>}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
      <style>{`@keyframes scan-pulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }`}</style>
    </div>
  );
};

/* ─── 41, 43. PWA install card + push notifs config ─────────────── */
const MobileSetup = () => {
  const toast = (typeof useToastX === "function") ? useToastX() : null;
  const NOTIF_SEED = [
    { l: "Alertes critiques",         d: "Stock <3j, marge négative, échec 2FA",      on: true },
    { l: "Messages directs",          d: "DM ou mention dans un canal",               on: true },
    { l: "Daily Digest",              d: "Récap quotidien 07:00",                     on: false },
    { l: "JARVIS Autopilot",          d: "Quand une suggestion à fort impact apparaît", on: true },
    { l: "Rapport hebdo",             d: "Lundi matin · résumé de la semaine",        on: false },
  ];
  const [notifs, setNotifs] = useState(() => { try { const s = localStorage.getItem("kcc:notif-prefs"); return s ? JSON.parse(s) : NOTIF_SEED; } catch { return NOTIF_SEED; } });
  const toggleNotif = (i) => setNotifs((arr) => { const v = arr.map((n, j) => j === i ? { ...n, on: !n.on } : n); try { localStorage.setItem("kcc:notif-prefs", JSON.stringify(v)); } catch {} return v; });
  const installApp = async () => {
    const evt = window.__kccDeferredPrompt;
    if (evt && evt.prompt) {
      evt.prompt();
      const { outcome } = await evt.userChoice;
      toast?.push?.({ tone: outcome === "accepted" ? "good" : "warn", title: outcome === "accepted" ? "App installée" : "Installation annulée" });
      window.__kccDeferredPrompt = null;
    } else {
      toast?.push?.({ tone: "warn", title: "Installation manuelle", body: "Menu navigateur → « Ajouter à l'écran d'accueil »." });
    }
  };
  return (
  <div className="page">
    <div className="page-head">
      <div>
        <div className="page-title">Mobile & notifications</div>
        <div className="page-sub">Installez le portail comme app · activez les notifs push · alertes critiques temps réel</div>
      </div>
    </div>
    <div className="grid" style={{ gridTemplateColumns: "1fr 1fr", gap: 14 }}>
      <div className="card" style={{ padding: 20 }}>
        <div className="row" style={{ gap: 12, marginBottom: 14 }}>
          <div style={{ width: 48, height: 48, borderRadius: 10, background: "linear-gradient(135deg, oklch(0.78 0.17 248), oklch(0.55 0.18 258))", display: "grid", placeItems: "center", color: "white", fontWeight: 700 }}>KC</div>
          <div>
            <div style={{ fontSize: 16, fontWeight: 600 }}>Installer comme application</div>
            <div style={{ fontSize: 12, color: "var(--text-dim)", marginTop: 2 }}>iOS · Android · macOS · Windows · ChromeOS</div>
          </div>
        </div>
        <div className="stack" style={{ gap: 8, marginBottom: 14 }}>
          {[
            "Icône sur l'écran d'accueil · lancement instantané",
            "Mode offline-first : Dashboard et Messages disponibles sans réseau",
            "Notifications natives (avec son et badge)",
            "Stockage local IndexedDB chiffré pour le cache",
          ].map((t, i) => (
            <div key={i} className="row" style={{ gap: 8, fontSize: 12 }}>
              <Icon name="check" size={11} style={{ color: "var(--green)" }}/>
              <span>{t}</span>
            </div>
          ))}
        </div>
        <button onClick={installApp} className="btn" data-variant="primary"><Icon name="download" size={13}/> Installer l'app</button>
      </div>

      <div className="card" style={{ padding: 18 }}>
        <div style={{ fontSize: 14, fontWeight: 600 }}>Notifications push</div>
        <div style={{ fontSize: 11.5, color: "var(--text-dim)", marginTop: 4, marginBottom: 14 }}>Configurez ce que vous voulez recevoir en push web ou natif</div>
        {notifs.map((n, i) => (
          <div key={i} className="between" style={{ padding: "9px 0", borderTop: i ? "1px solid var(--border-subtle)" : "none" }}>
            <div>
              <div style={{ fontSize: 12.5, fontWeight: 500 }}>{n.l}</div>
              <div style={{ fontSize: 11, color: "var(--text-dim)", marginTop: 2 }}>{n.d}</div>
            </div>
            <button onClick={() => toggleNotif(i)} style={{ width: 36, height: 20, borderRadius: 999, background: n.on ? "var(--accent)" : "var(--bg-4)", border: "none", position: "relative", cursor: "pointer" }}>
              <div style={{ position: "absolute", top: 2, left: n.on ? 18 : 2, width: 16, height: 16, borderRadius: "50%", background: "white", transition: "left 200ms" }}/>
            </button>
          </div>
        ))}
      </div>
    </div>
  </div>
  );
};

/* ─── 44. Onboarding flow ────────────────────────────────────────── */
const Onboarding = () => {
  const toast = (typeof useToastX === "function") ? useToastX() : null;
  const [step, setStep] = useState(2);
  const steps = [
    { id: 1, label: "Bienvenue",        desc: "Présentation du portail · 1 min",                  done: true },
    { id: 2, label: "Activer 2FA",      desc: "Sécurisez votre compte avec un code email",        done: false },
    { id: 3, label: "Compléter profil", desc: "Nom, rôle, photo, fuseau",                          done: false },
    { id: 4, label: "Connecter Sheets", desc: "Sync bidirectionnelle Google Sheets · OAuth",      done: false },
    { id: 5, label: "Choisir thème",    desc: "Sombre, clair, accent · personnalisation",         done: false },
    { id: 6, label: "Tour guidé",       desc: "Découvrir Dashboard, JARVIS, Messages",            done: false },
  ];
  return (
    <div className="page" style={{ maxWidth: 900 }}>
      <div className="page-head">
        <div>
          <div className="page-title">Bienvenue chez KCC Holdings</div>
          <div className="page-sub">Configurez votre portail en {steps.length - 1} étapes · ~5 minutes</div>
        </div>
      </div>

      <div className="card" style={{ padding: 0 }}>
        <div style={{ padding: 20, borderBottom: "1px solid var(--border-subtle)" }}>
          <div className="row" style={{ gap: 16 }}>
            {steps.map((s, i) => (
              <div key={s.id} className="row" style={{ gap: 6, flex: 1, minWidth: 0 }}>
                <div style={{
                  width: 26, height: 26, borderRadius: 999,
                  background: step > s.id || s.done ? "var(--green)" : step === s.id ? "var(--accent)" : "var(--bg-3)",
                  color: step > s.id || s.done || step === s.id ? "white" : "var(--text-dim)",
                  display: "grid", placeItems: "center",
                  fontSize: 11, fontWeight: 700,
                }}>
                  {step > s.id || s.done ? <Icon name="check" size={12}/> : s.id}
                </div>
                {i < steps.length - 1 && <div style={{ flex: 1, height: 2, background: step > s.id ? "var(--green)" : "var(--bg-3)", borderRadius: 999 }}/>}
              </div>
            ))}
          </div>
          <div className="row" style={{ gap: 24, marginTop: 8, fontSize: 11, color: "var(--text-dim)" }}>
            {steps.map((s) => <div key={s.id} style={{ flex: 1, textAlign: "left" }}>{s.label}</div>)}
          </div>
        </div>
        <div style={{ padding: 28 }}>
          <div style={{ fontSize: 22, fontWeight: 600, letterSpacing: "-0.015em" }}>{steps[step - 1].label}</div>
          <div style={{ fontSize: 13, color: "var(--text-dim)", marginTop: 6, maxWidth: 480 }}>{steps[step - 1].desc}</div>

          <div style={{ marginTop: 24, padding: 20, background: "var(--bg-2)", borderRadius: 12, maxWidth: 480 }}>
            {step === 2 && (
              <div>
                <div style={{ fontSize: 13, marginBottom: 12 }}>Saisissez votre numéro pour recevoir un code de vérification :</div>
                <input className="input" placeholder="clarens@kcc.ca" defaultValue="clarens@kcc.ca" style={{ marginBottom: 10 }}/>
                <button onClick={() => toast?.push?.({ tone: "good", title: "Code envoyé", body: "Vérifiez votre boîte mail." })} className="btn" data-variant="primary" style={{ width: "100%", justifyContent: "center" }}>Recevoir un code</button>
              </div>
            )}
          </div>

          <div className="row" style={{ marginTop: 28, gap: 8 }}>
            <button className="btn" disabled={step === 1} onClick={() => setStep(s => s - 1)}>← Précédent</button>
            <button className="btn" data-variant="ghost" style={{ marginLeft: "auto" }} onClick={() => setStep(s => Math.min(s + 1, steps.length))}>Passer</button>
            <button className="btn" data-variant="primary" onClick={() => setStep(s => Math.min(s + 1, steps.length))}>Continuer →</button>
          </div>
        </div>
      </div>
    </div>
  );
};

/* ─── 47. Backups ────────────────────────────────────────────────── */
const Backups = () => {
  const toast = useToastX();
  const LS_BACKUPS = "kcc:backups-log";
  const loadLog = () => { try { return JSON.parse(localStorage.getItem(LS_BACKUPS) || "[]"); } catch { return []; } };
  const [backups, setBackups] = useState(() => {
    const log = loadLog();
    if (log.length) return log;
    // Seed default rows on first visit
    return Array.from({ length: 10 }, (_, i) => ({
      date: `${10 - i} mai`,
      time: "03:00 ET",
      size: (47 + Math.random() * 4).toFixed(1) + " MB",
      tables: 18,
      status: i === 0 ? "auto" : i === 3 ? "manuel" : "auto",
      r2Key: `kcc-d1-${20260510 - i}.snapshot.sql.gz`,
    }));
  });
  const persist = (next) => { setBackups(next); try { localStorage.setItem(LS_BACKUPS, JSON.stringify(next)); } catch {} };
  const exportNow = () => {
    // Dump every kcc:* localStorage key into a JSON file
    const snap = {};
    let bytes = 0;
    for (let i = 0; i < localStorage.length; i++) {
      const k = localStorage.key(i);
      if (k && k.startsWith("kcc:")) { snap[k] = localStorage.getItem(k); bytes += (snap[k] || "").length; }
    }
    const payload = { ts: new Date().toISOString(), keys: Object.keys(snap).length, snap };
    const blob = new Blob([JSON.stringify(payload, null, 2)], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = `kcc-backup-${Date.now()}.json`; a.click();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
    const sizeMb = (bytes / 1024 / 1024).toFixed(2) + " MB";
    const row = {
      date: new Date().toLocaleDateString("fr-CA", { day: "numeric", month: "short" }),
      time: new Date().toLocaleTimeString("fr-CA", { hour: "2-digit", minute: "2-digit" }) + " ET",
      size: sizeMb,
      tables: Object.keys(snap).length,
      status: "manuel",
      r2Key: `kcc-local-${Date.now()}.json`,
    };
    persist([row, ...backups].slice(0, 30));
    fetch("/api/sync", { method: "PUT", body: JSON.stringify({ col: "_backup", items: [payload] }) }).catch(() => null);
    toast?.push?.({ tone: "good", title: "Backup créé", body: `${Object.keys(snap).length} clés · ${sizeMb}` });
  };
  const restoreFile = () => {
    const inp = document.createElement("input");
    inp.type = "file"; inp.accept = "application/json";
    inp.onchange = (e) => {
      const f = e.target.files?.[0]; if (!f) return;
      const r = new FileReader();
      r.onload = () => {
        try {
          const data = JSON.parse(r.result);
          if (!data?.snap) throw new Error("Format invalide");
          if (!confirm(`Restaurer ${Object.keys(data.snap).length} clés ? Les données actuelles seront écrasées.`)) return;
          Object.entries(data.snap).forEach(([k, v]) => localStorage.setItem(k, v));
          toast?.push?.({ tone: "good", title: "Restauration OK", body: "Recharge la page pour appliquer." });
        } catch (err) { toast?.push?.({ tone: "danger", title: "Échec restauration", body: String(err.message || err) }); }
      };
      r.readAsText(f);
    };
    inp.click();
  };
  const totalBytes = backups.reduce((s, b) => s + (parseFloat(b.size) || 0), 0);
  return (
    <div className="page">
      <div className="page-head">
        <div>
          <div className="page-title">Backups</div>
          <div className="page-sub">Export complet localStorage (kcc:*) en JSON · restauration en 1 clic</div>
        </div>
        <div className="row" style={{ gap: 6 }}>
          <button className="btn" onClick={restoreFile}><Icon name="upload" size={13}/> Restaurer</button>
          <button className="btn" data-variant="primary" onClick={exportNow}><Icon name="download" size={13}/> Backup manuel</button>
        </div>
      </div>
      <div className="grid" style={{ gridTemplateColumns: "repeat(4, 1fr)", marginBottom: 14 }}>
        <KpiCard label="Dernier backup"      value={backups[0]?.time || "—"} sparkColor="var(--green)" muted/>
        <KpiCard label="Total snapshots"      value={String(backups.length)}  muted/>
        <KpiCard label="Clés kcc:*"           value={String(Object.keys(localStorage).filter(k=>k.startsWith("kcc:")).length)} delta={0}/>
        <KpiCard label="RPO"                  value="manuel"            muted/>
      </div>
      <div className="card" style={{ padding: 0 }}>
        <table className="table">
          <thead><tr><th>Date</th><th>Heure</th><th style={{textAlign:"right"}}>Taille</th><th style={{textAlign:"right"}}>Tables</th><th>Statut</th><th>R2 Key</th><th></th></tr></thead>
          <tbody>
            {backups.map((b, i) => (
              <tr key={i}>
                <td className="mono">{b.date}</td>
                <td className="mono muted">{b.time}</td>
                <td className="num" style={{ textAlign: "right" }}>{b.size}</td>
                <td className="num" style={{ textAlign: "right" }}>{b.tables}</td>
                <td><Badge tone={b.status === "auto" ? "blue" : "violet"} dot>{b.status}</Badge></td>
                <td><span className="mono" style={{ fontSize: 10.5, color: "var(--text-faint)" }}>{b.r2Key}</span></td>
                <td>
                  <div className="row" style={{ gap: 4 }}>
                    <button className="btn" data-size="sm" title="Télécharger ce snapshot" onClick={() => {
                      const blob = new Blob([JSON.stringify(b, null, 2)], { type: "application/json" });
                      const url = URL.createObjectURL(blob);
                      const a = document.createElement("a");
                      a.href = url; a.download = b.r2Key.replace(/\.gz$/, "") + ".json"; a.click();
                      setTimeout(() => URL.revokeObjectURL(url), 1000);
                      toast?.push?.({ tone: "good", title: "Téléchargement", body: b.r2Key });
                    }}><Icon name="download" size={11}/></button>
                    <button className="btn" data-size="sm" onClick={restoreFile}><Icon name="refresh" size={11}/> Restaurer</button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};

/* ─── 48. Feature flags ──────────────────────────────────────────── */
const FeatureFlags = () => {
  const LS_FLAGS = "kcc:feature-flags";
  const DEFAULT_FLAGS = [
    { key: "JARVIS_AGENT_MODE",      desc: "Mode agent multi-étapes (beta)",         on: true,   rollout: 33, env: "prod" },
    { key: "MULTI_CURRENCY",          desc: "Soldes multi-devises consolidés",         on: true,   rollout: 100, env: "prod" },
    { key: "ASIN_SCANNER",            desc: "Scanner code-barre via caméra PWA",       on: true,   rollout: 100, env: "prod" },
    { key: "VOICE_NOTES",             desc: "Voice notes dans Messages",               on: false,  rollout: 0,   env: "staging" },
    { key: "AUTOPILOT_COPY",          desc: "JARVIS suggère des changements de copy",  on: false,  rollout: 0,   env: "dev" },
    { key: "QUICKBOOKS_EXPORT",       desc: "Export mensuel vers QuickBooks Online",   on: false,  rollout: 0,   env: "staging" },
    { key: "DAILY_BRIEFING_AUDIO",    desc: "Audio TTS du Daily Digest",               on: true,   rollout: 50,  env: "prod" },
    { key: "CANNIBALIZATION_DETECT",  desc: "Détection de cannibalisation produits",   on: true,   rollout: 100, env: "prod" },
  ];
  const loadFlags = () => { try { const s = localStorage.getItem(LS_FLAGS); return s ? JSON.parse(s) : DEFAULT_FLAGS; } catch { return DEFAULT_FLAGS; } };
  const [flags, _setFlags] = useState(loadFlags);
  const setFlags = (next) => {
    const v = typeof next === "function" ? next(flags) : next;
    _setFlags(v);
    try { localStorage.setItem(LS_FLAGS, JSON.stringify(v)); } catch {}
    // Expose globally for runtime feature gating
    window.__kcc_flags = Object.fromEntries(v.map(f => [f.key, f.on]));
    fetch("/api/sync", { method: "PUT", body: JSON.stringify({ col: "feature-flags", items: v }) }).catch(() => null);
  };
  useEffect(() => { window.__kcc_flags = Object.fromEntries(flags.map(f => [f.key, f.on])); }, []);
  return (
    <div className="page">
      <div className="page-head">
        <div>
          <div className="page-title">Feature flags</div>
          <div className="page-sub">Activation progressive · rollouts par % · KV-driven · changements live sans déploiement</div>
        </div>
      </div>
      <div className="card" style={{ padding: 0 }}>
        <table className="table">
          <thead><tr><th>Flag</th><th>Description</th><th>Environnement</th><th>Rollout</th><th>État</th></tr></thead>
          <tbody>
            {flags.map((f, i) => (
              <tr key={f.key}>
                <td><span className="mono" style={{ fontWeight: 600, color: "var(--accent)" }}>{f.key}</span></td>
                <td className="muted">{f.desc}</td>
                <td><Badge tone={f.env === "prod" ? "green" : f.env === "staging" ? "amber" : "muted"}>{f.env}</Badge></td>
                <td>
                  <div className="row" style={{ gap: 8 }}>
                    <div style={{ width: 100, height: 5, background: "var(--bg-3)", borderRadius: 999, overflow: "hidden" }}>
                      <div style={{ width: f.rollout + "%", height: "100%", background: "var(--accent)" }}/>
                    </div>
                    <span className="num" style={{ fontSize: 11 }}>{f.rollout}%</span>
                  </div>
                </td>
                <td>
                  <button onClick={() => setFlags(arr => arr.map((x, j) => j === i ? { ...x, on: !x.on } : x))} style={{ width: 36, height: 20, borderRadius: 999, background: f.on ? "var(--green)" : "var(--bg-4)", border: "none", position: "relative", cursor: "pointer" }}>
                    <div style={{ position: "absolute", top: 2, left: f.on ? 18 : 2, width: 16, height: 16, borderRadius: "50%", background: "white", transition: "left 200ms" }}/>
                  </button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};

/* ─── 49. Maintenance mode ───────────────────────────────────────── */
const MaintenanceMode = () => {
  const [on, setOn] = useState(false);
  const [readonly, setReadonly] = useState(true);
  const toast = useToastX();
  return (
    <div className="page" style={{ maxWidth: 900 }}>
      <div className="page-head">
        <div>
          <div className="page-title">Mode maintenance</div>
          <div className="page-sub">Bannière globale + lecture seule · à utiliser pendant les migrations critiques</div>
        </div>
      </div>
      <div className="card" style={{ padding: 24 }}>
        <div className="row" style={{ gap: 14, marginBottom: 22 }}>
          <div style={{ width: 48, height: 48, borderRadius: 12, background: on ? "var(--amber-soft)" : "var(--bg-3)", color: on ? "var(--amber)" : "var(--text-dim)", display: "grid", placeItems: "center" }}>
            <Icon name="wrench" size={20}/>
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 14, fontWeight: 600 }}>Mode maintenance global</div>
            <div style={{ fontSize: 11.5, color: "var(--text-dim)", marginTop: 2 }}>Affiche une bannière à tous les utilisateurs · bloque les actions d'écriture si lecture seule cochée</div>
          </div>
          <button onClick={() => { setOn(!on); toast({ message: on ? "Maintenance désactivée" : "Maintenance ACTIVÉE", tone: on ? "green" : "amber" }); }}
            style={{ width: 48, height: 26, borderRadius: 999, background: on ? "var(--amber)" : "var(--bg-4)", border: "none", position: "relative", cursor: "pointer" }}>
            <div style={{ position: "absolute", top: 3, left: on ? 24 : 3, width: 20, height: 20, borderRadius: "50%", background: "white", transition: "left 200ms" }}/>
          </button>
        </div>

        <div className="stack" style={{ gap: 14 }}>
          <div>
            <div style={{ fontSize: 12.5, fontWeight: 500, marginBottom: 6 }}>Message de la bannière</div>
            <textarea className="input" rows={2} defaultValue="Maintenance en cours · sync base de données · retour estimé à 16:00 ET." style={{ height: "auto", padding: 10, lineHeight: 1.5 }}/>
          </div>
          <div className="row" style={{ justifyContent: "space-between" }}>
            <div>
              <div style={{ fontSize: 12.5, fontWeight: 500 }}>Lecture seule globale</div>
              <div style={{ fontSize: 11, color: "var(--text-dim)", marginTop: 2 }}>Bloque tout POST/PATCH/DELETE pendant la maintenance</div>
            </div>
            <button onClick={() => setReadonly(!readonly)} style={{ width: 36, height: 20, borderRadius: 999, background: readonly ? "var(--accent)" : "var(--bg-4)", border: "none", position: "relative", cursor: "pointer" }}>
              <div style={{ position: "absolute", top: 2, left: readonly ? 18 : 2, width: 16, height: 16, borderRadius: "50%", background: "white" }}/>
            </button>
          </div>
        </div>

        {on && (
          <div style={{ marginTop: 20, padding: 14, background: "var(--amber-soft)", border: "1px solid var(--amber)", borderRadius: 10 }}>
            <div className="row" style={{ gap: 10 }}>
              <Icon name="bell" size={14} style={{ color: "var(--amber)" }}/>
              <div style={{ fontSize: 12.5, color: "var(--amber)", flex: 1 }}>
                <strong>Aperçu de la bannière :</strong> Maintenance en cours · sync base de données · retour estimé à 16:00 ET.
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

/* ─── 50. Activity heatmap ────────────────────────────────────────── */
const ActivityHeatmap = () => {
  // 7 days × 24 hours
  const grid = USERS.map((u) => ({
    user: u.id,
    name: u.name,
    data: Array.from({ length: 7 }, (_, d) => Array.from({ length: 24 }, (_, h) => {
      // peak hours 9-12 and 14-18, with lunch dip
      const workHours = (h >= 8 && h <= 12) || (h >= 13 && h <= 18);
      const base = workHours ? 0.6 + Math.random() * 0.4 : Math.random() * 0.15;
      const weekend = d >= 5 ? base * 0.3 : base;
      return weekend;
    })),
  }));
  const days = ["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"];
  return (
    <div className="page">
      <div className="page-head">
        <div>
          <div className="page-title">Activity heatmap équipe</div>
          <div className="page-sub">Qui fait quoi, quand · 7 derniers jours · clics, éditions, messages, requêtes JARVIS</div>
        </div>
        <div className="row">
          <select className="input" defaultValue="all" style={{ width: 160 }}>
            <option value="all">Toute activité</option>
            <option value="msg">Messages</option>
            <option value="edit">Éditions</option>
            <option value="jarvis">JARVIS</option>
          </select>
        </div>
      </div>
      <div className="card" style={{ padding: 18 }}>
        {grid.map((u) => (
          <div key={u.user} style={{ marginBottom: 18 }}>
            <div className="row" style={{ gap: 8, marginBottom: 8 }}>
              <Avatar user={u.user} size="sm"/>
              <span style={{ fontSize: 13, fontWeight: 600 }}>{u.name}</span>
              <span className="mono" style={{ fontSize: 10.5, color: "var(--text-faint)", marginLeft: 8 }}>
                {Math.round(u.data.flat().reduce((s, v) => s + v, 0) * 12)} interactions cette semaine
              </span>
            </div>
            <div>
              {u.data.map((day, d) => (
                <div key={d} style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 2 }}>
                  <span style={{ width: 28, fontSize: 10, color: "var(--text-faint)", textAlign: "right" }}>{days[d]}</span>
                  {day.map((v, h) => (
                    <div key={h} style={{
                      flex: 1, height: 10,
                      background: `oklch(${0.7 - v * 0.25} ${0.15 * v} 248 / ${0.1 + v * 0.85})`,
                      borderRadius: 2,
                    }} title={`${h}h · activité ${(v * 100).toFixed(0)}%`}/>
                  ))}
                </div>
              ))}
              <div style={{ display: "flex", gap: 6, marginTop: 4, paddingLeft: 34 }}>
                {Array.from({ length: 24 }, (_, h) => (
                  <span key={h} style={{ flex: 1, fontSize: 9, color: "var(--text-faint)", textAlign: "center" }}>{h % 4 === 0 ? h : ""}</span>
                ))}
              </div>
            </div>
          </div>
        ))}
        <div className="row" style={{ gap: 8, marginTop: 14, fontSize: 10.5, color: "var(--text-dim)", justifyContent: "flex-end" }}>
          <span>Moins actif</span>
          {[0.1, 0.3, 0.5, 0.7, 0.95].map((v) => <span key={v} style={{ width: 18, height: 10, background: `oklch(${0.7 - v * 0.25} ${0.15 * v} 248 / ${0.1 + v * 0.85})`, borderRadius: 2 }}/>)}
          <span>Très actif</span>
        </div>
      </div>
    </div>
  );
};

/* ─── 45. Focus mode toggle helper ───────────────────────────────── */
const FOCUS_CSS_ID = "kcc-focus-style";
const ensureFocusCss = () => {
  if (document.getElementById(FOCUS_CSS_ID)) return;
  const st = document.createElement("style");
  st.id = FOCUS_CSS_ID;
  st.textContent = "body.kcc-focus .sidebar,body.kcc-focus .topbar{display:none!important}body.kcc-focus .main,body.kcc-focus main{margin-left:0!important}";
  document.head.appendChild(st);
};
const toggleFocusMode = () => {
  ensureFocusCss();
  return document.body.classList.toggle("kcc-focus");
};
const FocusModeHelp = () => {
  const toast = useToastX();
  const [on, setOn] = useState(() => document.body.classList.contains("kcc-focus"));
  useEffect(() => {
    ensureFocusCss();
    const onKey = (e) => {
      if (e.key && e.key.toLowerCase() === "f" && !e.metaKey && !e.ctrlKey && !e.altKey) {
        const tag = (e.target?.tagName || "").toLowerCase();
        if (tag === "input" || tag === "textarea" || e.target?.isContentEditable) return;
        e.preventDefault();
        setOn(toggleFocusMode());
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);
  const activate = () => {
    const next = toggleFocusMode();
    setOn(next);
    toast?.push?.({ tone: next ? "good" : "warn", title: next ? "Mode focus activé" : "Mode focus désactivé", body: next ? "Appuyez sur F ou le bouton pour quitter." : "" });
  };
  return (
    <div className="page" style={{ maxWidth: 700 }}>
      <div className="page-head">
        <div>
          <div className="page-title">Mode focus</div>
          <div className="page-sub">Masque la sidebar et le chrome · ne garde que la page courante · raccourci F</div>
        </div>
      </div>
      <div className="card" style={{ padding: 24, textAlign: "center" }}>
        <div style={{ width: 56, height: 56, borderRadius: 14, background: "var(--accent-soft)", color: "var(--accent)", display: "grid", placeItems: "center", margin: "0 auto 14px" }}>
          <Icon name="target" size={26}/>
        </div>
        <div style={{ fontSize: 16, fontWeight: 600 }}>Appuyez sur <span className="kbd" style={{ fontSize: 13 }}>F</span> pour {on ? "quitter" : "activer"} le mode focus</div>
        <div style={{ fontSize: 12.5, color: "var(--text-dim)", marginTop: 8 }}>Masque la sidebar, la topbar et tous les overlays. Idéal pour les sessions deep-work ou les présentations.</div>
        <button className="btn" data-variant="primary" style={{ marginTop: 18 }} onClick={activate}><Icon name="target" size={13}/> {on ? "Désactiver" : "Activer maintenant"}</button>
      </div>
    </div>
  );
};

Object.assign(window, { AsinScanner, MobileSetup, Onboarding, Backups, FeatureFlags, MaintenanceMode, ActivityHeatmap, FocusModeHelp });
