/* ============================================================
   EBTR — App shell: routing, persistence, tweaks, modals
   ============================================================ */
const { Button: EBButtonA, ThreeBar: EBThreeBarA, Input: EBInputA } = window.EBTHubDesignSystem_ccdc9d;

const EBTR_LS = "ebtr_state_v1";
// The signed-in reader. In production this comes from the auth session
// (Google SSO for @ebthub.com, or the partner's invited account).
const EBTR_VIEWER = { name: "Demo Partner", company: "Acme GmbH" };
function ebtrLoad() { try { return JSON.parse(localStorage.getItem(EBTR_LS)) || {}; } catch (e) { return {}; } }
function ebtrSave(s) { try { localStorage.setItem(EBTR_LS, JSON.stringify(s)); } catch (e) {} }

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "layout": "highlight",
  "display": "michroma",
  "motion": true,
  "protect": true,
  "viewerState": "auto"
}/*EDITMODE-END*/;

/* ---- Modal ---- */
function EBTRModal({ title, subtitle, children, onClose, width = 460 }) {
  React.useEffect(() => {
    const k = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", k); return () => window.removeEventListener("keydown", k);
  }, [onClose]);
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 100, background: "rgba(8,8,10,0.74)", backdropFilter: "blur(6px)", display: "flex", alignItems: "center", justifyContent: "center", padding: 24, animation: "ebtrFade 200ms ease-out" }}>
      <div onClick={(e) => e.stopPropagation()} style={{ width: "100%", maxWidth: width, maxHeight: "88vh", overflowY: "auto", background: "var(--surface-raised)", border: "1px solid var(--border-hairline)", borderTop: "3px solid var(--ebt-orange)", padding: "34px 36px 38px", animation: "ebtrRise 240ms var(--ease-out)" }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 22 }}>
          <EBThreeBarA orientation="vertical" thickness={8} />
          <button onClick={onClose} style={{ background: "none", border: "none", color: "var(--text-muted)", cursor: "pointer", fontSize: 22, lineHeight: 1, fontFamily: "var(--font-ui)" }}>✕</button>
        </div>
        <h2 style={{ fontFamily: "var(--font-body)", fontWeight: 700, fontSize: 24, color: "var(--white)", margin: "0 0 8px", textWrap: "balance" }}>{title}</h2>
        {subtitle && <p style={{ fontFamily: "var(--font-body)", fontSize: 15.5, lineHeight: 1.6, color: "var(--text-secondary)", margin: "0 0 22px" }}>{subtitle}</p>}
        {children}
      </div>
    </div>
  );
}

/* Dark form field helpers for the application form */
const EBTR_FIELD = { fontFamily: "var(--font-body)", fontSize: 15, color: "var(--white)", background: "var(--neutral-900)", border: "1px solid var(--border-strong)", borderRadius: "var(--radius-sm)", padding: "12px 14px", outline: "none", width: "100%" };
function EBTRField({ label, children }) {
  return (
    <label style={{ display: "flex", flexDirection: "column", gap: 8 }}>
      <span style={{ fontFamily: "var(--font-ui)", fontSize: 10.5, letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--text-secondary)" }}>{label}</span>
      {children}
    </label>
  );
}
function EBTRApplyForm({ onSubmit }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      <EBInputA label="Work email" type="email" placeholder="you@company.com" />
      <EBInputA label="Company name" placeholder="Acme GmbH" />
      <EBTRField label="Team size">
        <select style={EBTR_FIELD} defaultValue="">
          <option value="" disabled>Select…</option>
          <option>1–10</option>
          <option>11–100</option>
          <option>101–1,000</option>
          <option>1,000+</option>
        </select>
      </EBTRField>
      <button onClick={onSubmit} style={{ width: "100%", background: "var(--ebt-orange)", border: "none", borderRadius: "var(--radius-sm)", padding: "13px 16px", cursor: "pointer", fontFamily: "var(--font-ui)", fontSize: 11, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--neutral-1000)" }}>Request partner access</button>
      <div style={{ fontFamily: "var(--font-ui)", fontSize: 10.5, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--text-muted)" }}>Goes to partners@ebthub.com · no obligation · GDPR-compliant</div>
    </div>
  );
}

function EBTRApp() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const saved0 = ebtrLoad();
  const [route, setRoute] = React.useState(saved0.route && saved0.route.name !== "saved" ? saved0.route : { name: "home" });
  const [activeCategory, setActiveCategory] = React.useState(saved0.activeCategory || "all");
  const [unlockedIds, setUnlockedIds] = React.useState(saved0.unlockedIds || []);
  const [signedIn, setSignedIn] = React.useState(!!saved0.signedIn);
  const [liveViewer, setLiveViewer] = React.useState(null);
  const [liveRoles, setLiveRoles] = React.useState([]);
  const [modal, setModal] = React.useState(null);
  const [signinEmail, setSigninEmail] = React.useState("");
  const LIVE = !!window.EBTR_AUTH;
  const [dataVer, setDataVer] = React.useState(0);

  // Live data: pull published articles from Firestore (falls back to bundled demo)
  React.useEffect(() => {
    if (!LIVE || !window.EBTR_FETCH_ARTICLES) return;
    window.EBTR_FETCH_ARTICLES().then(function (d) {
      if (d && d.articles && d.articles.length) {
        var cats = (d.categories && Object.keys(d.categories).length) ? d.categories : window.EBTR_DATA.categories;
        var authors = (d.authors && Object.keys(d.authors).length) ? d.authors : window.EBTR_DATA.authors;
        var catKeys = Object.keys(cats);
        var labelToKey = {}; catKeys.forEach(function (k) { labelToKey[(cats[k].label || "").toLowerCase()] = k; });
        var firstAuthor = Object.keys(authors)[0];
        // Sanitize: guarantee every article has a valid category key, a known author, and an array body.
        var clean = d.articles.map(function (a) {
          a = a || {};
          var cat = a.category;
          if (!cat || !cats[cat]) cat = labelToKey[(cat || "").toLowerCase()] || catKeys[0];
          var author = (a.author && authors[a.author]) ? a.author : (authors[a.author] ? a.author : firstAuthor);
          return Object.assign({}, a, {
            category: cat,
            author: author,
            body: Array.isArray(a.body) ? a.body : [],
            references: Array.isArray(a.references) ? a.references : [],
            related: Array.isArray(a.related) ? a.related : [],
            cover: a.cover || "blue",
            readingMins: a.readingMins || Math.max(2, Math.round(((a.body || []).reduce(function (n, b) { return n + ((b && b.text) ? b.text.length : 0); }, 0)) / 900)),
            freeUntil: a.freeUntil == null ? 3 : a.freeUntil,
          });
        }).filter(function (a) { return a.id && a.title; });
        if (clean.length) {
          window.EBTR_DATA.articles = clean;
          window.EBTR_DATA.categories = cats;
          window.EBTR_DATA.authors = authors;
          setDataVer(function (v) { return v + 1; });
        }
      }
    }).catch(function (e) { console.warn("article fetch failed", e); });
  }, []);

  // Live auth: subscribe to Firebase session + complete any email sign-in link
  React.useEffect(() => {
    if (!LIVE) return;
    window.EBTR_AUTH.completeLinkIfPresent().then(function (ok) { if (ok) setModal(null); }).catch(function () {});
    const unsub = window.EBTR_AUTH.onChange(function (v) {
      setLiveViewer(v);
      // pull this user's roles so premium gating reflects real all-access grants
      if (v && window.EBTR_MY_ROLES) {
        window.EBTR_MY_ROLES(v.email).then(function (roles) { setLiveRoles(roles || []); }).catch(function () { setLiveRoles([]); });
      } else { setLiveRoles([]); }
    });
    return unsub;
  }, []);

  React.useEffect(() => { ebtrSave({ route, activeCategory, unlockedIds, signedIn }); }, [route, activeCategory, unlockedIds, signedIn]);

  // Tweak can force a viewer state for previewing; otherwise follow real sign-in.
  // Tweak can force a viewer state for previewing; "auto" follows real sign-in.
  const realSignedIn = LIVE ? !!liveViewer : signedIn;
  const loggedIn = t.viewerState === "auto" ? realSignedIn : (t.viewerState === "in" || t.viewerState === "all");
  const allAccess = LIVE ? (liveRoles.indexOf("allaccess") >= 0 || liveRoles.indexOf("editor") >= 0) : (t.viewerState === "all");
  const VIEWER = (LIVE && liveViewer) ? liveViewer : EBTR_VIEWER;
  const signIn = () => {
    if (LIVE) { window.EBTR_AUTH.google().then(function () { setModal(null); }).catch(function (e) { alert(e && e.message ? e.message : "Sign-in failed"); }); return; }
    setSignedIn(true); setModal(null);
  };
  const sendLink = (email) => {
    if (LIVE) { return window.EBTR_AUTH.sendLink(email).then(function () { setModal({ type: "linksent", email: email }); }).catch(function (e) { alert(e && e.message ? e.message : "Could not send link"); }); }
    setSignedIn(true); setModal(null);
  };
  const signOut = () => { if (LIVE) { window.EBTR_AUTH.signOut(); return; } setSignedIn(false); };

  const openArticle = (id) => setRoute({ name: "article", id });
  const goHome = () => { setActiveCategory("all"); setRoute({ name: "home" }); };
  const pickCategory = (k) => { setActiveCategory(k); setRoute({ name: "home" }); window.scrollTo(0, 0); };

  const isUnlocked = (id) => unlockedIds.includes(id);
  // In production there is no self-serve unlock yet: a logged-in reader can ONLY
  // open a Premium paper if an editor granted them all-access. Clicking "Buy"
  // explains that instead of revealing the article. (Demo mode keeps the unlock
  // so the flow can be previewed without a backend.)
  const doUnlock = (id) => {
    if (LIVE) { setModal({ type: "premiumlocked" }); return; }
    setUnlockedIds((s) => s.includes(id) ? s : [...s, id]); setModal({ type: "unlocked", id });
  };

  const data = window.EBTR_DATA;

  return (
    <div style={{ minHeight: "100vh", background: "var(--ebt-ink)", "--ebtr-display": t.display === "blanka" ? "var(--font-display)" : "var(--font-ui)" }}>
      <EBTRMasthead route={route} onHome={goHome} onCategory={pickCategory} activeCategory={activeCategory} loggedIn={loggedIn} viewer={VIEWER} onSignIn={() => setModal({ type: "signin" })} onSignOut={signOut} onApply={() => setModal({ type: "apply" })} onSearch={() => setModal({ type: "search" })} />

      {route.name === "home" && (
        <EBTRHome layout={t.layout} activeCategory={activeCategory} onOpen={openArticle} onCategory={pickCategory} motion={t.motion} />
      )}

      {route.name === "article" && (
        <EBTRReader articleId={route.id} onOpen={openArticle} onBack={goHome} onCategory={pickCategory}
          loggedIn={loggedIn} allAccess={allAccess} isUnlocked={isUnlocked(route.id)} onUnlock={doUnlock} onSignIn={() => setModal({ type: "signin" })} onApply={() => setModal({ type: "apply" })} protect={t.protect} watermark={false} viewer={VIEWER} motion={t.motion} />
      )}

      <EBTRFooter onCategory={pickCategory} />

      {/* ---- Modals ---- */}
      {modal && modal.type === "search" && (
        <EBTRSearch articles={data.articles} onOpen={(id) => { setModal(null); openArticle(id); }} onClose={() => setModal(null)} />
      )}
      {modal && modal.type === "signin" && (
        <EBTRModal title="Sign in" subtitle="Unlock every EBTR article and insider content." onClose={() => setModal(null)}>
          <button onClick={signIn} style={{ width: "100%", display: "flex", alignItems: "center", justifyContent: "center", gap: 10, background: "var(--white)", border: "none", borderRadius: "var(--radius-sm)", padding: "12px 16px", cursor: "pointer", fontFamily: "var(--font-ui)", fontSize: 12.5, letterSpacing: "0.01em", color: "#1f1f1f" }}>
            <svg width="16" height="16" viewBox="0 0 24 24" aria-hidden="true"><path fill="#4285F4" d="M23.5 12.27c0-.79-.07-1.54-.2-2.27H12v4.51h6.47a5.53 5.53 0 0 1-2.4 3.63v3h3.88c2.27-2.09 3.55-5.17 3.55-8.87z"/><path fill="#34A853" d="M12 24c3.24 0 5.95-1.08 7.95-2.91l-3.88-3c-1.08.72-2.45 1.16-4.07 1.16-3.13 0-5.78-2.11-6.73-4.96H1.29v3.09A12 12 0 0 0 12 24z"/><path fill="#FBBC05" d="M5.27 14.29A7.21 7.21 0 0 1 4.89 12c0-.8.14-1.57.38-2.29V6.62H1.29A12 12 0 0 0 0 12c0 1.94.46 3.77 1.29 5.38l3.98-3.09z"/><path fill="#EA4335" d="M12 4.75c1.77 0 3.35.61 4.6 1.8l3.43-3.43C17.95 1.19 15.24 0 12 0A12 12 0 0 0 1.29 6.62l3.98 3.09C6.22 6.86 8.87 4.75 12 4.75z"/></svg>
            Continue with EBTHub email
          </button>
          <div style={{ fontFamily: "var(--font-ui)", fontSize: 10.5, letterSpacing: "0.03em", color: "var(--text-muted)", textAlign: "center", margin: "9px 0 2px" }}>For @ebthub.com staff · Google sign-in</div>
          <div style={{ display: "flex", alignItems: "center", gap: 12, margin: "18px 0" }}>
            <span style={{ flex: 1, height: 1, background: "var(--border-hairline)" }} />
            <span style={{ fontFamily: "var(--font-ui)", fontSize: 9.5, letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--text-muted)" }}>Partner sign-in</span>
            <span style={{ flex: 1, height: 1, background: "var(--border-hairline)" }} />
          </div>
          <label style={{ display: "flex", flexDirection: "column", gap: 7 }}>
            <span style={{ fontFamily: "var(--font-ui)", fontSize: 10, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--text-secondary)" }}>Registered partner email</span>
            <input type="email" value={signinEmail} onChange={(e) => setSigninEmail(e.target.value)} placeholder="you@company.com" style={{ fontFamily: "var(--font-body)", fontSize: 15, color: "var(--white)", background: "var(--neutral-900)", border: "1px solid var(--border-strong)", borderRadius: "var(--radius-sm)", padding: "11px 13px", outline: "none", width: "100%" }} />
          </label>
          <button onClick={() => sendLink(signinEmail)} style={{ width: "100%", marginTop: 12, background: "var(--ebt-orange)", border: "none", borderRadius: "var(--radius-sm)", padding: "13px 16px", cursor: "pointer", fontFamily: "var(--font-ui)", fontSize: 11, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--neutral-1000)" }}>Send sign-in link →</button>
          <div style={{ marginTop: 18, display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 8, fontFamily: "var(--font-ui)", fontSize: 10.5, letterSpacing: "0.03em", color: "var(--text-muted)" }}>
            <button onClick={() => setModal({ type: "apply" })} className="ebtr-flink" style={{ background: "none", border: "none", padding: 0, cursor: "pointer", color: "var(--blue-400)", font: "inherit", letterSpacing: "inherit" }}>Not a partner yet? Apply →</button>
            <span>GDPR-compliant</span>
          </div>
        </EBTRModal>
      )}
      {modal && modal.type === "apply" && (
        <EBTRModal width={460} title="Ready to unlock exclusive access?" subtitle="Share your work email, company name and team size. Our partnerships team will reach out with everything you need." onClose={() => setModal(null)}>
          <EBTRApplyForm onSubmit={() => setModal({ type: "applied" })} />
        </EBTRModal>
      )}
      {modal && modal.type === "applied" && (
        <EBTRModal title="Thanks — we'll be in touch" subtitle="Your details are on their way to our partnerships team at partners@ebthub.com. We'll reach out shortly with next steps for partner access." onClose={() => setModal(null)}>
          <EBButtonA variant="primary" size="lg" onClick={() => setModal(null)}>Back to the Review</EBButtonA>
        </EBTRModal>
      )}
      {modal && modal.type === "linksent" && (
        <EBTRModal title="Check your email" subtitle={"We sent a one-time sign-in link to " + (modal.email || "your inbox") + ". Open it on this device to finish signing in."} onClose={() => setModal(null)}>
          <EBButtonA variant="primary" size="lg" onClick={() => setModal(null)}>Got it</EBButtonA>
        </EBTRModal>
      )}
      {modal && modal.type === "unlocked" && (
        <EBTRModal title="Article unlocked" subtitle="This piece is now open on this device. In production this is where a one-time purchase clears through secure checkout — or a partner entitlement is confirmed. Both handled off the app store." onClose={() => setModal(null)}>
          <EBButtonA variant="primary" size="lg" onClick={() => setModal(null)}>Keep reading</EBButtonA>
        </EBTRModal>
      )}
      {modal && modal.type === "premiumlocked" && (
        <EBTRModal title="Premium — partners only" subtitle="This in-depth paper is reserved for members with All-Access. One-time purchases aren't open yet. Ask an editor to enable All-Access for your account, or read the free articles." onClose={() => setModal(null)}>
          <EBButtonA variant="primary" size="lg" onClick={() => setModal(null)}>Back to the Review</EBButtonA>
        </EBTRModal>
      )}

      {/* ---- Tweaks ---- */}
      <TweaksPanel>
        <TweakSection label="Homepage" />
        <TweakRadio label="Layout" value={t.layout} options={[{ value: "highlight", label: "Highlight" }, { value: "briefing", label: "Briefing" }, { value: "editorial", label: "Editorial" }, { value: "signal", label: "Signal" }]} onChange={(v) => setTweak("layout", v)} />
        <TweakSection label="Headline type" />
        <TweakRadio label="Display font" value={t.display} options={[{ value: "michroma", label: "Michroma" }, { value: "blanka", label: "Blanka" }]} onChange={(v) => setTweak("display", v)} />
        <TweakSection label="Viewer" />
        <TweakRadio label="Preview as" value={t.viewerState} options={[{ value: "auto", label: "Live" }, { value: "out", label: "Visitor" }, { value: "in", label: "Reader" }, { value: "all", label: "All-Access" }]} onChange={(v) => setTweak("viewerState", v)} />
        <TweakSection label="Motion" />
        <TweakToggle label="Scroll & hover animation" value={t.motion} onChange={(v) => setTweak("motion", v)} />
        <TweakSection label="Content protection" />
        <TweakToggle label="Block copy & right-click" value={t.protect} onChange={(v) => setTweak("protect", v)} />
      </TweaksPanel>
    </div>
  );
}

class EBTRBoundary extends React.Component {
  constructor(p) { super(p); this.state = { err: null }; }
  static getDerivedStateFromError(err) { return { err: err }; }
  componentDidCatch(err, info) { try { console.error("EBTR crash:", err, info); } catch (e) {} }
  render() {
    if (this.state.err) {
      return (
        <div style={{ minHeight: "100vh", background: "var(--ebt-ink)", color: "var(--white)", padding: "60px 24px", fontFamily: "var(--font-body)" }}>
          <div style={{ maxWidth: 760, margin: "0 auto" }}>
            <div style={{ fontFamily: "var(--font-ui)", fontSize: 12, letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--ebt-orange)", marginBottom: 12 }}>Something broke while rendering</div>
            <div style={{ fontFamily: "ui-monospace, Menlo, monospace", fontSize: 14, lineHeight: 1.6, color: "var(--neutral-100)", background: "#0c0c0e", border: "1px solid var(--border-strong)", padding: "16px 18px", whiteSpace: "pre-wrap", wordBreak: "break-word" }}>{String(this.state.err && this.state.err.message ? this.state.err.message : this.state.err)}{"\n\n"}{String((this.state.err && this.state.err.stack) || "").split("\n").slice(0, 4).join("\n")}</div>
            <button onClick={() => { try { window.EBTR_DATA && (window.__noLive = 1); } catch (e) {} location.reload(); }} style={{ marginTop: 18, background: "var(--ebt-orange)", border: "none", padding: "12px 22px", cursor: "pointer", fontFamily: "var(--font-ui)", fontSize: 12, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--neutral-1000)" }}>Reload</button>
          </div>
        </div>
      );
    }
    return this.props.children;
  }
}

ReactDOM.createRoot(document.getElementById("root")).render(<EBTRBoundary><EBTRApp /></EBTRBoundary>);
