// analyse-2026.jsx — Section « Analyse » de RAYCAST
//
// Résumé d'analyste SYNTHÉTISÉ : acquisition → comportement → conversion → verdict.
// Données comportementales = Microsoft Clarity (projet wvm6u5crpy) EN DIRECT via le
// relais worker `/clarity/insights` (KV-cache 3h). Repli gracieux sur un instantané
// curé si l'API échoue / pas de config. L'entonnoir détaillé (paliers de défilement)
// + le verdict restent curés (l'API Data Export ne donne pas les paliers ni les events
// de formulaire — ça vient de l'analyse profonde, rafraîchie sur demande).
//
// 100 % en tokens var(--*) → compatible mode clair ET sombre. Exposé : window.Analyse2026

(function () {
  const { useState, useEffect } = React;

  // ── Instantané curé (repli + entonnoir/verdict). Source : Clarity + Meta, 2026-06-07. ──
  const SNAP = {
    date: "2026-06-07", periode: "3 derniers jours",
    adClics: 191, sessions: 284, users: 273,
    scrollMoyen: 27, tempsActifSec: 45, quebecPct: 90,
    rageClicks: 0, deadClicks: 4, quickback: 3,
    devices: [
      { label: "Tablette", n: 127, scroll: 13, tone: "bad" },
      { label: "Mobile", n: 117, scroll: 33, tone: "warn" },
      { label: "PC", n: 41, scroll: 37, tone: "good" },
    ],
    funnel: [
      { label: "Sessions sur la LP", n: 284, pct: 100 },
      { label: "Dépassent 25 % de la page", n: 91, pct: 32 },
      { label: "Atteignent le formulaire (75 %+)", n: 54, pct: 19 },
      { label: "Interagissent avec le formulaire", n: 4, pct: 1.4 },
      { label: "Soumettent", n: 1, pct: 0.35 },
    ],
    causes: [
      { rang: 1, tone: "bad", titre: "La fuite est EN HAUT de page",
        txt: "68 % ne dépassent pas le 1ᵉʳ quart (scroll moyen 27 %, 45 s). Aucun bug (0 rage click) — le hero n'accroche pas assez pour donner envie de descendre." },
      { rang: 2, tone: "warn", titre: "Le formulaire est trop bas",
        txt: "Seulement 19 % l'atteignent, et il n'y a aucun CTA fort visible en haut pour capter les 68 % qui ne défilent pas. (Correctif CTA collant déployé.)" },
      { rang: 3, tone: "warn", titre: "Trafic « tablette » à faible intention",
        txt: "127 sessions tablette à 13 % de défilement (vs mobile 33 %, PC 37 %) = clics peu intentionnels, typiques des placements Advantage+ (Audience Network / Reels)." },
    ],
    actions: [
      "✅ CTA collant « Évaluation gratuite » sur tous les appareils + hero refait (fait).",
      "✅ A/B en cours : « Gardez le courant » (P1) vs « Quand Hydro-Québec lâche » (P2).",
      "Resserrer les placements Meta (exclure Audience Network / Reels) → moins de clics « tablette ».",
      "Exclure le trafic interne (?raycom_internal=1) pour des chiffres propres.",
    ],
  };

  const T = {
    ink: "var(--raycom-ink, #0b1b2b)", muted: "var(--raycom-ink-muted, #475569)", dim: "var(--raycom-ink-dim, #94a3b8)",
    surface: "var(--raycom-surface, #fff)", surface2: "var(--raycom-surface-2, #f1f5f9)", border: "var(--raycom-border, #e2e8f0)",
    accent: "var(--raycom-accent, #1a6fc4)", good: "var(--raycom-energy, #059669)", bad: "var(--margin-red, #dc2626)", warn: "var(--margin-yellow, #d97706)",
  };
  const toneColor = (t) => (t === "bad" ? T.bad : t === "good" ? T.good : t === "warn" ? T.warn : T.accent);

  // ── Lecture config worker (sous-domaine + token), comme la section Analytics ──
  function readCfg() { try { return JSON.parse(localStorage.getItem("raycast_analytics_cfg") || "{}"); } catch (e) { return {}; } }

  // ── Mappe la réponse Clarity (16 métriques) → objet live ──
  function mapClarity(arr) {
    const by = {};
    (arr || []).forEach((m) => { if (m && m.metricName) by[m.metricName] = m.information; });
    const f = (k) => (Array.isArray(by[k]) && by[k][0]) || {};
    const num = (v) => { const n = Number(v); return Number.isFinite(n) ? n : null; };
    let scroll = num(f("ScrollDepth").averageScrollDepth);
    if (scroll != null && scroll <= 1) scroll = scroll * 100;
    const list = (k, nameKey, valKey) => (Array.isArray(by[k]) ? by[k] : [])
      .map((r) => ({ label: r[nameKey], n: num(r[valKey]) })).filter((x) => x.label != null).slice(0, 6);
    return {
      sessions: num(f("Traffic").totalSessionCount),
      users: num(f("Traffic").distinctUserCount),
      bots: num(f("Traffic").totalBotSessionCount),
      scroll: scroll != null ? Math.round(scroll) : null,
      rage: num(f("RageClickCount").sessionsCount),
      dead: num(f("DeadClickCount").sessionsCount),
      quickback: num(f("QuickbackClick").sessionsCount),
      devices: list("Device", "name", "sessionsCount"),
      pages: (Array.isArray(by["PopularPages"]) ? by["PopularPages"] : []).map((p) => ({ label: p.url, n: num(p.visitsCount) })).slice(0, 6),
      country: list("Country", "name", "sessionsCount"),
    };
  }

  const Card = ({ children, style }) => (
    <div style={{ background: T.surface, border: `1px solid ${T.border}`, borderRadius: 16, padding: 20, marginBottom: 18, ...style }}>{children}</div>
  );
  const SectionTitle = ({ children, hint }) => (
    <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", marginBottom: 14, gap: 12, flexWrap: "wrap" }}>
      <h3 style={{ margin: 0, fontSize: 15, fontWeight: 700, color: T.ink, letterSpacing: ".2px" }}>{children}</h3>
      {hint && <span style={{ fontSize: 12, color: T.dim }}>{hint}</span>}
    </div>
  );
  const Stat = ({ label, value, sub, tone }) => (
    <div style={{ flex: "1 1 120px", minWidth: 120, background: T.surface2, border: `1px solid ${T.border}`, borderRadius: 12, padding: "14px 16px" }}>
      <div style={{ fontSize: 22, fontWeight: 800, color: tone ? toneColor(tone) : T.ink, lineHeight: 1.1 }}>{value}</div>
      <div style={{ fontSize: 12, color: T.muted, marginTop: 4 }}>{label}</div>
      {sub && <div style={{ fontSize: 11, color: T.dim, marginTop: 2 }}>{sub}</div>}
    </div>
  );
  const Funnel = ({ steps }) => (
    <div>
      {steps.map((s, i) => {
        const prev = i > 0 ? steps[i - 1].pct : null;
        const drop = prev != null && prev > 0 ? Math.round((1 - s.pct / prev) * 100) : null;
        const tone = i === 0 ? "accent" : s.pct >= 19 ? "warn" : "bad";
        return (
          <div key={i} style={{ marginBottom: 10 }}>
            <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12.5, color: T.muted, marginBottom: 4 }}>
              <span>{s.label}</span><span style={{ color: T.ink, fontWeight: 600 }}>{s.n.toLocaleString("fr-CA")} · {s.pct}%</span>
            </div>
            <div style={{ height: 12, background: T.surface2, borderRadius: 6, overflow: "hidden" }}>
              <div style={{ height: "100%", width: Math.max(s.pct, 1.5) + "%", background: toneColor(tone), borderRadius: 6 }} />
            </div>
            {drop != null && drop > 0 && <div style={{ fontSize: 11, color: drop >= 50 ? T.bad : T.dim, marginTop: 3 }}>▼ −{drop}% à cette étape</div>}
          </div>
        );
      })}
    </div>
  );
  const BarRow = ({ label, n, max, tone, suffix }) => (
    <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 9 }}>
      <div style={{ width: 130, fontSize: 12.5, color: T.ink, fontWeight: 600, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }} title={label}>{label}</div>
      <div style={{ flex: 1, height: 10, background: T.surface2, borderRadius: 5, overflow: "hidden" }}>
        <div style={{ height: "100%", width: (max ? Math.round((n / max) * 100) : 0) + "%", background: toneColor(tone), borderRadius: 5 }} />
      </div>
      <div style={{ width: 92, textAlign: "right", fontSize: 12, color: T.muted }}>{n != null ? n.toLocaleString("fr-CA") : "—"}{suffix || ""}</div>
    </div>
  );

  function Analyse2026() {
    const [live, setLive] = useState(null);
    const [meta, setMeta] = useState({ loading: true });

    useEffect(() => {
      let cancel = false;
      (async () => {
        let c = readCfg();
        if ((!c.token || !c.subdomain) && window.RaycastDB && window.RaycastDB.getAppSetting) {
          try { const a = await window.RaycastDB.getAppSetting("analytics"); if (a) c = Object.assign({}, a, c); } catch (e) {}
        }
        if (!c.token || !c.subdomain) { if (!cancel) setMeta({ loading: false, noCfg: true }); return; }
        try {
          const u = `https://raycom-ghl-worker.${c.subdomain}.workers.dev/clarity/insights?token=${encodeURIComponent(c.token)}`;
          const r = await fetch(u);
          const j = await r.json();
          if (cancel) return;
          if (j && j.ok && Array.isArray(j.data)) { setLive(mapClarity(j.data)); setMeta({ loading: false, at: j.fetchedAt }); }
          else setMeta({ loading: false, err: (j && j.error) || "format inattendu" });
        } catch (e) { if (!cancel) setMeta({ loading: false, err: String(e) }); }
      })();
      return () => { cancel = true; };
    }, []);

    // Fusion live > instantané
    const sessions = (live && live.sessions != null) ? live.sessions : SNAP.sessions;
    const users = (live && live.users != null) ? live.users : SNAP.users;
    const scroll = (live && live.scroll != null) ? live.scroll : SNAP.scrollMoyen;
    const rage = (live && live.rage != null) ? live.rage : SNAP.rageClicks;
    const dead = (live && live.dead != null) ? live.dead : SNAP.deadClicks;
    const devices = (live && live.devices && live.devices.length) ? live.devices : SNAP.devices;
    const pages = (live && live.pages && live.pages.length) ? live.pages : null;
    const maxDev = Math.max.apply(null, devices.map((d) => d.n || 0).concat([1]));
    const maxPage = pages ? Math.max.apply(null, pages.map((p) => p.n || 0).concat([1])) : 1;

    const liveBadge = meta.loading
      ? { txt: "chargement…", col: T.dim }
      : (live ? { txt: "● live", col: T.good } : { txt: "instantané", col: T.warn });

    return (
      <div style={{ padding: "26px 30px", maxWidth: 1080, margin: "0 auto", color: T.ink }}>
        <div style={{ marginBottom: 20 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
            <h2 style={{ margin: "0 0 4px", fontSize: 22, fontWeight: 800, color: T.ink }}>🔍 Analyse — Diagnostic de conversion</h2>
            <span style={{ fontSize: 12, fontWeight: 700, color: liveBadge.col, border: `1px solid ${T.border}`, borderRadius: 999, padding: "2px 10px" }}>{liveBadge.txt}</span>
          </div>
          <p style={{ margin: 0, fontSize: 13.5, color: T.muted }}>
            Landing page Powerwall · {SNAP.periode} · pourquoi <strong>1 soumission</strong> sur <strong>{Number(sessions).toLocaleString("fr-CA")} sessions</strong>.
          </p>
          <p style={{ margin: "4px 0 0", fontSize: 12, color: T.dim }}>
            📊 Données comportementales : <strong style={{ color: T.muted }}>Microsoft Clarity</strong> (replays + cartes de chaleur) · rafraîchies automatiquement aux 24 h.
          </p>
        </div>

        <div style={{ display: "flex", gap: 12, flexWrap: "wrap", marginBottom: 18 }}>
          <Stat label="Sessions" value={Number(sessions).toLocaleString("fr-CA")} sub={`${Number(users).toLocaleString("fr-CA")} visiteurs`} />
          <Stat label="Scroll moyen" value={scroll + "%"} tone={scroll < 40 ? "bad" : "good"} sub="profondeur de page" />
          <Stat label="Rage clicks" value={rage} tone={rage > 0 ? "warn" : "good"} sub={`${dead} dead clicks`} />
          <Stat label="Québec" value={SNAP.quebecPct + "%"} tone="good" sub="ciblage géo ✓" />
        </div>

        <Card>
          <SectionTitle hint="curé — analyse profonde (paliers + events formulaire)">Entonnoir de conversion</SectionTitle>
          <Funnel steps={SNAP.funnel} />
        </Card>

        <Card>
          <SectionTitle hint={live ? "● live" : "instantané"}>Par appareil</SectionTitle>
          {devices.map((d, i) => <BarRow key={i} label={d.label} n={d.n} max={maxDev} tone={d.tone || (i === 0 ? "warn" : "accent")} />)}
          <p style={{ fontSize: 12, color: T.dim, margin: "8px 0 0" }}>La tablette domine le trafic mais défile le moins → segment à faible intention.</p>
        </Card>

        {pages && (
          <Card>
            <SectionTitle hint="● live">Pages les plus vues</SectionTitle>
            {pages.map((p, i) => <BarRow key={i} label={p.label} n={p.n} max={maxPage} tone="accent" suffix=" vues" />)}
          </Card>
        )}

        <Card style={{ borderLeft: `3px solid ${T.bad}` }}>
          <SectionTitle>Verdict — 3 causes (par impact)</SectionTitle>
          {SNAP.causes.map((c) => (
            <div key={c.rang} style={{ display: "flex", gap: 12, marginBottom: 14 }}>
              <div style={{ flexShrink: 0, width: 26, height: 26, borderRadius: 8, background: toneColor(c.tone), color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 800, fontSize: 13 }}>{c.rang}</div>
              <div>
                <div style={{ fontSize: 14, fontWeight: 700, color: T.ink }}>{c.titre}</div>
                <div style={{ fontSize: 13, color: T.muted, marginTop: 2, lineHeight: 1.5 }}>{c.txt}</div>
              </div>
            </div>
          ))}
        </Card>

        <Card style={{ borderLeft: `3px solid ${T.good}` }}>
          <SectionTitle>Actions</SectionTitle>
          <ol style={{ margin: 0, paddingLeft: 20 }}>
            {SNAP.actions.map((a, i) => <li key={i} style={{ fontSize: 13.5, color: T.ink, marginBottom: 8, lineHeight: 1.5 }}>{a}</li>)}
          </ol>
        </Card>

        <p style={{ fontSize: 11.5, color: T.dim, textAlign: "center", marginTop: 16 }}>
          {live
            ? `Source : Microsoft Clarity (projet wvm6u5crpy) · rafraîchi aux 24 h · dernière donnée ${meta.at ? new Date(meta.at).toLocaleString("fr-CA") : ""}.`
            : meta.noCfg
              ? "Config analytics absente → instantané du 2026-06-07. (Ouvre l'onglet Analytics une fois pour charger le token.)"
              : "Données live indisponibles → instantané du 2026-06-07. Entonnoir + verdict = analyse profonde, « refais l'analyse de la LP » pour rafraîchir."}
        </p>
      </div>
    );
  }

  window.Analyse2026 = Analyse2026;
})();
