// ============================================================
// Screen components — Landing, Scanning, Results, ShareCard
// ============================================================
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ─── i18n helper ─────────────────────────────────────────────
const T = (ar, en, lang) => (lang === "en" ? en : ar);

const PLATFORM_LABEL_AR = { salla: "سلة", zid: "زد", shopify: "شوبيفاي", other: "مخصص" };
const PLATFORM_LABEL_EN = { salla: "Salla", zid: "Zid", shopify: "Shopify", other: "Custom" };
function platformLabel(p, lang) {
  const key = String(p || "other").toLowerCase();
  return (lang === "en" ? PLATFORM_LABEL_EN : PLATFORM_LABEL_AR)[key] || p || "";
}

// ─── Live scan API client ────────────────────────────────────
// Adapts a /benchmark/scan response into the STORES[] shape the Results and
// ShareCard components already consume, so they don't care whether the data
// is a live scan or a demo store.
function liveToStore(live) {
  if (!live) return null;
  const host = live.normalizedUrl
    ? (() => { try { return new URL(live.normalizedUrl).hostname; } catch { return live.inputUrl; } })()
    : live.inputUrl;
  const displayName = live.displayName || host;
  const initials = (displayName || host || "?").trim().charAt(0) || "?";
  return {
    id: live.scanId,
    name: displayName,
    nameEn: displayName,
    url: host,
    handle: null,
    platform: (live.signals && live.signals.platform) || "—",
    category: "—",
    categoryEn: "—",
    followers: (live.signals && live.signals.instagramFollowers) || 0,
    initials,
    logoUrl: (live.signals && live.signals.logoUrl) || null,
    color: "linear-gradient(135deg, #D6F2ED, #417C9C)",
    pillars: live.pillars,
    total: live.total,
    tier: live.tier,
    percentile: live.percentile,
    verdict: live.verdict,
    insight: live.insight,
  };
}

async function apiStartScan({ input, lang, enrichment }) {
  const res = await fetch(`${API_BASE}/api/benchmark/scan`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ input, lang, enrichment }),
  });
  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(err.error || `HTTP ${res.status}`);
  }
  return res.json();
}

async function apiGetScan(scanId) {
  const res = await fetch(`${API_BASE}/api/benchmark/scan/${scanId}`);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

async function apiCaptureLead({ email, scanId, lang }) {
  const res = await fetch(`${API_BASE}/api/benchmark/leads`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ email, scanId, lang }),
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

// Download a DOM node as PNG via html-to-image. The node is expected to be the
// "natural size" element (e.g. the 1200x630 card), which in our ShareModal is
// CSS-scaled down to fit the preview frame. We temporarily clear the transform
// so html-to-image captures the real resolution, then restore it.
async function downloadNodeAsPng(node, filename) {
  if (!node) {
    alert("Share card not ready yet — try again in a moment.");
    return;
  }
  if (!window.htmlToImage) {
    alert("Image exporter didn't load (check your network blocker). Try a hard refresh.");
    return;
  }
  const prevTransform = node.style.transform;
  const prevOrigin = node.style.transformOrigin;
  node.style.transform = "none";
  node.style.transformOrigin = "top left";
  try {
    const dataUrl = await window.htmlToImage.toPng(node, {
      pixelRatio: 2,
      cacheBust: true,
      skipFonts: false,
    });
    const a = document.createElement("a");
    a.href = dataUrl;
    a.download = filename;
    a.click();
  } catch (err) {
    console.error("downloadNodeAsPng failed:", err);
    alert("Couldn't generate PNG: " + (err && err.message ? err.message : String(err)));
  } finally {
    node.style.transform = prevTransform;
    node.style.transformOrigin = prevOrigin;
  }
}

// Compose a Saudi-Arabic / English share message for WhatsApp / clipboard.
function shareText(store, lang) {
  const tierAr = { leader: "رائد", solid: "قوي", needs: "يحتاج تحسين", risk: "في خطر" };
  const tierEn = { leader: "Leader", solid: "Solid", needs: "Needs work", risk: "At risk" };
  if (lang === "en") {
    return `My store scored ${store.total}/100 on the Karam CX Benchmark — ${tierEn[store.tier] || ""}. Test yours: https://karamai.co/check`;
  }
  return `متجري حصل على ${store.total}/100 في مقياس كرم لتجربة العميل — ${tierAr[store.tier] || ""}. جرب متجرك: https://karamai.co/check`;
}

async function copyToClipboard(text) {
  try {
    if (navigator.clipboard && navigator.clipboard.writeText) {
      await navigator.clipboard.writeText(text);
      return true;
    }
  } catch { /* fall through */ }
  // Fallback for non-secure contexts
  const ta = document.createElement("textarea");
  ta.value = text;
  ta.style.position = "fixed";
  ta.style.opacity = "0";
  document.body.appendChild(ta);
  ta.select();
  try { document.execCommand("copy"); document.body.removeChild(ta); return true; }
  catch { document.body.removeChild(ta); return false; }
}

function openWhatsAppShare(store, lang) {
  const msg = shareText(store, lang);
  window.open(`https://wa.me/?text=${encodeURIComponent(msg)}`, "_blank", "noopener");
}

// ─── Icon wrapper ────────────────────────────────────────────
// Renders a Lucide icon as inline SVG under a React-owned <span>. We deliberately
// do NOT call window.lucide.createIcons() — that mutates React's DOM tree
// (replaces <i data-lucide> with <svg>) and causes NotFoundError: removeChild
// the moment React re-renders during a live scan.
function lucideSvgHtml(name, size) {
  if (typeof window === "undefined" || !window.lucide) return "";
  const pascal = String(name)
    .split("-")
    .filter(Boolean)
    .map((p) => p[0].toUpperCase() + p.slice(1))
    .join("");
  const iconsMap = window.lucide.icons || {};
  const def = iconsMap[pascal] || iconsMap[name];
  if (!def || !window.lucide.createElement) return "";
  try {
    const el = window.lucide.createElement(def);
    el.setAttribute("width", String(size));
    el.setAttribute("height", String(size));
    el.setAttribute("stroke-width", "2");
    return el.outerHTML;
  } catch {
    return "";
  }
}

function Icon({ name, size = 16, style, className }) {
  const html = useMemo(() => lucideSvgHtml(name, size), [name, size]);
  return (
    <span
      className={className}
      style={{
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center",
        width: size,
        height: size,
        lineHeight: 0,
        ...style,
      }}
      dangerouslySetInnerHTML={{ __html: html }}
    />
  );
}

// No-op — kept so existing call sites don't need edits.
// (The old implementation called window.lucide.createIcons() globally, which
// mutated React-owned DOM and crashed reconciliation on re-render.)
function useLucide() {}

// ─── Top bar ─────────────────────────────────────────────────
function AppTopbar({ lang, onLang, onHome, screen }) {
  useLucide([lang, screen]);
  return (
    <div className="app-topbar">
      <button className="app-brand" onClick={onHome} aria-label="home">
        <img src="assets/karam-logo.png" alt="Karam" />
        <span className="app-brand-sub">
          {T("مقياس تجربة العميل", "CX Benchmark", lang)}
        </span>
      </button>
      <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
        <div className="lang-toggle">
          <button className={lang === "ar" ? "is-active" : ""} onClick={() => onLang("ar")}>عربي</button>
          <button className={lang === "en" ? "is-active" : ""} onClick={() => onLang("en")}>EN</button>
        </div>
      </div>
    </div>
  );
}

// ─── Landing ─────────────────────────────────────────────────
function Landing({ lang, onScan }) {
  const [input, setInput] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState(null);
  useLucide([lang]);

  const placeholders = lang === "ar"
    ? ["mystore.salla.sa", "mybrand.com", "mystore.zid.store", "mystore.com.sa"]
    : ["mystore.salla.sa", "mybrand.com", "mystore.zid.store", "mystore.com.sa"];
  const [phIdx, setPhIdx] = useState(0);
  useEffect(() => {
    const t = setInterval(() => setPhIdx(i => (i + 1) % placeholders.length), 2200);
    return () => clearInterval(t);
  }, []);

  const errorText = (code) => {
    if (!code) return null;
    if (code === "input_handle-only") {
      return T(
        "أدخل رابط متجرك (مثل store.salla.sa) بدلاً من حساب التواصل الاجتماعي.",
        "Enter your store URL (e.g. store.salla.sa) instead of a social handle.",
        lang,
      );
    }
    if (code === "input_empty") return T("الحقل فارغ.", "Empty input.", lang);
    if (code === "input_invalid") {
      return T(
        "الرابط غير صالح. تأكد من كتابة المجال الكامل.",
        "Invalid URL. Make sure to include the full domain.",
        lang,
      );
    }
    return T("تعذر بدء الفحص. حاول مرة أخرى.", "Couldn't start the scan. Please try again.", lang);
  };

  const submit = async (e) => {
    e.preventDefault();
    const val = input.trim();
    if (!val) {
      setError("input_empty");
      return;
    }
    setError(null);
    setSubmitting(true);
    try {
      const { scanId } = await apiStartScan({ input: val, lang });
      onScan(val, scanId);
    } catch (err) {
      setError((err && err.message) || "unknown");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="landing">
      <div className="landing-inner">
        <div className="eyebrow-pill">
          <span className="dot" />
          {T("جديد · يعمل بالذكاء الاصطناعي", "New · powered by AI", lang)}
        </div>
        <h1>
          {lang === "ar" ? (
            <>كيف <em>تجربة العميل</em> في متجرك؟<br />احصل على التقييم خلال دقيقتين.</>
          ) : (
            <>How <em>strong</em> is your store's CX?<br />Get the score in two minutes.</>
          )}
        </h1>
        <p className="sub">
          {T(
            "افحص مجاناً. قارن نفسك بالسوق السعودي. احصل على ٣ توصيات ذكية.",
            "Free scan. Benchmarked against the Saudi market. Three AI-tailored fixes.",
            lang
          )}
        </p>
        <form className="scan-form" onSubmit={submit}>
          <div className="scan-form-icon"><Icon name="search" size={18} /></div>
          <input
            type="text"
            value={input}
            onChange={(e) => { setInput(e.target.value); if (error) setError(null); }}
            placeholder={placeholders[phIdx]}
            dir="ltr"
            style={{ textAlign: lang === "ar" ? "end" : "start" }}
            disabled={submitting}
          />
          <button type="submit" className="scan-btn" disabled={submitting}>
            {submitting
              ? T("بدء الفحص...", "Starting...", lang)
              : T("افحص متجري الآن", "Scan my store", lang)}
            {!submitting && <Icon name={lang === "ar" ? "arrow-left" : "arrow-right"} size={16} />}
          </button>
        </form>
        {error && (
          <div className="privacy-note" style={{ color: "var(--karam-danger)", marginTop: 10 }}>
            <Icon name="alert-circle" size={13} />
            {errorText(error)}
          </div>
        )}
        <div className="privacy-note">
          <Icon name="lock" size={13} />
          {T(
            "بدون تسجيل · بدون ربط حساب · فحص للبيانات العامة فقط",
            "No signup · no account link · public data only",
            lang
          )}
          <a
            href="privacy.html"
            target="_blank"
            style={{
              marginInlineStart: 8,
              color: "var(--karam-muted-ink)",
              textDecoration: "underline",
              textUnderlineOffset: 3,
              fontSize: 12,
            }}
          >
            {T("الخصوصية", "Privacy", lang)}
          </a>
        </div>

        <div className="social-proof">
          <div className="social-proof-label">
            {T("موثوق من متاجر سعودية", "Trusted by Saudi merchants", lang)}
          </div>
          <div className="proof-row">
            <div className="proof-avatar-stack">
              {["س", "ن", "د", "م", "ع"].map((c, i) => (
                <div key={i} className="proof-avatar" style={{
                  background: ["linear-gradient(135deg,#F7D1DE,#F5A8C2)",
                    "linear-gradient(135deg,#D6F2ED,#8FC2B6)",
                    "linear-gradient(135deg,#FFE1B3,#E8A768)",
                    "linear-gradient(135deg,#164863,#417C9C)",
                    "linear-gradient(135deg,#E8D9C4,#B8967A)"][i]
                }}>
                  {lang === "ar" ? c : ["S","N","D","M","A"][i]}
                </div>
              ))}
            </div>
            <div className="proof-text">
              <b>+٣١٧ متجر سعودي</b> {T("فحصوا هذا الأسبوع", "scanned this week", lang)}
            </div>
          </div>
        </div>

        <div className="steps-strip">
          {[
            { num: "١", ar: "ألصق رابط متجرك", en: "Paste your store URL",
              descAr: "سلة، زد، Shopify، أو حساب إنستقرام", descEn: "Salla, Zid, Shopify, or Instagram" },
            { num: "٢", ar: "نفحص ٣٠+ إشارة عامة", en: "We scan 30+ public signals",
              descAr: "من متجرك، معروف، Google PageSpeed، وسائل التواصل", descEn: "Your storefront, Maroof, PageSpeed, socials" },
            { num: "٣", ar: "احصل على تقييمك + ٣ توصيات", en: "Get your score + 3 fixes",
              descAr: "شارك البطاقة في واتساب بضغطة", descEn: "Share the card to WhatsApp in one tap" },
          ].map((s, i) => (
            <div key={i} className="step-card">
              <div className="step-num">{lang === "ar" ? s.num : (i + 1)}</div>
              <div className="step-title">{T(s.ar, s.en, lang)}</div>
              <div className="step-desc">{T(s.descAr, s.descEn, lang)}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ─── Scanning screen ─────────────────────────────────────────
// Two modes:
//   - live (scanId set): polls GET /api/benchmark/scan/:id for real probe state
//   - demo (no scanId):  runs the original timer-based animation. Kept so the
//                        tweaks panel's "Jump to scanning" button still works.
function ScanningScreen({ lang, input, storeId, scanId, onDone }) {
  const [probeIdx, setProbeIdx] = useState(0);
  const [probeStates, setProbeStates] = useState(PROBES.map(() => "pending"));
  const [showEnrich, setShowEnrich] = useState(false);
  const enrichDismissedRef = useRef(false);
  const [answers, setAnswers] = useState({});
  const dismissEnrich = useCallback(() => {
    enrichDismissedRef.current = true;
    setShowEnrich(false);
  }, []);
  useLucide([probeIdx, showEnrich, answers]);

  const totalMs = useMemo(() => PROBES.reduce((a, p) => a + p.ms, 0), []);
  const [elapsed, setElapsed] = useState(0);

  // Live polling mode
  useEffect(() => {
    if (!scanId) return;
    let cancelled = false;
    let timer = null;
    const tick = async () => {
      if (cancelled) return;
      try {
        const data = await apiGetScan(scanId);
        if (cancelled) return;
        // Map server probe states (pending|running|done|failed) onto UI states.
        const mapState = (s) => s === "running" ? "active" : s === "failed" ? "fail" : s;
        const serverStates = PROBES.map((p) => {
          const probe = (data.probes || []).find((x) => x.id === p.id);
          return probe ? mapState(probe.state) : "pending";
        });
        setProbeStates(serverStates);
        const activeIdx = serverStates.findIndex((s) => s === "active");
        if (activeIdx >= 0) setProbeIdx(activeIdx);
        // Reveal enrichment once we're mid-scan.
        if (!enrichDismissedRef.current && serverStates.filter((s) => s === "done").length >= 3) setShowEnrich(true);
        // Map progress to the progress bar.
        const done = serverStates.filter((s) => s === "done").length;
        setElapsed((done / PROBES.length) * totalMs);

        if (data.status === "completed") {
          // Small settling delay so the final probe flash is visible.
          setTimeout(() => { if (!cancelled) onDone(data); }, 300);
          return;
        }
        if (data.status === "failed") {
          setTimeout(() => { if (!cancelled) onDone(data); }, 300);
          return;
        }
        timer = setTimeout(tick, 600);
      } catch (_err) {
        timer = setTimeout(tick, 1500);
      }
    };
    tick();
    return () => { cancelled = true; if (timer) clearTimeout(timer); };
  }, [scanId]);

  // Demo mode animation
  useEffect(() => {
    if (scanId) return;
    let mounted = true;
    let accum = 0;
    const run = async () => {
      for (let i = 0; i < PROBES.length; i++) {
        if (!mounted) return;
        setProbeIdx(i);
        setProbeStates(s => { const n = [...s]; n[i] = "active"; return n; });
        if (i === 4 && !enrichDismissedRef.current) setShowEnrich(true);
        const ms = PROBES[i].ms;
        const steps = 10;
        for (let k = 0; k < steps; k++) {
          if (!mounted) return;
          await new Promise(r => setTimeout(r, ms / steps));
          setElapsed(accum + (ms * (k + 1) / steps));
        }
        accum += ms;
        setProbeStates(s => { const n = [...s]; n[i] = "done"; return n; });
      }
      if (mounted) setTimeout(() => onDone(null), 500);
    };
    run();
    return () => { mounted = false; };
  }, [scanId]);

  const pct = Math.min(100, (elapsed / totalMs) * 100);

  return (
    <div className="scan-screen">
      <div className="scan-scope">
        <div className="scan-scope-icon">
          {scanId
            ? (input || "?").replace(/^https?:\/\//, "").replace(/^www\./, "").charAt(0).toUpperCase() || "?"
            : (STORES[storeId]?.initials || "?")}
        </div>
        <div className="scan-scope-text">
          {T("نفحص", "Scanning", lang)} <b>{input}</b>
        </div>
      </div>
      <h2 className="scan-title">
        {(() => {
          // Dynamic title: reflect the currently-active probe so the page doesn't
          // feel idle during long PSI/Apify waits. Falls back to the generic line
          // before any probe starts and after everything completes.
          const activeIdx = probeStates.findIndex((s) => s === "active");
          if (activeIdx >= 0) return T(PROBES[activeIdx].ar, PROBES[activeIdx].en, lang);
          if (probeStates.every((s) => s === "done" || s === "fail")) {
            return T("جار جمع النتائج...", "Compiling results...", lang);
          }
          return T("جار فحص متجرك...", "Scanning your store...", lang);
        })()}
      </h2>
      <div className="scan-sub">
        {T("نجمع ٣٠+ إشارة ونقارنها بمتاجر سعودية مماثلة", "Gathering 30+ signals and comparing with Saudi peers", lang)}
      </div>

      <div className="scan-progress-bar">
        <div className="scan-progress-fill" style={{ width: `${pct}%` }} />
      </div>

      <div className="probe-list">
        {PROBES.map((p, i) => (
          <div key={p.id} className={`probe-item ${probeStates[i] === "active" ? "is-active" : probeStates[i] === "done" ? "is-done" : probeStates[i] === "fail" ? "is-fail" : ""}`}>
            <div className="probe-icon">
              {probeStates[i] === "done" ? <Icon name="check" size={16} /> : <Icon name={p.icon} size={16} />}
            </div>
            <div className="probe-label">
              {T(p.ar, p.en, lang)}
              <span className="sub">{T(p.subAr, p.subEn, lang)}</span>
            </div>
            <div className="probe-status">
              {probeStates[i] === "done" && (<><Icon name="check" size={13} /> {T("تم", "Done", lang)}</>)}
              {probeStates[i] === "active" && (<><span className="probe-spinner" /> {T("يعمل", "Working", lang)}</>)}
              {probeStates[i] === "pending" && T("بانتظار", "Waiting", lang)}
            </div>
          </div>
        ))}
      </div>

      {showEnrich && (
        <div className="enrich-card">
          <div className="enrich-head">
            <div>
              <h3 className="enrich-title">
                {T("٣ أسئلة ترفع دقة التقييم", "3 questions to sharpen your score", lang)}
              </h3>
              <p className="enrich-sub">
                {T(
                  "من ٧٠٪ ثقة إلى ٩٥٪. تخطَّى إذا تريد النتيجة السريعة.",
                  "From 70% to 95% confidence. Skip for the quick result.",
                  lang
                )}
              </p>
            </div>
            <button className="enrich-skip" onClick={dismissEnrich}>
              {T("تخطَّى", "Skip", lang)}
            </button>
          </div>
          {ENRICH_Q.map((q) => (
            <div key={q.id} className="enrich-q">
              <div className="enrich-q-label">{T(q.ar, q.en, lang)}</div>
              <div className="enrich-options">
                {q.options.map((o) => (
                  <button
                    key={o.v}
                    className={`enrich-opt ${answers[q.id] === o.v ? "is-selected" : ""}`}
                    onClick={() => setAnswers(a => ({ ...a, [q.id]: o.v }))}
                  >
                    {T(o.ar, o.en, lang)}
                  </button>
                ))}
              </div>
            </div>
          ))}
          <div className="enrich-confidence">
            <span>{T("دقة التقييم", "Score confidence", lang)}</span>
            <div className="enrich-conf-bar">
              <div className="enrich-conf-fill" style={{ width: `${70 + Object.keys(answers).length * 8}%` }} />
            </div>
            <span><b style={{ color: "var(--karam-navy)" }}>{70 + Object.keys(answers).length * 8}%</b></span>
          </div>
        </div>
      )}
    </div>
  );
}

// ─── Score gauge ─────────────────────────────────────────────
function ScoreGauge({ score, tier, animateKey }) {
  const r = 130;
  const c = 2 * Math.PI * r;
  const [progress, setProgress] = useState(0);
  useEffect(() => {
    setProgress(0);
    const t = setTimeout(() => setProgress(score), 80);
    return () => clearTimeout(t);
  }, [score, animateKey]);
  const offset = c - (progress / 100) * c;
  const color = tier === "leader" ? "#22C55E" : tier === "solid" ? "#0EA5A0" : tier === "needs" ? "#F59E0B" : "var(--karam-danger)";
  return (
    <div className="score-gauge">
      <svg viewBox="0 0 300 300">
        <circle cx="150" cy="150" r={r} className="score-gauge-track" />
        <circle cx="150" cy="150" r={r}
          className="score-gauge-fill"
          style={{ stroke: color }}
          strokeDasharray={c}
          strokeDashoffset={offset}
        />
      </svg>
      <div className="score-gauge-center">
        <div className="score-value">{score}</div>
        <div className="score-of">/ 100</div>
      </div>
    </div>
  );
}

// ─── ScaledFit: scales a fixed-size child to fill parent width ───────
function ScaledFit({ width, height, innerRef, children }) {
  const hostRef = React.useRef(null);
  const [scale, setScale] = React.useState(1);
  React.useLayoutEffect(() => {
    const el = hostRef.current;
    if (!el) return;
    const compute = () => {
      const w = el.clientWidth;
      if (w > 0) setScale(w / width);
    };
    compute();
    const ro = new ResizeObserver(compute);
    ro.observe(el);
    return () => ro.disconnect();
  }, [width]);
  return (
    <div ref={hostRef} style={{ width: "100%", height: "100%", position: "relative", overflow: "hidden" }}>
      <div ref={innerRef} style={{
        width, height,
        transform: `scale(${scale})`,
        transformOrigin: document.documentElement.getAttribute("dir") === "rtl" ? "top right" : "top left",
        position: "absolute",
        top: 0,
        insetInlineStart: 0,
      }}>
        {children}
      </div>
    </div>
  );
}

// ─── Share Card (the actual 1200x630 artwork) ───────────────
function ShareCardArt({ store, lang, editorial, revealName = false }) {
  const tierLabelAr = { leader: "رائد", solid: "قوي", needs: "يحتاج تحسين", risk: "في خطر" };
  const tierLabelEn = { leader: "Leader", solid: "Solid", needs: "Needs work", risk: "At risk" };
  const tierClass = { leader: "tier-leader", solid: "tier-solid", needs: "tier-needs", risk: "tier-risk" };
  const bandClass = { leader: "band-leader", solid: "band-solid", needs: "band-needs", risk: "band-risk" };

  const pillarScore = (id) => store.pillars[id].score;
  const bandForScore = (s) => s >= 80 ? "band-leader" : s >= 60 ? "band-solid" : s >= 40 ? "band-needs" : "band-risk";

  const pillarNames = {
    response: T("الاستجابة", "Response", lang),
    channels: T("القنوات", "Channels", lang),
    trust:    T("الثقة", "Trust", lang),
    reviews:  T("التقييمات", "Reviews", lang),
    speed:    T("السرعة", "Speed", lang),
  };

  // Anonymous-by-default share line. Spec: merchants share more when not self-exposing.
  // Reveal toggle in the modal opts into showing the actual store name.
  const followersLabel = store.followers
    ? `${store.followers.toLocaleString(lang === "ar" ? "ar-SA" : "en")} ${T("متابع", "followers", lang)}`
    : null;
  const platformPart = platformLabel(store.platform, lang);
  const anonymousLabel = lang === "ar"
    ? `متجر سعودي · ${platformPart}${followersLabel ? ` · ${followersLabel}` : ""}`
    : `Saudi store · ${platformPart}${followersLabel ? ` · ${followersLabel}` : ""}`;
  const namedLabel = `${T(store.name, store.nameEn, lang)} · ${platformPart}${followersLabel ? ` · ${followersLabel}` : ""}`;
  const metaLine = revealName ? namedLabel : anonymousLabel;

  return (
    <div className="share-card" dir={lang === "ar" ? "rtl" : "ltr"}
      style={editorial ? { background: "#0E1419", color: "#E6EDE9" } : {}}>
      <div className="share-card-head">
        <div className="share-card-brand">
          <img src="assets/karam-logo.png" alt="Karam" style={editorial ? { filter: "brightness(0) invert(1)" } : {}} />
          <div className="share-card-title" style={editorial ? { color: "#8CA5B4", borderInlineStartColor: "#25333C" } : {}}>
            {T("تقييم تجربة العميل", "CX Benchmark", lang)}
          </div>
        </div>
        <div className="share-card-meta" style={editorial ? { background: "#1A242B", borderColor: "#25333C", color: "#B8CAD1" } : {}}>
          {metaLine}
        </div>
      </div>

      <div className="share-card-body">
        <div className="share-score-block">
          <div className="share-score-value" style={editorial ? { color: "#F5FAF8" } : {}}>{store.total}</div>
          <div className="share-score-of" style={editorial ? { color: "#8CA5B4" } : {}}>/ 100</div>
          <div className={`share-tier-badge ${tierClass[store.tier]}`}>
            {T(tierLabelAr[store.tier], tierLabelEn[store.tier], lang)}
          </div>
        </div>

        <div className="share-bars">
          {PILLARS.map((p) => (
            <div key={p.id} className="share-bar">
              <div className="share-bar-label" style={editorial ? { color: "#E6EDE9" } : {}}>{pillarNames[p.id]}</div>
              <div className="share-bar-track" style={editorial ? { background: "rgba(255,255,255,0.1)" } : {}}>
                <div className={`share-bar-fill ${bandForScore(pillarScore(p.id))}`}
                  style={{ width: `${pillarScore(p.id)}%` }} />
              </div>
              <div className="share-bar-value" style={editorial ? { color: "#F5FAF8" } : {}}>{pillarScore(p.id)}</div>
            </div>
          ))}
        </div>
      </div>

      <div className="share-card-foot">
        <div className="share-insight" style={editorial ? { background: "#1A242B", borderColor: "#25333C" } : {}}>
          <div className="share-insight-label">
            {T("أبرز ملاحظة", "Top insight", lang)}
          </div>
          <div className="share-insight-text" style={editorial ? { color: "#F5FAF8" } : {}}>
            {T(store.insight.ar, store.insight.en, lang)}
          </div>
        </div>
        <div className="share-cta-link" style={editorial ? { color: "#8CA5B4" } : {}}>
          {T("افحص متجرك", "Scan your store", lang)}
          <b style={editorial ? { color: "#90D2E1" } : {}}>karamai.co/check</b>
        </div>
      </div>
    </div>
  );
}

// ─── Results ─────────────────────────────────────────────────
// ─── Email capture ───────────────────────────────────────────
function EmailCapture({ lang, scanId }) {
  const [email, setEmail] = useState("");
  const [state, setState] = useState("idle"); // idle | sending | sent | error
  const submit = async (e) => {
    e.preventDefault();
    if (!email || state === "sending") return;
    setState("sending");
    try {
      await apiCaptureLead({ email, scanId, lang });
      setState("sent");
    } catch (_err) {
      setState("error");
    }
  };
  return (
    <div className="email-capture">
      <div>
        <h3>{T("ابعث لي التقرير الكامل + إعادة فحص بعد ٣٠ يوم", "Send me the full report + 30-day rescan", lang)}</h3>
        <p>
          {state === "sent"
            ? T("وصلنا إيميلك — ببعث التقرير خلال دقايق.", "Got it — the report is on its way.", lang)
            : state === "error"
              ? T("صار خطأ. جرب مرة ثانية.", "Something went wrong. Try again.", lang)
              : T("٨–١٢ صفحة PDF بالعربية مع المصادر، وخطة عمل ٣٠ يوم.", "8–12 page Arabic PDF with sources and a 30-day action plan.", lang)}
        </p>
      </div>
      {state !== "sent" && (
        <div>
          <form className="email-form" onSubmit={submit}>
            <input
              type="email"
              placeholder={T("بريدك@متجرك.com", "you@yourstore.com", lang)}
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              disabled={state === "sending"}
              dir="ltr"
              required
            />
            <button className="btn btn-primary" type="submit" disabled={state === "sending"}>
              {state === "sending"
                ? T("جار الإرسال...", "Sending...", lang)
                : T("أرسل التقرير", "Send report", lang)}
              {state !== "sending" && <Icon name={lang === "ar" ? "arrow-left" : "arrow-right"} size={14} />}
            </button>
          </form>
          <div style={{ fontSize: 11.5, color: "var(--karam-muted-ink)", marginTop: 8, lineHeight: 1.5 }}>
            {T(
              "بإرسال بريدك توافق على ",
              "By submitting your email you agree to our ",
              lang,
            )}
            <a href="privacy.html" target="_blank" style={{ color: "var(--karam-muted-ink)", textDecoration: "underline", textUnderlineOffset: 2 }}>
              {T("سياسة الخصوصية", "privacy policy", lang)}
            </a>
            {T(
              ". لن نشاركه مع أحد.",
              ". We won't share it with anyone.",
              lang,
            )}
          </div>
        </div>
      )}
    </div>
  );
}

function Results({ lang, storeId, live, onRescan, onShare, editorial }) {
  // Live data takes precedence; demo mode (STORES[]) is the fallback so the
  // tweaks panel's "Jump to results" still works with no backend.
  const liveStore = useMemo(() => liveToStore(live), [live]);
  const store = liveStore || STORES[storeId];
  const recs = (live && live.recommendations && live.recommendations.length > 0)
    ? live.recommendations
    : RECOMMENDATIONS[storeId] || [];
  useLucide([storeId, lang, live && live.scanId]);

  const tierLabelAr = { leader: "رائد", solid: "قوي", needs: "يحتاج تحسين", risk: "في خطر" };
  const tierLabelEn = { leader: "Leader", solid: "Solid", needs: "Needs work", risk: "At risk" };
  const tierClass = { leader: "tier-leader", solid: "tier-solid", needs: "tier-needs", risk: "tier-risk" };

  const bandForScore = (s) => s >= 80 ? "band-leader" : s >= 60 ? "band-solid" : s >= 40 ? "band-needs" : "band-risk";

  return (
    <div className="result-screen">
      <div className="result-inner">
        <div className="result-head">
          <div className="result-head-left">
            <div className="store-avatar" style={{ background: store.color, overflow: "hidden" }}>
              {store.logoUrl ? (
                <img
                  src={store.logoUrl}
                  alt={store.name}
                  style={{ width: "100%", height: "100%", objectFit: "cover" }}
                  onError={(e) => { e.target.style.display = "none"; }}
                />
              ) : store.initials}
            </div>
            <div>
              <h1 className="store-name">{T(store.name, store.nameEn, lang)}</h1>
              <div className="store-url">{store.url} · {platformLabel(store.platform, lang)} · {store.followers.toLocaleString(lang === "ar" ? "ar-SA" : "en")} {T("متابع على إنستقرام", "IG followers", lang)}</div>
            </div>
          </div>
          <div className="result-head-right">
            <button className="btn btn-secondary" onClick={onRescan}>
              <Icon name="rotate-cw" size={14} />
              {T("فحص جديد", "New scan", lang)}
            </button>
            <button className="btn btn-primary" onClick={onShare}>
              <Icon name="share-2" size={14} />
              {T("شارك النتيجة", "Share result", lang)}
            </button>
          </div>
        </div>

        {/* HERO */}
        <div className="hero-card">
          <ScoreGauge score={store.total} tier={store.tier} animateKey={storeId} />
          <div className="hero-right">
            <div className={`tier-badge ${tierClass[store.tier]}`} style={{ marginBottom: 12 }}>
              <Icon name={store.tier === "leader" ? "trophy" : store.tier === "solid" ? "check-circle-2" : store.tier === "needs" ? "alert-triangle" : "alert-octagon"} size={14} />
              {T(tierLabelAr[store.tier], tierLabelEn[store.tier], lang)}
            </div>
            <h2>{T(store.verdict.ar, store.verdict.en, lang)}</h2>
            <div className="percentile-row">
              <div className="percentile-num">{store.percentile}%</div>
              <div className="percentile-label">
                {T(
                  `أفضل من ${store.percentile}٪ من متاجر ${store.category} على ${platformLabel(store.platform, "ar")}`,
                  `Ahead of ${store.percentile}% of ${store.categoryEn} stores on ${platformLabel(store.platform, "en")}`,
                  lang
                )}
              </div>
            </div>
          </div>
        </div>

        {/* PILLARS */}
        <div className="section-title">
          <h3>{T("التفكيك حسب المحاور الخمسة", "Five-pillar breakdown", lang)}</h3>
          <div className="sub">{T("أوزان مبنية على ما يحرّك الإيرادات في السوق السعودي", "Weights anchored to what moves revenue in KSA", lang)}</div>
        </div>
        <div className="pillars-grid">
          {PILLARS.map((p) => {
            const s = store.pillars[p.id].score;
            return (
              <div key={p.id} className="pillar-card">
                <div className="pillar-head">
                  <div className="pillar-icon"><Icon name={p.icon} size={18} /></div>
                  <div className="pillar-weight">{p.weight}%</div>
                </div>
                <div className="pillar-name">{T(p.nameAr, p.nameEn, lang)}</div>
                <div className="pillar-score-row">
                  <div className="pillar-score">{s}</div>
                  <div className="pillar-score-of">/ 100</div>
                </div>
                <div className="pillar-bar">
                  <div className={`pillar-bar-fill ${bandForScore(s)}`} style={{ width: `${s}%` }} />
                </div>
                <div className="pillar-note">{T(p.noteAr, p.noteEn, lang)}</div>
              </div>
            );
          })}
        </div>

        {/* RECOMMENDATIONS */}
        <div className="section-title">
          <h3>{T("٣ توصيات مبنية على نتائجك", "Your top 3 fixes", lang)}</h3>
          <div className="sub">{T("مرتبة حسب الأثر × سهولة التنفيذ", "Ranked by impact × ease", lang)}</div>
        </div>
        <div className="recs-list">
          {recs.map((r, i) => {
            const pillar = PILLARS.find(p => p.id === r.pillar);
            return (
              <div key={r.id} className={`rec-card ${r.karam ? "is-karam" : ""}`}>
                <div className="rec-num">{lang === "ar" ? ["١","٢","٣"][i] : i + 1}</div>
                <div className="rec-body">
                  <div className="rec-pillar-tag">
                    <Icon name={pillar.icon} size={11} />
                    {T(pillar.nameAr, pillar.nameEn, lang)}
                  </div>
                  <h4 className="rec-title">{T(r.titleAr, r.titleEn, lang)}</h4>
                  <p className="rec-finding">{T(r.findingAr, r.findingEn, lang)}</p>
                  <div className="rec-action">
                    <Icon name="arrow-right" size={16} />
                    <div>
                      <span className="rec-action-label">{T("الإجراء:", "Action:", lang)}</span>
                      {T(r.actionAr, r.actionEn, lang)}
                    </div>
                  </div>
                  {r.karam && (
                    <div className="rec-karam-fit">
                      <span className="k-mark">K</span>
                      <div>
                        <b>{T("كرم يقدر يسوي هذا", "Karam can do this", lang)} · </b>
                        {T(r.karamPitchAr, r.karamPitchEn, lang)}
                      </div>
                    </div>
                  )}
                  {r.ext && (
                    <a className="rec-ext-link" href="#">
                      {T(r.ext.ar, r.ext.en, lang)}
                      <Icon name={lang === "ar" ? "arrow-left" : "arrow-right"} size={12} />
                    </a>
                  )}
                </div>
                <div className="rec-side">
                  <div className={`rec-severity sev-${r.severity}`}>
                    {r.severity === "high" ? T("أولوية عالية", "High", lang) :
                     r.severity === "med"  ? T("متوسطة", "Med", lang) : T("منخفضة", "Low", lang)}
                  </div>
                  <div className="rec-impact">
                    <b>{T(r.impactValueAr, r.impactValueEn, lang)}</b>
                    <div>{T(r.impactAr, r.impactEn, lang)}</div>
                  </div>
                </div>
              </div>
            );
          })}
        </div>

        {/* SHARE BLOCK */}
        <div className="share-section">
          <div className="share-copy">
            <h3>{T("بطاقة جاهزة للمشاركة في واتساب", "A share card ready for WhatsApp", lang)}</h3>
            <p>
              {T(
                "حمّل بطاقتك بثلاثة أحجام أو شاركها مباشرة. تلقائياً مجهولة الاسم — لك حرية إظهار اسم المتجر.",
                "Download the card in three sizes or share directly. Anonymous by default — reveal your store name if you like.",
                lang
              )}
            </p>
            <div className="share-buttons">
              <button className="share-btn is-wa" onClick={() => openWhatsAppShare(store, lang)}>
                <Icon name="message-circle" size={15} />
                {T("مشاركة عبر واتساب", "Share on WhatsApp", lang)}
              </button>
              <button className="share-btn" onClick={onShare}>
                <Icon name="download" size={15} />
                {T("عرض البطاقة", "Preview card", lang)}
              </button>
              <button className="share-btn" onClick={async () => {
                const ok = await copyToClipboard(shareText(store, lang));
                if (!ok) alert(T("تعذر النسخ.", "Couldn't copy.", lang));
              }}>
                <Icon name="copy" size={15} />
                {T("نسخ الرابط", "Copy link", lang)}
              </button>
            </div>
          </div>
          <div className="share-card-preview" onClick={onShare}>
            <ScaledFit width={1200} height={630}>
              <ShareCardArt store={store} lang={lang} editorial={editorial} />
            </ScaledFit>
          </div>
        </div>

        {/* EMAIL CAPTURE */}
        <EmailCapture lang={lang} scanId={live && live.scanId} />

        {/* TRIAL CTA (contextual) — only shows when at least one rec is Karam-solvable;
            otherwise we'd be misclaiming Karam fits the merchant's top issue. */}
        {(() => {
          const karamRec = recs.find((r) => r.karam);
          if (!karamRec) return null;
          const headline = lang === "ar"
            ? `${karamRec.titleAr} — كرم يقدر يحلها اليوم.`
            : `${karamRec.titleEn} — Karam can solve it today.`;
          const pitch = lang === "ar"
            ? (karamRec.karamPitchAr || "رد تلقائي ذكي بالعربي السعودي خلال ١٥ ثانية، ٢٤/٧ — ويكمّل الطلب داخل المحادثة بدلاً من أن تفقد العميل.")
            : (karamRec.karamPitchEn || "AI auto-reply in Saudi Arabic in 15s, 24/7 — completes the order inside the chat instead of losing the customer.");
          return (
        <div className="trial-cta">
          <div className="trial-mascot">
            <img src="assets/karam-mascot.png" alt="" />
          </div>
          <div className="trial-copy">
            <h3>{headline}</h3>
            <p>{pitch}</p>
            <button className="trial-btn">
              {T("ابدأ الفترة التجريبية ١٤ يوم", "Start 14-day trial", lang)}
              <Icon name={lang === "ar" ? "arrow-left" : "arrow-right"} size={15} />
            </button>
          </div>
        </div>
          );
        })()}

      </div>
    </div>
  );
}

// ─── Share Modal ─────────────────────────────────────────────
function ShareModal({ lang, storeId, live, editorial, onClose }) {
  const liveStore = useMemo(() => liveToStore(live), [live]);
  const store = liveStore || STORES[storeId];
  // Anonymous by default — spec says merchants share more when not self-exposing.
  const [revealName, setRevealName] = useState(false);
  // Inner refs point at the un-scaled 1200x630 / 1080x1080 nodes inside ScaledFit,
  // not the scaled-down preview frames — so the exported PNG is at full resolution.
  const ogInnerRef = useRef(null);
  const sqInnerRef = useRef(null);
  const safeHost = (store && (store.url || store.name) || "karam").replace(/[^a-z0-9]+/gi, "-");
  const downloadOg = useCallback(() => {
    downloadNodeAsPng(ogInnerRef.current, `karam-benchmark-${safeHost}-1200x630.png`);
  }, [safeHost]);
  const downloadSq = useCallback(() => {
    downloadNodeAsPng(sqInnerRef.current, `karam-benchmark-${safeHost}-1080x1080.png`);
  }, [safeHost]);
  const onWhatsApp = useCallback(() => openWhatsAppShare(store, lang), [store, lang]);
  const onCopy = useCallback(async () => {
    const ok = await copyToClipboard(shareText(store, lang));
    if (!ok) alert(T("تعذر النسخ.", "Couldn't copy.", lang));
  }, [store, lang]);
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <h3 className="modal-title">{T("بطاقة المشاركة", "Your share card", lang)}</h3>
            <div style={{ fontSize: 13, color: "var(--karam-muted-ink)", marginTop: 4 }}>
              {T("ثلاثة أحجام جاهزة — واتساب، إنستقرام، ستوري.", "Three sizes — WhatsApp, Instagram feed, Story.", lang)}
            </div>
          </div>
          <button className="modal-close" onClick={onClose}><Icon name="x" size={16} /></button>
        </div>

        <div className="share-previews">
          {/* 1200x630 */}
          <div className="share-preview-wrap">
            <div className="share-preview-label">
              <span>{T("١٢٠٠×٦٣٠ — واتساب / OG", "1200×630 — WhatsApp / OG", lang)}</span>
              <button className="btn btn-secondary" style={{ padding: "4px 10px", fontSize: 12 }} onClick={downloadOg}>
                <Icon name="download" size={12} /> PNG
              </button>
            </div>
            <div className="share-preview-frame og">
              <ScaledFit width={1200} height={630} innerRef={ogInnerRef}>
                <ShareCardArt store={store} lang={lang} editorial={editorial} revealName={revealName} />
              </ScaledFit>
            </div>
            <div style={{ display: "flex", gap: 6, marginTop: 4 }}>
              <button className="share-btn is-wa" style={{ flex: 1, justifyContent: "center" }} onClick={onWhatsApp}>
                <Icon name="message-circle" size={14} />
                {T("واتساب", "WhatsApp", lang)}
              </button>
              <button className="share-btn" style={{ flex: 1, justifyContent: "center", background: "var(--karam-surface)", color: "var(--karam-ink)", border: "1px solid var(--karam-border)" }} onClick={onCopy}>
                <Icon name="copy" size={14} />
                {T("نسخ الرابط", "Copy link", lang)}
              </button>
            </div>
          </div>

          {/* Square + Story stacked */}
          <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
            <div className="share-preview-wrap">
              <div className="share-preview-label">
                <span>{T("١٠٨٠×١٠٨٠ — إنستقرام", "1080×1080 — Instagram", lang)}</span>
                <button className="btn btn-secondary" style={{ padding: "4px 10px", fontSize: 12 }} onClick={downloadSq}>
                  <Icon name="download" size={12} /> PNG
                </button>
              </div>
              <div className="share-preview-frame sq">
                <ScaledFit width={1080} height={1080} innerRef={sqInnerRef}>
                  <div style={{
                    width: 1080, height: 1080,
                    background: editorial ? "#0E1419" : "#FAFCFC",
                    padding: "100px 80px",
                    display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 24,
                    boxSizing: "border-box"
                  }} dir={lang === "ar" ? "rtl" : "ltr"}>
                  <img src="assets/karam-logo.png" style={{ height: 56, filter: editorial ? "brightness(0) invert(1)" : "none" }} />
                  <div style={{ fontSize: 30, color: editorial ? "#8CA5B4" : "var(--karam-muted-ink)" }}>
                    {T("تقييم تجربة العميل", "CX Benchmark", lang)}
                  </div>
                  <div style={{ fontSize: 260, fontWeight: 700, color: editorial ? "#F5FAF8" : "var(--karam-navy)", lineHeight: 0.9, letterSpacing: "-0.02em" }}>
                    {store.total}
                  </div>
                  <div style={{ fontSize: 36, color: editorial ? "#8CA5B4" : "var(--karam-muted-ink)" }}>/ 100</div>
                  <div className={`share-tier-badge ${store.tier === "leader" ? "tier-leader" : store.tier === "solid" ? "tier-solid" : store.tier === "needs" ? "tier-needs" : "tier-risk"}`} style={{ fontSize: 32, padding: "14px 36px" }}>
                    {T({leader:"رائد", solid:"قوي", needs:"يحتاج تحسين", risk:"في خطر"}[store.tier],
                       {leader:"Leader", solid:"Solid", needs:"Needs work", risk:"At risk"}[store.tier], lang)}
                  </div>
                  <div style={{ fontSize: 28, color: editorial ? "#B8CAD1" : "var(--karam-ink)", textAlign: "center", fontWeight: 600, maxWidth: 800, textWrap: "balance", marginTop: 16 }}>
                    {T(store.insight.ar, store.insight.en, lang)}
                  </div>
                  <div style={{ fontSize: 26, color: editorial ? "#90D2E1" : "var(--karam-steel-prod)", marginTop: 12, fontWeight: 600 }}>
                    karamai.co/check
                  </div>
                  </div>
                </ScaledFit>
              </div>
            </div>
          </div>
        </div>

        <div style={{ display: "flex", gap: 10, justifyContent: "center", marginTop: 20, fontSize: 12, color: "var(--karam-muted-ink)" }}>
          <label style={{ display: "flex", alignItems: "center", gap: 6 }}>
            <input
              type="checkbox"
              checked={revealName}
              onChange={(e) => setRevealName(e.target.checked)}
            />
            {T("إظهار اسم المتجر في البطاقة", "Show store name on card", lang)}
          </label>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { AppTopbar, Landing, ScanningScreen, Results, ShareModal, ShareCardArt });
