// More screens — closing prototype gaps.
// Profile, Notifications, Pay Confirmation, Add Card, Txn Detail, Email signup, Offers.

// ──────────────────────────────────────────────────────────
// Profile / Settings
// ──────────────────────────────────────────────────────────
function ScrProfile({ onBack, onScreen, onLogout }) {
  const [notifSettings, setNotifSettings] = React.useState(ED_USER.notifSettings);
  const toggle = (k) => setNotifSettings({ ...notifSettings, [k]: !notifSettings[k] });

  const totalEarned = ED_INSIGHTS.ytd.earned;

  return (
    <EDScreen>
      <EDHero>
        <div style={{ display: "flex", alignItems: "center", gap: 16 }}>
          <div style={{
            width: 64, height: 64, borderRadius: ED_R_PILL, background: ED_BILL,
            color: ED_FOREST_900, display: "flex", alignItems: "center", justifyContent: "center",
            fontSize: 22, fontWeight: 800, letterSpacing: "-0.02em",
          }}>{ED_USER.initials}</div>
          <div style={{ flex: 1 }}>
            <EDEyebrow color={ED_BILL} style={{ marginBottom: 4 }}>Account</EDEyebrow>
            <div style={{ fontSize: 28, fontWeight: 800, color: "#fff", letterSpacing: "-0.025em", lineHeight: 1.1 }}>{ED_USER.name}</div>
            <div style={{ fontSize: 13, color: ED_ON_DARK_2, marginTop: 2 }}>{ED_USER.email}</div>
          </div>
        </div>
        <div style={{ display: "flex", gap: 10, marginTop: 18 }}>
          <div style={{ flex: 1, background: "rgba(255,255,255,0.08)", borderRadius: ED_R_ICON, padding: 12 }}>
            <EDEyebrow color={ED_ON_DARK_3}>Earned YTD</EDEyebrow>
            <div style={{ fontSize: 20, fontWeight: 800, color: ED_BILL, marginTop: 4, fontFeatureSettings: '"tnum"' }}>${totalEarned.toFixed(2)}</div>
          </div>
          <div style={{ flex: 1, background: "rgba(255,255,255,0.08)", borderRadius: ED_R_ICON, padding: 12 }}>
            <EDEyebrow color={ED_ON_DARK_3}>Member since</EDEyebrow>
            <div style={{ fontSize: 14, fontWeight: 700, color: "#fff", marginTop: 4 }}>{ED_USER.joined}</div>
          </div>
        </div>
      </EDHero>

      {/* Settings groups */}
      <EDBody style={{ paddingTop: 20, paddingBottom: ED_TAB_HEIGHT + 24 }}>
        <SettingsGroup title="Account">
          <SettingsRow icon="card" label="Plan" value={ED_USER.plan} action="Upgrade" onClick={() => onScreen("upgrade")}/>
          <SettingsRow icon="mail" label="Email" value={ED_USER.email}/>
          <SettingsRow icon="bank" label="Connected bank" value="Chase · 4 cards" action="Manage" onClick={() => onScreen("plaid-manage")}/>
        </SettingsGroup>

        <SettingsGroup title="Notifications">
          <SettingsToggle icon="pin" label="Nearby alerts" sub="Heads-up when we have a recommendation" value={notifSettings.nearby} onChange={() => toggle("nearby")}/>
          <SettingsToggle icon="check" label="Wins" sub="When you swipe the optimal card" value={notifSettings.wins} onChange={() => toggle("wins")}/>
          <SettingsToggle icon="alert" label="Missed earnings" sub="When a better card was available" value={notifSettings.misses} onChange={() => toggle("misses")}/>
          <SettingsToggle icon="gift" label="Benefit reminders" sub="Credits about to expire" value={notifSettings.benefits} onChange={() => toggle("benefits")}/>
          <SettingsToggle icon="chart" label="Weekly digest" sub="Sunday recap email" value={notifSettings.weekly} onChange={() => toggle("weekly")}/>
        </SettingsGroup>

        <SettingsGroup title="Privacy & security">
          <SettingsRow icon="lock" label="Hide amounts" value="Off" action="Edit" onClick={() => alert("Privacy mode toggle — use the Tweaks panel for now")}/>
          <SettingsRow icon="shield" label="Face ID lock" value="On" action="Edit" onClick={() => alert("Face ID lock — coming soon")}/>
          <SettingsRow icon="doc" label="Legal & disclosures" action="View" onClick={() => onScreen("legal")}/>
          <SettingsRow icon="doc" label="Export my data" action="Request" onClick={() => onScreen("data-export")}/>
          <SettingsRow icon="trash" label="Delete account" tone="danger" action="Request" onClick={() => onScreen("delete-account")}/>
        </SettingsGroup>

        <SettingsGroup title="Support">
          <SettingsRow icon="help" label="Help Center" action="Open" onClick={() => alert("Help Center — opens external URL")}/>
          <SettingsRow icon="chat" label="Contact us" value="Reply in &lt;1 day" action="Email" onClick={() => { window.location.href = "mailto:hello@extradollar.com"; }}/>
          <SettingsRow icon="star" label="Rate Extra Dollar" action="App Store" onClick={() => alert("Opens App Store rating prompt")}/>
          <SettingsRow icon="share" label="Tell a friend" sub="Both get $5 when they connect a card" action="Share" onClick={() => onScreen("referral")}/>
        </SettingsGroup>

        <button onClick={onLogout} style={{
          width: "100%", padding: 14, marginTop: 12, background: "transparent",
          border: `1px solid ${ED_LINE}`, borderRadius: ED_R_BTN, cursor: "pointer",
          color: ED_DANGER, fontWeight: 600, fontSize: 15, fontFamily: "inherit",
        }}>Log out</button>

        <div style={{ textAlign: "center", marginTop: 18, fontSize: 11, color: ED_FG3 }}>
          Extra Dollar 1.0.4 · made in Brooklyn
        </div>
      </EDBody>
    </EDScreen>
  );
}

function SettingsGroup({ title, children }) {
  return (
    <div style={{ marginBottom: 22 }}>
      <EDEyebrow style={{ marginBottom: 10, paddingLeft: 4 }}>{title}</EDEyebrow>
      <div style={{ background: "#fff", borderRadius: ED_R_SURFACE, border: `1px solid ${ED_LINE}`, overflow: "hidden" }}>
        {React.Children.map(children, (c, i) => (
          <React.Fragment>
            {i > 0 && <div style={{ height: 1, background: ED_LINE, marginLeft: 52 }}/>}
            {c}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

function SettingsRow({ icon, label, sub, value, action, tone = "default", onClick }) {
  const labelColor = tone === "danger" ? ED_DANGER : ED_FOREST;
  return (
    <button onClick={onClick} style={{
      width: "100%", padding: 14, background: "transparent", border: "none",
      display: "flex", alignItems: "center", gap: 12, cursor: onClick ? "pointer" : "default",
      textAlign: "left", fontFamily: "inherit",
    }}>
      <SettingsIcon name={icon} tone={tone}/>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 15, fontWeight: 600, color: labelColor }}>{label}</div>
        {sub && <div style={{ fontSize: 12, color: ED_FG3, marginTop: 2 }}>{sub}</div>}
      </div>
      {value && <div style={{ fontSize: 13, color: ED_FG3, marginRight: action ? 6 : 0 }} dangerouslySetInnerHTML={{ __html: value }}/>}
      {action && <span style={{ fontSize: 13, color: ED_BILL_700, fontWeight: 600 }}>{action} ›</span>}
    </button>
  );
}

function SettingsToggle({ icon, label, sub, value, onChange }) {
  return (
    <div style={{ width: "100%", padding: 14, display: "flex", alignItems: "center", gap: 12 }}>
      <SettingsIcon name={icon}/>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 15, fontWeight: 600, color: ED_FOREST }}>{label}</div>
        {sub && <div style={{ fontSize: 12, color: ED_FG3, marginTop: 2 }}>{sub}</div>}
      </div>
      <button onClick={onChange} aria-label={label} style={{
        width: 46, height: 28, borderRadius: 999, border: "none", padding: 2,
        background: value ? ED_BILL : "rgba(6,57,50,0.18)",
        cursor: "pointer", transition: "background 200ms",
        position: "relative", flexShrink: 0,
      }}>
        <span style={{
          display: "block", width: 24, height: 24, borderRadius: "50%", background: "#fff",
          transform: value ? "translateX(18px)" : "translateX(0)",
          transition: "transform 200ms cubic-bezier(0.2,0.7,0.2,1)",
          boxShadow: "0 2px 4px rgba(0,0,0,0.15)",
        }}/>
      </button>
    </div>
  );
}

function SettingsIcon({ name, tone = "default" }) {
  const bg = tone === "danger" ? ED_DANGER_BG : "rgba(6,57,50,0.06)";
  const color = tone === "danger" ? ED_DANGER : ED_FOREST;
  const paths = {
    card: <><rect x="3" y="6" width="18" height="12" rx="2" stroke={color} strokeWidth="1.6"/><path d="M3 10h18" stroke={color} strokeWidth="1.6"/></>,
    mail: <><rect x="3" y="6" width="18" height="12" rx="2" stroke={color} strokeWidth="1.6"/><path d="M3 8l9 6 9-6" stroke={color} strokeWidth="1.6" strokeLinejoin="round"/></>,
    bank: <><path d="M3 10h18M5 10v8M19 10v8M9 10v8M15 10v8M3 18h18M3 10l9-6 9 6" stroke={color} strokeWidth="1.6" strokeLinejoin="round"/></>,
    pin: <><path d="M12 22s7-7 7-13a7 7 0 10-14 0c0 6 7 13 7 13z" stroke={color} strokeWidth="1.6" strokeLinejoin="round"/><circle cx="12" cy="9" r="2.5" stroke={color} strokeWidth="1.6"/></>,
    check: <path d="M5 12l4 4 10-10" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>,
    alert: <><circle cx="12" cy="12" r="9" stroke={color} strokeWidth="1.6"/><path d="M12 7v6M12 17v.5" stroke={color} strokeWidth="1.8" strokeLinecap="round"/></>,
    gift: <><rect x="3" y="9" width="18" height="12" rx="1" stroke={color} strokeWidth="1.6"/><path d="M12 9v12M3 13h18M9 9c0-3 1-5 3-5s3 2 3 5" stroke={color} strokeWidth="1.6"/></>,
    chart: <path d="M4 20V10M10 20V4M16 20v-7M22 20H2" stroke={color} strokeWidth="1.6" strokeLinecap="round"/>,
    lock: <><rect x="5" y="11" width="14" height="10" rx="2" stroke={color} strokeWidth="1.6"/><path d="M8 11V8a4 4 0 018 0v3" stroke={color} strokeWidth="1.6"/></>,
    shield: <path d="M12 3l8 3v6c0 5-3 8-8 9-5-1-8-4-8-9V6l8-3z" stroke={color} strokeWidth="1.6" strokeLinejoin="round"/>,
    doc: <><path d="M6 3h8l4 4v14H6V3z" stroke={color} strokeWidth="1.6" strokeLinejoin="round"/><path d="M14 3v4h4" stroke={color} strokeWidth="1.6"/></>,
    trash: <><path d="M5 7h14M9 7V5a1 1 0 011-1h4a1 1 0 011 1v2M7 7l1 13a1 1 0 001 1h6a1 1 0 001-1l1-13" stroke={color} strokeWidth="1.6" strokeLinejoin="round"/></>,
    help: <><circle cx="12" cy="12" r="9" stroke={color} strokeWidth="1.6"/><path d="M9 9.5a3 3 0 116 0c0 2-3 2-3 4M12 17.5v.5" stroke={color} strokeWidth="1.6" strokeLinecap="round"/></>,
    chat: <path d="M3 7a3 3 0 013-3h12a3 3 0 013 3v8a3 3 0 01-3 3H9l-4 4v-4a3 3 0 01-2-3V7z" stroke={color} strokeWidth="1.6" strokeLinejoin="round"/>,
    star: <path d="M12 3l2.6 6 6.4.5-4.8 4.4 1.5 6.5L12 17l-5.7 3.4 1.5-6.5L3 9.5 9.4 9 12 3z" stroke={color} strokeWidth="1.6" strokeLinejoin="round"/>,
    share: <><circle cx="6" cy="12" r="2.5" stroke={color} strokeWidth="1.6"/><circle cx="18" cy="6" r="2.5" stroke={color} strokeWidth="1.6"/><circle cx="18" cy="18" r="2.5" stroke={color} strokeWidth="1.6"/><path d="M8 11l8-4M8 13l8 4" stroke={color} strokeWidth="1.6"/></>,
  }[name] || null;
  return (
    <div style={{ width: 32, height: 32, borderRadius: ED_R_ICON, background: bg, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none">{paths}</svg>
    </div>
  );
}

// ──────────────────────────────────────────────────────────
// Notifications feed
// ──────────────────────────────────────────────────────────
function ScrNotifications({ onBack, onScreen }) {
  const [items, setItems] = React.useState(ED_NOTIFICATIONS);
  const markAllRead = () => setItems(items.map(n => ({ ...n, unread: false })));
  const unread = items.filter(n => n.unread).length;

  return (
    <EDScreen>
      <EDHeader
        back={onBack} eyebrow="Activity" title="Notifications"
        subtitle={`${unread} new · ${items.length} total`}
        trailing={unread > 0 ? <EDPillButton onClick={markAllRead} tone="ghost">Mark all read</EDPillButton> : null}
      />
      <EDBody style={{ paddingTop: 4, paddingBottom: ED_TAB_HEIGHT + 16 }}>
        {items.length === 0 ? (
          <EDSurface style={{ padding: 24, textAlign: "center", marginTop: 8 }}>
            <div style={{ fontSize: 15, fontWeight: 600, color: ED_FOREST, marginBottom: 6 }}>You're all caught up</div>
            <div style={{ fontSize: 13, color: ED_FG3, lineHeight: 1.5 }}>
              We'll let you know when there's a missed swipe, expiring credit, or a card to use nearby.
            </div>
          </EDSurface>
        ) : (
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {items.map(n => {
              // Route by notification type — different destinations per type per PRD §4.
              const route = () => {
                if (n.type === "benefit") return onScreen("offers");
                if (n.type === "miss" || n.type === "win") return onScreen("txn", n.txn || ED_TXNS[0]);
                if (n.type === "system") return onScreen("profile");
                return onScreen("which"); // nearby + default
              };
              return <NotifRow key={n.id} n={n} onClick={route}/>;
            })}
          </div>
        )}
      </EDBody>
    </EDScreen>
  );
}

function NotifRow({ n, onClick }) {
  const card = n.card ? ED_CARDS.find(c => c.id === n.card) : null;
  const tone = {
    nearby: { bg: ED_FOREST_900, fg: ED_BILL, label: "Nearby" },
    win: { bg: "#1f4d2a", fg: "#a3e29d", label: "Win" },
    miss: { bg: "#7a2916", fg: "#ffb29c", label: "Miss" },
    benefit: { bg: "#7a5a00", fg: "#fff3a8", label: "Benefit" },
    system: { bg: "rgba(6,57,50,0.06)", fg: ED_FOREST, label: "System" },
  }[n.type];

  return (
    <button onClick={onClick} style={{
      width: "100%", textAlign: "left", padding: 14, borderRadius: ED_R_SURFACE,
      background: n.unread ? "#fff" : "rgba(255,255,255,0.55)",
      border: `1px solid ${n.unread ? "rgba(6,57,50,0.14)" : ED_LINE}`,
      cursor: "pointer", display: "flex", gap: 12, fontFamily: "inherit",
      position: "relative",
    }}>
      <div style={{
        width: 38, height: 38, borderRadius: ED_R_ICON, background: tone.bg, color: tone.fg,
        display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
        fontSize: 11, fontWeight: 800, letterSpacing: "0.04em", textTransform: "uppercase",
      }}>{tone.label}</div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginBottom: 4 }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: ED_FOREST, flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
            {n.merchant || n.title}
          </div>
          <div style={{ fontSize: 11, color: ED_FG3, flexShrink: 0 }}>{n.time}</div>
        </div>
        <div style={{ fontSize: 13, color: ED_FG2, lineHeight: 1.4 }}>{n.body}</div>
        {card && (
          <div style={{ display: "inline-flex", alignItems: "center", gap: 6, marginTop: 8, padding: "3px 8px", background: "rgba(6,57,50,0.04)", borderRadius: 999 }}>
            <EDCardChip card={card} size={20}/>
            <span style={{ fontSize: 11, fontWeight: 600, color: ED_FOREST }}>{card.short}</span>
          </div>
        )}
      </div>
      {n.unread && <span style={{ position: "absolute", top: 16, right: 16, width: 8, height: 8, borderRadius: "50%", background: ED_BILL }}/>}
    </button>
  );
}

// ──────────────────────────────────────────────────────────
// Tap-to-Pay confirmation flow (the satisfying reward moment)
// ──────────────────────────────────────────────────────────
function ScrPayConfirm({ card, merchant, amount, multiplier, earned, onDone, onBack }) {
  // Defaults derived from card context if not explicitly passed.
  const cardObj0 = card || ED_CARDS[1];
  merchant = merchant || (typeof window !== "undefined" && window.__edLastMerchant) || "Trader Joe's";
  amount = amount ?? 30;
  // Pull multiplier from card's top reward rate when not specified.
  const topRate = cardObj0.rates ? cardObj0.rates[0] : { x: 4 };
  multiplier = multiplier ?? topRate.x;
  earned = earned ?? +(amount * (multiplier * (cardObj0.pointValue || 1)) / 100).toFixed(2);
  const [stage, setStage] = React.useState(0); // 0: ready, 1: hold-to-pay, 2: success
  const [holdProgress, setHoldProgress] = React.useState(0);
  const cardObj = cardObj0;

  React.useEffect(() => {
    if (stage !== 1) return;
    const start = performance.now();
    const dur = 900;
    let raf;
    const tick = (t) => {
      const p = Math.min(1, (t - start) / dur);
      setHoldProgress(p);
      if (p >= 1) {
        setStage(2);
        if (navigator.vibrate) navigator.vibrate(50);
      } else {
        raf = requestAnimationFrame(tick);
      }
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [stage]);

  if (stage === 2) {
    return (
      <EDScreen bg={ED_FOREST_900} dark>
        <div style={{ position: "absolute", inset: 0, background: `radial-gradient(circle at 50% 30%, ${ED_BILL}40, transparent 60%)`, animation: "edFadeIn 600ms ease", pointerEvents: "none" }}/>
        <EDBody style={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", paddingTop: ED_SAFE_TOP, paddingBottom: 0, textAlign: "center" }}>
          <div style={{
            width: 96, height: 96, borderRadius: ED_R_PILL, background: ED_BILL,
            display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 28,
            animation: "edFadeIn 500ms cubic-bezier(0.2,0.8,0.2,1)",
          }}>
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none">
              <path d="M5 12l5 5L20 7" stroke={ED_FOREST_900} strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </div>
          <EDEyebrow color={ED_BILL} style={{ marginBottom: 8 }}>+ Earned</EDEyebrow>
          <div style={{ fontSize: 56, fontWeight: 800, letterSpacing: "-0.03em", color: "#fff", fontFeatureSettings: '"tnum"', lineHeight: 1 }}>
            <EDCounter value={earned} duration={700}/>
          </div>
          <div style={{ fontSize: 16, color: ED_ON_DARK_2, marginTop: 18, lineHeight: 1.5, maxWidth: 280 }}>
            {multiplier}× on ${amount} at {merchant}, on your <strong style={{ color: "#fff" }}>{cardObj.short}</strong>.
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 28, padding: "12px 18px", background: "rgba(255,255,255,0.08)", borderRadius: ED_R_PILL }}>
            <EDCardChip card={cardObj} size={28}/>
            <span style={{ fontSize: 13, color: ED_ON_DARK_2 }}>•••• {cardObj.last4} · authorized</span>
          </div>
        </EDBody>
        <EDFooter dark>
          <EDPrimaryButton onClick={onDone} variant="dark">Done</EDPrimaryButton>
        </EDFooter>
      </EDScreen>
    );
  }

  return (
    <EDScreen bg={ED_FOREST_900} dark>
      <div style={{ padding: `${ED_SAFE_TOP}px ${ED_GUTTER}px 16px`, display: "flex", alignItems: "center", justifyContent: "space-between", flexShrink: 0 }}>
        <EDIconButton onClick={onBack} ariaLabel="Close" variant="dark">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/></svg>
        </EDIconButton>
        <EDEyebrow color={ED_BILL}>Pay with Extra Dollar</EDEyebrow>
        <span style={{ width: 36 }}/>
      </div>

      <EDBody style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", paddingTop: 0, paddingBottom: 0 }}>
        <div style={{ marginBottom: 22, transform: stage === 1 ? "scale(1.04)" : "scale(1)", transition: "transform 600ms cubic-bezier(0.2,0.7,0.2,1)" }}>
          <EDCardArt card={cardObj} w={260} h={164}/>
        </div>
        <EDEyebrow color={ED_BILL} style={{ marginBottom: 6 }}>{multiplier}× best card</EDEyebrow>
        <div style={{ fontSize: 17, color: ED_ON_DARK_2, marginBottom: 4 }}>at {merchant}</div>
        <div style={{ fontSize: 48, fontWeight: 800, color: "#fff", letterSpacing: "-0.03em", fontFeatureSettings: '"tnum"' }}>${amount.toFixed(2)}</div>
        <div style={{ fontSize: 13, color: ED_BILL, marginTop: 6, fontWeight: 600 }}>You'll earn ${earned.toFixed(2)} back</div>
      </EDBody>

      <EDFooter dark>
        <button
          onMouseDown={() => setStage(1)}
          onMouseUp={() => stage === 1 && setStage(0)}
          onMouseLeave={() => stage === 1 && setStage(0)}
          onTouchStart={() => setStage(1)}
          onTouchEnd={() => stage === 1 && setStage(0)}
          style={{
            width: "100%", height: 60, borderRadius: ED_R_PILL,
            background: stage === 1 ? `linear-gradient(90deg, ${ED_BILL} ${holdProgress*100}%, rgba(255,255,255,0.1) ${holdProgress*100}%)` : "rgba(255,255,255,0.1)",
            color: "#fff", fontSize: 16, fontWeight: 700, cursor: "pointer", fontFamily: "inherit",
            transition: stage === 1 ? "none" : "background 200ms",
            position: "relative", overflow: "hidden",
            border: `1.5px solid ${stage === 1 ? ED_BILL : ED_ON_DARK_BORDER}`,
          }}>
          {stage === 1 ? "Hold to confirm…" : "Hold to pay"}
        </button>
        <div style={{ fontSize: 11, color: "rgba(238,230,227,0.5)", textAlign: "center", marginTop: 4, lineHeight: 1.5 }}>
          Authenticated with Face ID · Apple Pay
        </div>
      </EDFooter>
    </EDScreen>
  );
}

// ──────────────────────────────────────────────────────────
// Add Card flow (manual entry)
// ──────────────────────────────────────────────────────────
function ScrAddCard({ onBack, onDone }) {
  const [issuer, setIssuer] = React.useState("");
  const [name, setName] = React.useState("");
  const [last4, setLast4] = React.useState("");
  // Each popular card pre-fills both name and issuer so the user doesn't retype.
  const popular = [
    { name: "Chase Sapphire Reserve",  issuer: "Chase" },
    { name: "Amex Platinum",           issuer: "Amex" },
    { name: "Capital One Venture X",   issuer: "Capital One" },
    { name: "Citi Premier",            issuer: "Citi" },
    { name: "Wells Fargo Active Cash", issuer: "Wells Fargo" },
    { name: "Apple Card",              issuer: "Apple" },
  ];

  return (
    <EDScreen>
      <EDHeader back={onBack} title="Add a card" subtitle="We just need the name to look up its rewards. No card numbers stored."/>
      <EDBody style={{ paddingTop: 8 }}>
        <EDEyebrow style={{ marginBottom: 10 }}>Popular cards</EDEyebrow>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 24 }}>
          {popular.map(p => (
            <button key={p.name} onClick={() => { setName(p.name); setIssuer(p.issuer); }} style={{
              padding: "8px 14px", borderRadius: ED_R_PILL, border: name === p.name ? `2px solid ${ED_FOREST}` : `1px solid ${ED_LINE}`,
              background: name === p.name ? ED_FOREST : "#fff", color: name === p.name ? ED_CREAM : ED_FOREST,
              fontSize: 13, fontWeight: 600, cursor: "pointer", fontFamily: "inherit",
            }}>{p.name}</button>
          ))}
        </div>

        <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
          <Field label="Card name" value={name} onChange={setName} placeholder="e.g. Chase Sapphire Preferred"/>
          <Field label="Issuer" value={issuer} onChange={setIssuer} placeholder="Chase, Amex, Citi…"/>
          <Field label="Last 4 digits (optional)" value={last4} onChange={setLast4} placeholder="••••" maxLength={4}/>
        </div>
      </EDBody>

      <EDFooter>
        <EDPrimaryButton disabled={!name} onClick={onDone}>Add card</EDPrimaryButton>
      </EDFooter>
    </EDScreen>
  );
}

function Field({ label, value, onChange, placeholder, maxLength }) {
  return (
    <label style={{ display: "block" }}>
      <EDEyebrow style={{ marginBottom: 6 }}>{label}</EDEyebrow>
      <input
        value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder} maxLength={maxLength}
        style={{
          width: "100%", padding: "14px 16px", borderRadius: ED_R_BTN,
          border: `1px solid ${ED_LINE}`, background: "#fff",
          fontSize: 16, fontFamily: "inherit", color: ED_FOREST, outline: "none",
          boxSizing: "border-box",
        }}/>
    </label>
  );
}

// ──────────────────────────────────────────────────────────
// Transaction Detail
// ──────────────────────────────────────────────────────────
function ScrTxnDetail({ txn, onBack, onScreen }) {
  if (!txn) txn = ED_TXNS[1]; // fallback
  const opt = optimize(txn);
  const usedCard = ED_CARDS.find(c => c.id === txn.used);

  return (
    <EDScreen>
      <EDHero back={onBack} bg={opt.isOptimal ? "#1f4d2a" : ED_FOREST_900} decorative={false}>
        <div style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 18 }}>
          <div style={{
            width: 56, height: 56, borderRadius: ED_R_BTN, background: "rgba(255,255,255,0.10)",
            display: "flex", alignItems: "center", justifyContent: "center", fontSize: 26,
          }}>{txn.logo}</div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 20, fontWeight: 800, letterSpacing: "-0.02em" }}>{txn.merchant}</div>
            <div style={{ fontSize: 13, color: ED_ON_DARK_2, marginTop: 2 }}>{txn.date} · {txn.category}</div>
          </div>
        </div>
        <EDEyebrow color={opt.isOptimal ? "#a3e29d" : "#ffb29c"} style={{ marginBottom: 6 }}>
          {opt.isOptimal ? "Optimal swipe" : `You missed $${opt.missed.toFixed(2)}`}
        </EDEyebrow>
        <div style={{ fontSize: 44, fontWeight: 800, letterSpacing: "-0.03em", fontFeatureSettings: '"tnum"' }}>${txn.amount.toFixed(2)}</div>
      </EDHero>

      <EDBody style={{ paddingTop: 20, paddingBottom: ED_TAB_HEIGHT + 16 }}>
        {/* What you used */}
        <EDEyebrow style={{ marginBottom: 8 }}>What you swiped</EDEyebrow>
        <EDSurface style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 14 }}>
          <EDCardArt card={usedCard} w={100} h={64}/>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 16, fontWeight: 700, color: ED_FOREST }}>{usedCard.short}</div>
            <div style={{ fontSize: 13, color: ED_FG3, marginTop: 2 }}>{opt.usedX}× · earned ${opt.usedEarn.toFixed(2)}</div>
          </div>
        </EDSurface>

        {/* What you should have used */}
        {!opt.isOptimal && (
          <>
            <EDEyebrow color={ED_DANGER} style={{ marginBottom: 8 }}>The better card</EDEyebrow>
            <EDSurface style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 24, background: ED_DANGER_BG_SUBTLE, borderColor: ED_DANGER_BORDER }}>
              <EDCardArt card={opt.optimal} w={100} h={64}/>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 16, fontWeight: 700, color: ED_FOREST }}>{opt.optimal.short}</div>
                <div style={{ fontSize: 13, color: ED_DANGER, marginTop: 2, fontWeight: 600 }}>{opt.optimalX}× · would've earned ${opt.optimalEarn.toFixed(2)}</div>
              </div>
            </EDSurface>
          </>
        )}

        {/* Action */}
        <TxnActionButton onClick={() => onScreen("which")} icon="search">
          Find best card for {txn.category}
        </TxnActionButton>
        <TxnActionButton onClick={() => alert(`Report sent — we'll review the category for ${txn.merchant}.`)} icon="flag">
          Report wrong category
        </TxnActionButton>
        <TxnActionButton onClick={() => alert(`Set ${opt.optimal?.short || 'top card'} as default for ${txn.category}.`)} icon="repeat">
          Set as default for {txn.category}
        </TxnActionButton>
      </EDBody>
    </EDScreen>
  );
}

// Action-row button used inside ScrTxnDetail. SVG icon, consistent chrome.
function TxnActionButton({ onClick, icon, children }) {
  const icons = {
    search: <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><circle cx="11" cy="11" r="7" stroke={ED_FOREST} strokeWidth="1.8"/><path d="M16.5 16.5L21 21" stroke={ED_FOREST} strokeWidth="1.8" strokeLinecap="round"/></svg>,
    flag: <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M5 4v17M5 4h12l-2 4 2 4H5" stroke={ED_FOREST} strokeWidth="1.8" strokeLinejoin="round"/></svg>,
    repeat: <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M4 12a8 8 0 0114-5l2 2M4 12l2 2 2-2M20 12a8 8 0 01-14 5l-2-2M20 12l-2-2-2 2" stroke={ED_FOREST} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>,
  };
  return (
    <button onClick={onClick} style={{
      width: "100%", padding: "14px 18px", borderRadius: ED_R_BTN, border: `1px solid ${ED_LINE}`,
      background: "#fff", color: ED_FOREST, fontSize: 14, fontWeight: 600, cursor: "pointer", fontFamily: "inherit",
      textAlign: "left", display: "flex", alignItems: "center", gap: 12, marginBottom: 10,
    }}>
      <span style={{ display: "inline-flex", flexShrink: 0 }}>{icons[icon]}</span>
      <span style={{ flex: 1 }}>{children}</span>
      <span style={{ color: ED_FG3 }}>›</span>
    </button>
  );
}

// ──────────────────────────────────────────────────────────
// Email signup screen
// ──────────────────────────────────────────────────────────
function ScrEmailSignup({ onBack, onNext }) {
  const [email, setEmail] = React.useState("");
  const valid = /\S+@\S+\.\S+/.test(email);
  return (
    <EDScreen bg={ED_FOREST_900} dark>
      <EDHeader dark back={onBack} paddingBottom={0}/>
      <EDBody style={{ display: "flex", flexDirection: "column", justifyContent: "flex-end", paddingBottom: 16 }}>
        <h1 style={{ fontSize: 32, fontWeight: 800, lineHeight: 1.1, letterSpacing: "-0.025em", margin: 0, color: "#fff" }}>What's your email?</h1>
        <p style={{ marginTop: 14, fontSize: 14, color: "rgba(238,230,227,0.7)", lineHeight: 1.5 }}>We'll send a magic link. No passwords to remember, no spam.</p>
        <input
          type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@example.com" autoFocus
          style={{
            marginTop: 24, padding: "16px 18px", borderRadius: ED_R_BTN,
            border: `1px solid ${ED_ON_DARK_BORDER}`, background: "rgba(255,255,255,0.06)",
            color: "#fff", fontSize: 17, fontFamily: "inherit", outline: "none",
          }}/>
      </EDBody>
      <EDFooter dark>
        <EDPrimaryButton variant="dark" disabled={!valid} onClick={onNext}>Send magic link</EDPrimaryButton>
        <div style={{ textAlign: "center", fontSize: 12, color: "rgba(238,230,227,0.5)", marginTop: 4 }}>
          We never store your bank password.
        </div>
      </EDFooter>
    </EDScreen>
  );
}

// ──────────────────────────────────────────────────────────
// Offers screen (saved credits & perks)
// ──────────────────────────────────────────────────────────
function ScrOffers({ onBack }) {
  // Local override of "complete" status so the user can mark credits used in the prototype.
  const [usedIds, setUsedIds] = React.useState(() => new Set(ED_OFFERS.filter(o => o.complete).map(o => o.id)));
  const isComplete = (o) => usedIds.has(o.id) || o.complete;
  const markUsed = (id) => setUsedIds(prev => { const next = new Set(prev); next.add(id); return next; });
  const activeCount = ED_OFFERS.filter(o => !isComplete(o)).length;
  const urgentCount = ED_OFFERS.filter(o => o.urgent && !isComplete(o)).length;
  return (
    <EDScreen>
      <EDHeader
        back={onBack}
        eyebrow="Don't leave money on the table"
        title="Your credits"
        subtitle={`${activeCount} active · ${urgentCount} expiring soon`}
      />
      <EDBody style={{ paddingTop: 4, paddingBottom: ED_TAB_HEIGHT + 16, display: "flex", flexDirection: "column", gap: 10 }}>
        {ED_OFFERS.length === 0 && (
          <EDSurface style={{ padding: 24, textAlign: "center" }}>
            <div style={{ fontSize: 15, fontWeight: 600, color: ED_FOREST, marginBottom: 6 }}>No active credits</div>
            <div style={{ fontSize: 13, color: ED_FG3, lineHeight: 1.5 }}>We'll surface statement credits and card-linked offers here as they show up on your cards.</div>
          </EDSurface>
        )}
        {ED_OFFERS.map(o => {
          const card = ED_CARDS.find(c => c.id === o.card);
          const complete = isComplete(o);
          return (
            <EDSurface key={o.id} style={{ padding: 16, opacity: complete ? 0.55 : 1 }}>
              <div style={{ display: "flex", alignItems: "flex-start", gap: 12 }}>
                <div style={{
                  width: 48, height: 48, borderRadius: ED_R_ICON,
                  background: complete ? ED_BILL_BG : (o.urgent ? ED_DANGER_BG : ED_BILL_BG),
                  color: complete ? ED_BILL_700 : (o.urgent ? ED_DANGER : ED_BILL_700),
                  display: "flex", alignItems: "center", justifyContent: "center", fontSize: 22, flexShrink: 0, fontWeight: 800,
                }}>{complete ? "✓" : (o.value > 0 ? `$${o.value}` : "★")}</div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 15, fontWeight: 700, color: ED_FOREST, marginBottom: 2 }}>{o.merchant}</div>
                  <div style={{ fontSize: 13, color: ED_FG2, marginBottom: 8 }}>{o.desc}</div>
                  <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                    {card && <EDCardChip card={card} size={20}/>}
                    <span style={{ fontSize: 11, color: ED_FG3 }}>{card?.short}</span>
                    <span style={{ fontSize: 11, color: ED_FG3 }}>·</span>
                    <span style={{ fontSize: 11, fontWeight: 600, color: complete ? ED_BILL_700 : (o.urgent ? ED_DANGER : ED_FG3) }}>
                      {complete ? "Used" : `Expires ${o.expires}`}
                    </span>
                  </div>
                </div>
                {!complete && (
                  <EDPillButton tone="forest" size="sm" onClick={() => markUsed(o.id)}>Mark used</EDPillButton>
                )}
              </div>
            </EDSurface>
          );
        })}
      </EDBody>
    </EDScreen>
  );
}

// ──────────────────────────────────────────────────────────
// Refer-a-friend screen
// ──────────────────────────────────────────────────────────
function ScrReferral({ onBack }) {
  const [copied, setCopied] = React.useState(false);
  const code = "JORDAN5";
  const link = `extradollar.com/r/${code}`;
  return (
    <EDScreen>
      <EDHero back={onBack} paddingBottom={32}>
        <EDEyebrow color={ED_BILL} style={{ marginBottom: 12 }}>Refer a friend</EDEyebrow>
        <h1 style={{ margin: 0, fontSize: 32, fontWeight: 800, letterSpacing: "-0.025em", lineHeight: 1.05 }}>Both of you<br/>get $5.</h1>
        <p style={{ marginTop: 14, fontSize: 14, color: ED_ON_DARK_2, lineHeight: 1.5, maxWidth: 320 }}>
          When your friend signs up with your link and connects a card, $5 lands in both of your accounts. No cap, no catch.
        </p>
      </EDHero>

      <EDBody style={{ paddingTop: 20, paddingBottom: ED_TAB_HEIGHT + 16 }}>
        <EDEyebrow style={{ marginBottom: 8 }}>Your link</EDEyebrow>
        <div style={{ background: "#fff", border: `1px solid ${ED_LINE}`, borderRadius: ED_R_BTN, padding: "12px 16px", display: "flex", alignItems: "center", gap: 10 }}>
          <div style={{ flex: 1, fontSize: 14, color: ED_FOREST, fontFeatureSettings: '"tnum"', overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{link}</div>
          <EDPillButton
            tone={copied ? "bill" : "forest"} size="sm"
            onClick={() => { setCopied(true); setTimeout(() => setCopied(false), 1600); }}
          >{copied ? "Copied" : "Copy"}</EDPillButton>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8, marginTop: 14 }}>
          {[
            { id: "email", label: "Email", svg: <svg width="20" height="20" viewBox="0 0 24 24" fill="none"><rect x="3" y="6" width="18" height="12" rx="2" stroke={ED_FOREST} strokeWidth="1.6"/><path d="M3 8l9 6 9-6" stroke={ED_FOREST} strokeWidth="1.6" strokeLinejoin="round"/></svg>,
              action: () => { window.location.href = `mailto:?subject=Try Extra Dollar&body=I've been using Extra Dollar to maximize card rewards. Use my link for $5: ${link}`; } },
            { id: "messages", label: "Messages", svg: <svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M3 7a3 3 0 013-3h12a3 3 0 013 3v8a3 3 0 01-3 3H9l-4 4v-4a3 3 0 01-2-3V7z" stroke={ED_FOREST} strokeWidth="1.6" strokeLinejoin="round"/></svg>,
              action: () => { window.location.href = `sms:?body=Try Extra Dollar — use my link for $5: ${link}`; } },
            { id: "share",  label: "Share",    svg: <svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M12 3v12M12 3l-4 4M12 3l4 4M5 14v4a2 2 0 002 2h10a2 2 0 002-2v-4" stroke={ED_FOREST} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>,
              action: async () => {
                if (navigator.share) {
                  try { await navigator.share({ title: "Extra Dollar", text: "Try Extra Dollar — use my link for $5", url: `https://${link}` }); }
                  catch {}
                } else {
                  navigator.clipboard?.writeText(`https://${link}`);
                  setCopied(true); setTimeout(() => setCopied(false), 1600);
                }
              } },
          ].map(s => (
            <button key={s.id} onClick={s.action} style={{
              background: "#fff", border: `1px solid ${ED_LINE}`, borderRadius: ED_R_ICON, padding: "14px 8px",
              display: "flex", flexDirection: "column", alignItems: "center", gap: 6, cursor: "pointer", fontFamily: "inherit",
            }}>
              <span style={{ display: "inline-flex" }}>{s.svg}</span>
              <span style={{ fontSize: 12, fontWeight: 600, color: ED_FOREST }}>{s.label}</span>
            </button>
          ))}
        </div>

        <EDSurface style={{ marginTop: 24 }}>
          <div style={{ fontSize: 13, fontWeight: 700, color: ED_FOREST, marginBottom: 12 }}>Your earnings</div>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 4 }}>
            <span style={{ fontSize: 12, color: ED_FG3 }}>Friends invited</span>
            <span style={{ fontSize: 14, fontWeight: 700, color: ED_FOREST }}>3</span>
          </div>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 4 }}>
            <span style={{ fontSize: 12, color: ED_FG3 }}>Activated</span>
            <span style={{ fontSize: 14, fontWeight: 700, color: ED_FOREST }}>2</span>
          </div>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", paddingTop: 8, borderTop: `1px solid ${ED_LINE}`, marginTop: 8 }}>
            <span style={{ fontSize: 13, color: ED_FG2, fontWeight: 600 }}>Earned</span>
            <span style={{ fontSize: 18, fontWeight: 800, color: ED_BILL_700, fontFeatureSettings: '"tnum"' }}>$10.00</span>
          </div>
        </EDSurface>
      </EDBody>
    </EDScreen>
  );
}

// ──────────────────────────────────────────────────────────
// Subscription paywall (Premium / Lifetime upgrade)
// Real Stripe/StoreKit billing is a future integration; this surfaces the value prop.
// ──────────────────────────────────────────────────────────
function ScrUpgrade({ onBack }) {
  const [tier, setTier] = React.useState("annual");
  const tiers = [
    { id: "monthly", label: "Monthly", price: "$9.99", per: "/ mo", note: "Cancel anytime" },
    { id: "annual",  label: "Annual",  price: "$59.99", per: "/ yr", note: "Save 50% · Most popular", highlight: true },
    { id: "life",    label: "Lifetime", price: "$199", per: "one-time", note: "Pay once. Yours forever." },
  ];
  const features = [
    { title: "Money Left on the Table", body: "Plaid-connected retrospective insights. We score every swipe." },
    { title: "Unlimited cards", body: "Track your whole wallet (free tier capped at 3 cards)." },
    { title: "Location-based recommendations", body: "Nearby merchant alerts before you tap." },
    { title: "Benefit & credit tracking", body: "Never let a $10 statement credit expire again." },
    { title: "Welcome bonus tracking", body: "Stay on pace for every new-card bonus." },
    { title: "All push notifications", body: "Annual fee renewals, weekly digest, missed-savings alerts." },
  ];
  return (
    <EDScreen>
      <EDHero back={onBack} paddingBottom={24}>
        <EDEyebrow color={ED_BILL} style={{ marginBottom: 8 }}>Extra Dollar Premium</EDEyebrow>
        <h1 style={{ margin: 0, fontSize: 32, fontWeight: 800, letterSpacing: "-0.025em", lineHeight: 1.05 }}>
          Stop swiping<br/>the wrong card.
        </h1>
        <p style={{ marginTop: 14, fontSize: 14, color: ED_ON_DARK_2, lineHeight: 1.5, maxWidth: 320 }}>
          Members find an average of <b style={{ color: "#fff" }}>$58/mo</b> in missed rewards in their first 90 days.
        </p>
      </EDHero>

      <EDBody style={{ paddingTop: 18, paddingBottom: 16 }}>
        <EDSection eyebrow="Pick your plan" title="Choose a tier">
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {tiers.map(t => {
              const on = tier === t.id;
              return (
                <button key={t.id} onClick={() => setTier(t.id)} style={{
                  textAlign: "left", padding: 16, borderRadius: ED_R_SURFACE,
                  background: "#fff",
                  border: on ? `2px solid ${ED_FOREST}` : `1px solid ${ED_LINE}`,
                  cursor: "pointer", fontFamily: "inherit",
                  display: "flex", alignItems: "center", gap: 12,
                  position: "relative",
                }}>
                  <div style={{
                    width: 22, height: 22, borderRadius: "50%",
                    background: on ? ED_FOREST : "transparent",
                    border: on ? "none" : `2px solid rgba(6,57,50,0.2)`,
                    display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
                  }}>
                    {on && <svg width="11" height="11" viewBox="0 0 14 14"><path d="M2 7l3.5 3.5L12 3.5" stroke="#fff" strokeWidth="2.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>}
                  </div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 15, fontWeight: 700, color: ED_FOREST }}>{t.label}</div>
                    <div style={{ fontSize: 12, color: t.highlight ? ED_BILL_700 : ED_FG3, fontWeight: t.highlight ? 700 : 500 }}>{t.note}</div>
                  </div>
                  <div style={{ textAlign: "right", fontFeatureSettings: '"tnum"' }}>
                    <div style={{ fontSize: 20, fontWeight: 800, color: ED_FOREST, letterSpacing: "-0.02em" }}>{t.price}</div>
                    <div style={{ fontSize: 11, color: ED_FG3 }}>{t.per}</div>
                  </div>
                </button>
              );
            })}
          </div>
        </EDSection>

        <EDSection eyebrow="What's included" title="Premium unlocks">
          <EDSurface padded={false}>
            {features.map((f, i) => (
              <div key={i} style={{ padding: 14, display: "flex", alignItems: "flex-start", gap: 12, borderBottom: i < features.length - 1 ? `1px solid ${ED_LINE}` : "none" }}>
                <div style={{ width: 28, height: 28, borderRadius: ED_R_ICON, background: ED_BILL_BG, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
                  <svg width="14" height="14" viewBox="0 0 14 14"><path d="M2 7l3.5 3.5L12 3.5" stroke={ED_BILL_700} strokeWidth="2.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 14, fontWeight: 700, color: ED_FOREST }}>{f.title}</div>
                  <div style={{ fontSize: 12, color: ED_FG2, marginTop: 2, lineHeight: 1.5 }}>{f.body}</div>
                </div>
              </div>
            ))}
          </EDSurface>
        </EDSection>
      </EDBody>

      <EDFooter>
        <EDPrimaryButton onClick={onBack}>Start 7-day free trial</EDPrimaryButton>
        <div style={{ textAlign: "center", fontSize: 11, color: ED_FG3, marginTop: 4, lineHeight: 1.5 }}>
          Billing via Apple. Cancel anytime in Settings. Subject to App Store terms.
        </div>
      </EDFooter>
    </EDScreen>
  );
}

// ──────────────────────────────────────────────────────────
// Plaid management — view / disconnect connected institutions
// Real Plaid integration is future; this mocks the connected-items list.
// ──────────────────────────────────────────────────────────
function ScrPlaidManage({ onBack }) {
  const [items, setItems] = React.useState([
    { id: "chase", name: "Chase", logo: "C", color: "#117ACA", accounts: 4, status: "Connected", lastSync: "2m ago" },
  ]);
  const [confirmId, setConfirmId] = React.useState(null);
  const disconnect = (id) => { setItems(items.filter(i => i.id !== id)); setConfirmId(null); };
  return (
    <EDScreen>
      <EDHeader back={onBack} eyebrow="Privacy & data" title="Connected banks"
        subtitle="Manage the institutions Extra Dollar reads transactions from."/>
      <EDBody>
        {items.length === 0 ? (
          <EDSurface style={{ padding: 24, textAlign: "center" }}>
            <div style={{ fontSize: 15, fontWeight: 600, color: ED_FOREST, marginBottom: 6 }}>No banks connected</div>
            <div style={{ fontSize: 13, color: ED_FG3, lineHeight: 1.5 }}>
              You're using manual-card mode. Connect a bank to unlock retrospective insights.
            </div>
          </EDSurface>
        ) : (
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            {items.map(item => (
              <EDSurface key={item.id}>
                <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 10 }}>
                  <div style={{ width: 44, height: 44, borderRadius: ED_R_ICON, background: item.color, color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 800, fontSize: 18, flexShrink: 0 }}>{item.logo}</div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 16, fontWeight: 700, color: ED_FOREST }}>{item.name}</div>
                    <div style={{ fontSize: 12, color: ED_FG3 }}>{item.accounts} accounts · last sync {item.lastSync}</div>
                  </div>
                  <span style={{ fontSize: 11, fontWeight: 700, color: ED_BILL_700, background: ED_BILL_BG, padding: "4px 8px", borderRadius: ED_R_PILL, letterSpacing: "0.04em", textTransform: "uppercase" }}>{item.status}</span>
                </div>
                {confirmId === item.id ? (
                  <div style={{ background: ED_DANGER_BG_SUBTLE, padding: 12, borderRadius: ED_R_BTN, border: `1px solid ${ED_DANGER_BORDER}` }}>
                    <div style={{ fontSize: 13, color: ED_DANGER, fontWeight: 600, marginBottom: 8 }}>
                      Disconnect {item.name}? You'll lose retrospective insights for these accounts.
                    </div>
                    <div style={{ display: "flex", gap: 8 }}>
                      <EDPillButton tone="ghost" onClick={() => setConfirmId(null)} style={{ flex: 1, color: ED_FG2 }}>Cancel</EDPillButton>
                      <EDPillButton onClick={() => disconnect(item.id)} style={{ flex: 1, background: ED_DANGER, color: "#fff" }}>Disconnect</EDPillButton>
                    </div>
                  </div>
                ) : (
                  <div style={{ display: "flex", gap: 8 }}>
                    <EDPillButton tone="ghost" size="sm" onClick={() => alert("Re-link flow — coming soon")} style={{ flex: 1 }}>Re-link</EDPillButton>
                    <EDPillButton tone="ghost" size="sm" onClick={() => setConfirmId(item.id)} style={{ flex: 1, color: ED_DANGER }}>Disconnect</EDPillButton>
                  </div>
                )}
              </EDSurface>
            ))}
          </div>
        )}
      </EDBody>
      <EDFooter>
        <EDSecondaryButton onClick={() => alert("Plaid Link flow — coming soon")}>+ Connect another bank</EDSecondaryButton>
      </EDFooter>
    </EDScreen>
  );
}

// ──────────────────────────────────────────────────────────
// Annual fee renewal decision (PRD §4 journey 5)
// ──────────────────────────────────────────────────────────
function ScrRenewalDecision({ card, onBack }) {
  const c = card || ED_CARDS[0];
  const annualFee = c.annualFee || 95;
  const earnedYTD = 247;
  const creditsUsed = 60;
  const benefitsUsed = 30;
  const totalValue = earnedYTD + creditsUsed + benefitsUsed;
  const netValue = totalValue - annualFee;
  const isWorth = netValue > 0;
  return (
    <EDScreen>
      <EDHero back={onBack} bg={c.color} decorative={false} paddingBottom={32}>
        <EDEyebrow color={c.accent} style={{ opacity: 0.7, marginBottom: 8 }}>Annual fee renews in 47 days</EDEyebrow>
        <h1 style={{ margin: 0, fontSize: 28, fontWeight: 800, letterSpacing: "-0.025em", lineHeight: 1.1, color: "#fff" }}>{c.issuer} {c.name}</h1>
        <div style={{ marginTop: 18, display: "flex", alignItems: "baseline", gap: 8 }}>
          <span style={{ fontSize: 13, color: c.accent, opacity: 0.7 }}>Net value this year</span>
          <span style={{ fontSize: 28, fontWeight: 800, color: isWorth ? "#a3e29d" : "#ffb29c", fontFeatureSettings: '"tnum"', letterSpacing: "-0.02em" }}>
            {isWorth ? "+" : "−"}${Math.abs(netValue).toFixed(2)}
          </span>
        </div>
      </EDHero>
      <EDBody style={{ paddingTop: 18 }}>
        <EDSection eyebrow="The math" title="What you got vs. what it cost">
          <EDSurface>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "8px 0" }}>
              <div style={{ color: ED_FG2 }}>Annual fee</div>
              <div style={{ fontWeight: 700, color: ED_DANGER, fontFeatureSettings: '"tnum"' }}>−${annualFee}</div>
            </div>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "8px 0", borderTop: `1px solid ${ED_LINE}` }}>
              <div style={{ color: ED_FG2 }}>Rewards earned YTD</div>
              <div style={{ fontWeight: 700, color: ED_BILL_700, fontFeatureSettings: '"tnum"' }}>+${earnedYTD}</div>
            </div>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "8px 0", borderTop: `1px solid ${ED_LINE}` }}>
              <div style={{ color: ED_FG2 }}>Credits used</div>
              <div style={{ fontWeight: 700, color: ED_BILL_700, fontFeatureSettings: '"tnum"' }}>+${creditsUsed}</div>
            </div>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "8px 0", borderTop: `1px solid ${ED_LINE}` }}>
              <div style={{ color: ED_FG2 }}>Benefits used (lounge, insurance)</div>
              <div style={{ fontWeight: 700, color: ED_BILL_700, fontFeatureSettings: '"tnum"' }}>+${benefitsUsed}</div>
            </div>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "12px 0 4px", borderTop: `2px solid ${ED_FOREST}`, marginTop: 8 }}>
              <div style={{ fontWeight: 800, color: ED_FOREST }}>Net value</div>
              <div style={{ fontWeight: 800, color: isWorth ? ED_BILL_700 : ED_DANGER, fontFeatureSettings: '"tnum"', fontSize: 18 }}>
                {isWorth ? "+" : "−"}${Math.abs(netValue).toFixed(2)}
              </div>
            </div>
          </EDSurface>
        </EDSection>
        <EDSection eyebrow="Decide" title="What do you want to do?">
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            <button onClick={() => alert("Marked: keep the card")} style={{
              textAlign: "left", padding: 16, borderRadius: ED_R_SURFACE, background: "#fff",
              border: `2px solid ${ED_BILL_700}`, cursor: "pointer", fontFamily: "inherit",
            }}>
              <div style={{ fontSize: 15, fontWeight: 700, color: ED_FOREST, marginBottom: 2 }}>Keep — pay the fee</div>
              <div style={{ fontSize: 12, color: ED_FG3 }}>Worth it based on your usage. We'll remind you again next year.</div>
            </button>
            <button onClick={() => alert("Product change request — pretend we filed it")} style={{
              textAlign: "left", padding: 16, borderRadius: ED_R_SURFACE, background: "#fff",
              border: `1px solid ${ED_LINE}`, cursor: "pointer", fontFamily: "inherit",
            }}>
              <div style={{ fontSize: 15, fontWeight: 700, color: ED_FOREST, marginBottom: 2 }}>Product change to a no-fee card</div>
              <div style={{ fontSize: 12, color: ED_FG3 }}>Keep the credit history; drop the annual fee.</div>
            </button>
            <button onClick={() => alert("Cancel intent recorded")} style={{
              textAlign: "left", padding: 16, borderRadius: ED_R_SURFACE, background: "#fff",
              border: `1px solid ${ED_LINE}`, cursor: "pointer", fontFamily: "inherit",
            }}>
              <div style={{ fontSize: 15, fontWeight: 700, color: ED_DANGER, marginBottom: 2 }}>Cancel the card</div>
              <div style={{ fontSize: 12, color: ED_FG3 }}>We'll walk you through retention offers first.</div>
            </button>
          </div>
        </EDSection>
      </EDBody>
    </EDScreen>
  );
}

// ──────────────────────────────────────────────────────────
// Legal screen — Privacy / Terms / Security disclosure
// ──────────────────────────────────────────────────────────
function ScrLegal({ onBack }) {
  return (
    <EDScreen>
      <EDHeader back={onBack} eyebrow="Privacy & legal" title="Legal"
        subtitle="The fine print, in plain language."/>
      <EDBody style={{ paddingBottom: 24 }}>
        <EDSection eyebrow="What you sign" title="Documents">
          <EDSurface padded={false}>
            {[
              { label: "Privacy Policy", sub: "What we store, how long, who we share with" },
              { label: "Terms of Service", sub: "Your subscription terms and acceptable use" },
              { label: "Security disclosures", sub: "How we protect your data" },
              { label: "Plaid disclosure", sub: "How bank-connected data is used" },
            ].map((d, i, arr) => (
              <button key={d.label} onClick={() => alert(`Open: ${d.label}`)} style={{
                width: "100%", padding: 16, background: "transparent", border: "none",
                display: "flex", alignItems: "center", gap: 12, cursor: "pointer",
                textAlign: "left", fontFamily: "inherit",
                borderBottom: i < arr.length - 1 ? `1px solid ${ED_LINE}` : "none",
              }}>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 15, fontWeight: 600, color: ED_FOREST }}>{d.label}</div>
                  <div style={{ fontSize: 12, color: ED_FG3, marginTop: 2 }}>{d.sub}</div>
                </div>
                <span style={{ color: ED_BILL_700, fontWeight: 600, fontSize: 13 }}>View ›</span>
              </button>
            ))}
          </EDSurface>
        </EDSection>
        <div style={{ fontSize: 12, color: ED_FG3, lineHeight: 1.55, marginTop: 14 }}>
          <b style={{ color: ED_FOREST }}>The short version:</b> we never sell your data, never train AI on your bank
          transactions, and never share with third parties beyond what's required to deliver the
          service. You can delete your account at any time and we'll process the request within
          30 days.
        </div>
      </EDBody>
    </EDScreen>
  );
}

// ──────────────────────────────────────────────────────────
// Data export
// ──────────────────────────────────────────────────────────
function ScrDataExport({ onBack }) {
  const [requested, setRequested] = React.useState(false);
  return (
    <EDScreen>
      <EDHeader back={onBack} eyebrow="Privacy & data" title="Export your data"
        subtitle="Get a downloadable archive of everything we have on you."/>
      <EDBody>
        <EDSurface>
          <div style={{ fontSize: 14, fontWeight: 700, color: ED_FOREST, marginBottom: 8 }}>What's included</div>
          <ul style={{ margin: 0, padding: "0 0 0 18px", fontSize: 13, color: ED_FG2, lineHeight: 1.7 }}>
            <li>Your profile + sign-in history</li>
            <li>Card portfolio (issuer, name, last 4, dates)</li>
            <li>All transactions ingested via Plaid (last 24 months)</li>
            <li>All optimization scores + missed-savings calculations</li>
            <li>Notification log (last 90 days)</li>
            <li>Subscription + billing history</li>
          </ul>
        </EDSurface>
        <div style={{ fontSize: 12, color: ED_FG3, lineHeight: 1.5, marginTop: 14 }}>
          We send the archive as a JSON + CSV bundle to your registered email. Most users get
          theirs in under 5 minutes; complex accounts can take up to 24 hours.
        </div>
      </EDBody>
      <EDFooter>
        {requested ? (
          <div style={{ background: ED_BILL_BG, color: ED_BILL_700, padding: 14, borderRadius: ED_R_BTN, textAlign: "center", fontWeight: 700, fontSize: 14 }}>
            ✓ Request received. We'll email you when it's ready.
          </div>
        ) : (
          <EDPrimaryButton onClick={() => setRequested(true)}>Request export</EDPrimaryButton>
        )}
      </EDFooter>
    </EDScreen>
  );
}

// ──────────────────────────────────────────────────────────
// Account deletion (GDPR / CCPA)
// ──────────────────────────────────────────────────────────
function ScrDeleteAccount({ onBack, onConfirm }) {
  const [confirmText, setConfirmText] = React.useState("");
  const ready = confirmText.toUpperCase() === "DELETE";
  return (
    <EDScreen>
      <EDHeader back={onBack} eyebrow="This can't be undone" title="Delete account"/>
      <EDBody>
        <div style={{ background: ED_DANGER_BG_SUBTLE, border: `1px solid ${ED_DANGER_BORDER}`, borderRadius: ED_R_SURFACE, padding: 16, marginBottom: 14 }}>
          <div style={{ fontSize: 13, fontWeight: 700, color: ED_DANGER, marginBottom: 8 }}>What happens when you delete:</div>
          <ul style={{ margin: 0, padding: "0 0 0 18px", fontSize: 13, color: ED_FG2, lineHeight: 1.6 }}>
            <li>All Plaid connections are immediately disconnected</li>
            <li>Your transactions, optimizations, and notifications are erased</li>
            <li>Your subscription is cancelled (no refund for current period)</li>
            <li>Your account record is purged within 30 days</li>
          </ul>
        </div>
        <div style={{ fontSize: 13, color: ED_FG2, lineHeight: 1.55, marginBottom: 14 }}>
          If you'd rather keep your data but pause notifications, you can <b style={{ color: ED_FOREST }}>turn them off in settings</b> instead.
        </div>
        <Field label="Type DELETE to confirm" value={confirmText} onChange={setConfirmText} placeholder="DELETE"/>
      </EDBody>
      <EDFooter>
        <EDPrimaryButton disabled={!ready} onClick={onConfirm} style={{ background: ready ? ED_DANGER : undefined, color: "#fff" }}>
          Permanently delete my account
        </EDPrimaryButton>
        <EDSecondaryButton onClick={onBack}>Cancel — go back</EDSecondaryButton>
      </EDFooter>
    </EDScreen>
  );
}

Object.assign(window, {
  ScrProfile, ScrNotifications, ScrPayConfirm, ScrAddCard, ScrTxnDetail, ScrEmailSignup, ScrOffers, ScrReferral,
  ScrUpgrade, ScrPlaidManage, ScrRenewalDecision, ScrLegal, ScrDataExport, ScrDeleteAccount,
});
