function SendEmailModal({ to, onClose }) {
  // `to` is an array of { email, name } objects
  const [from, setFrom] = React.useState("Talio <hello@talio.fun>");
  const [subject, setSubject] = React.useState("");
  const [body, setBody] = React.useState("");
  const [sending, setSending] = React.useState(false);
  const [result, setResult] = React.useState(null); // { ok, message }

  const send = async () => {
    if (!subject.trim() || !body.trim()) return;
    setSending(true);
    setResult(null);
    try {
      const res = await fetch("http://localhost:3099/emails", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          from,
          to: to.map(u => u.name ? `${u.name} <${u.email}>` : u.email),
          subject,
          html: body.replace(/\n/g, "<br/>"),
        }),
      });
      const data = await res.json();
      if (res.ok) {
        setResult({ ok: true, message: `Sent to ${to.length} recipient${to.length > 1 ? "s" : ""}` });
      } else {
        setResult({ ok: false, message: data.message || data.error || "Send failed" });
      }
    } catch (e) {
      setResult({ ok: false, message: e.message });
    } finally {
      setSending(false);
    }
  };

  const inputStyle = { width: "100%", marginTop: 6, padding: "8px 12px", background: "var(--bg-elev)", border: "1px solid var(--border)", borderRadius: 8, color: "var(--ink)", fontSize: 13, fontFamily: "inherit" };

  return (
    <>
      <div className="drawer-backdrop" onClick={onClose}/>
      <div className="drawer" style={{ width: "min(560px, 95vw)" }}>
        <header>
          <Icon.mail size={16}/>
          <div style={{ fontWeight: 600, marginLeft: 8 }}>
            Send Email
            <span className="muted" style={{ fontWeight: 400, fontSize: 12, marginLeft: 8 }}>
              to {to.length === 1 ? to[0].name || to[0].email : `${to.length} users`}
            </span>
          </div>
          <div className="spacer"/>
          <button className="btn ghost icon sm" onClick={onClose}><Icon.close size={14}/></button>
        </header>

        <div className="body" style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <div>
            <label style={{ fontSize: 11, fontWeight: 500, color: "var(--ink-2)", textTransform: "uppercase", letterSpacing: ".05em" }}>From</label>
            <input style={inputStyle} value={from} onChange={e => setFrom(e.target.value)} placeholder="Name <email@domain.com>"/>
          </div>
          <div>
            <label style={{ fontSize: 11, fontWeight: 500, color: "var(--ink-2)", textTransform: "uppercase", letterSpacing: ".05em" }}>To</label>
            <div style={{ marginTop: 6, padding: "8px 12px", background: "var(--bg-soft)", border: "1px solid var(--border)", borderRadius: 8, fontSize: 12, color: "var(--ink-2)", lineHeight: 1.6 }}>
              {to.map((u, i) => (
                <span key={i} style={{ display: "inline-block", background: "var(--bg-elev)", border: "1px solid var(--border)", borderRadius: 4, padding: "1px 7px", margin: "2px 3px", fontSize: 11 }}>
                  {u.name ? `${u.name} <${u.email}>` : u.email}
                </span>
              ))}
            </div>
          </div>
          <div>
            <label style={{ fontSize: 11, fontWeight: 500, color: "var(--ink-2)", textTransform: "uppercase", letterSpacing: ".05em" }}>Subject</label>
            <input style={inputStyle} value={subject} onChange={e => setSubject(e.target.value)} placeholder="Your email subject…"/>
          </div>
          <div>
            <label style={{ fontSize: 11, fontWeight: 500, color: "var(--ink-2)", textTransform: "uppercase", letterSpacing: ".05em" }}>Message</label>
            <textarea style={{ ...inputStyle, minHeight: 180, resize: "vertical" }} value={body} onChange={e => setBody(e.target.value)} placeholder="Write your message here. Line breaks become <br> tags."/>
          </div>

          {result && (
            <div style={{ padding: "10px 14px", borderRadius: 8, background: result.ok ? "var(--accent-soft)" : "oklch(0.97 0.03 20)", color: result.ok ? "var(--accent-ink)" : "var(--red)", fontSize: 13, fontWeight: 500 }}>
              {result.ok ? <><Icon.check size={13}/> {result.message}</> : <><Icon.flag size={13}/> {result.message}</>}
            </div>
          )}
        </div>

        <footer>
          <button className="btn ghost sm" onClick={onClose}>Cancel</button>
          <div className="spacer"/>
          <button className="btn accent sm" onClick={send} disabled={sending || !subject.trim() || !body.trim()}>
            {sending ? <><span className="pulse" style={{ width: 7, height: 7, borderRadius: "50%", background: "white", display: "inline-block" }}/> Sending…</> : <><Icon.mail size={12}/> Send</>}
          </button>
        </footer>
      </div>
    </>
  );
}

function SortTh({ label, col, sort, setSort, align }) {
  const active = sort === col;
  return (
    <th style={{textAlign: align || "left", cursor:"pointer", userSelect:"none", whiteSpace:"nowrap",
                color: active ? "var(--ink)" : "var(--ink-3)"}}
        onClick={() => setSort(col)}>
      {label}
      <span style={{marginLeft:4, fontSize:9, verticalAlign:"middle",
                    opacity: active ? 1 : 0, transition:"opacity .15s"}}>▼</span>
    </th>
  );
}

function PageUsers({ onOpenUser }) {
  const [search, setSearch] = React.useState("");
  const [plan, setPlan] = React.useState("all");
  const [platform, setPlatform] = React.useState("all");
  const [sort, setSort] = React.useState("active");
  const [selected, setSelected] = React.useState(new Set());
  const [openUser, setOpenUser] = React.useState(null);
  const [emailTarget, setEmailTarget] = React.useState(null);

  React.useEffect(() => {
    const handler = e => setOpenUser(e.detail);
    window.addEventListener("adminOpenUser", handler);
    return () => window.removeEventListener("adminOpenUser", handler);
  }, []);

  const filtered = USERS.filter(u => {
    if (search) {
      const q = search.toLowerCase();
      const haystack = `${u.name||""} ${u.email||""} ${u.uid||""} ${u.childName||""}`.toLowerCase();
      if (!haystack.includes(q)) return false;
    }
    if (plan !== "all" && u.plan !== plan) return false;
    if (platform !== "all" && u.platform !== platform) return false;
    return true;
  }).sort((a,b) => {
    if (sort === "stories") return (b.stories ?? 0) - (a.stories ?? 0);
    if (sort === "credits") return (b.credits ?? 0) - (a.credits ?? 0);
    if (sort === "signup")  return (b.signup || "").localeCompare(a.signup || "");
    if (sort === "active")  return (b.lastActive || "").localeCompare(a.lastActive || "");
    return 0;
  }).slice(0, 80);

  return (
    <>
      <div className="page-header">
        <div><h1>Users</h1><div className="sub">{KPIS.users.toLocaleString()} total · {compact(KPIS.dau)} active today</div></div>
        <div className="actions">
          <button className="btn sm"><Icon.download size={12}/> Export CSV</button>
          <button className="btn primary sm"><Icon.userPlus size={12}/> Invite admin</button>
        </div>
      </div>

      <div className="kpi-grid">
        <KPI label="New this week"  value={compact(KPIS.users)} delta={KPIS.usersDelta} spark={SIGNUPS_SERIES.slice(-14)} sparkColor="var(--plum)"/>
        <KPI label="Paying users"   value={compact(KPIS.activeSubs)} delta={null}/>
        <KPI label="Trial → Paid"   value={KPIS.trialConv || "—"} unit={KPIS.trialConv ? "%" : ""} delta={null}/>
        <KPI label="ARPU"           value={money(KPIS.arpu)} delta={KPIS.arpuDelta}/>
      </div>

      <div className="card">
        <div className="toolbar">
          <div className="input search" style={{flex:1, maxWidth:340}}>
            <Icon.search size={13}/>
            <input placeholder="Search by name, email, UID…" value={search} onChange={e=>setSearch(e.target.value)}/>
          </div>
          <div className="input">
            <span className="muted">Plan:</span>
            <select value={plan} onChange={e=>setPlan(e.target.value)}>
              <option value="all">All</option>
              {PLANS.map(p=><option key={p.id} value={p.id}>{p.name}</option>)}
            </select>
          </div>
          <div className="input">
            <span className="muted">Platform:</span>
            <select value={platform} onChange={e=>setPlatform(e.target.value)}>
              <option value="all">All</option>
              <option value="ios">iOS</option>
              <option value="android">Android</option>
              <option value="web">Web</option>
            </select>
          </div>
          <div className="spacer"/>
          {selected.size > 0 && (
            <>
              <span className="muted" style={{fontSize:12}}>{selected.size} selected</span>
              <button className="btn sm"><Icon.coin size={12}/> Grant credits</button>
              <button className="btn sm" onClick={() => {
                const targets = filtered.filter(u => selected.has(u.uid)).map(u => ({ email: u.email, name: u.name }));
                setEmailTarget(targets);
              }}><Icon.mail size={12}/> Email</button>
              <button className="btn danger sm"><Icon.x size={12}/> Suspend</button>
            </>
          )}
        </div>
        <div className="table-wrap">
          <table className="tbl">
            <thead>
              <tr>
                <th style={{width:30}}><input type="checkbox" onChange={e=>setSelected(e.target.checked ? new Set(filtered.map(u=>u.uid)) : new Set())}/></th>
                <th>User</th>
                <th>Kid's name</th>
                <th>Plan</th>
                <th>Signed in via</th>
                <SortTh label="Credits" col="credits" sort={sort} setSort={setSort} align="right"/>
                <SortTh label="Stories" col="stories" sort={sort} setSort={setSort} align="right"/>
                <SortTh label="Last active" col="active" sort={sort} setSort={setSort}/>
                <SortTh label="Signup" col="signup" sort={sort} setSort={setSort}/>
                <th style={{width:40}}></th>
              </tr>
            </thead>
            <tbody>
              {filtered.length === 0 && (
                <tr><td colSpan={11}><EmptyState icon="users" message="No users yet" sub="Users will appear here once they sign up for Talio"/></td></tr>
              )}
              {filtered.map(u => (
                <tr key={u.uid || u.id} onClick={()=>setOpenUser(u)}>
                  <td onClick={e=>e.stopPropagation()}>
                    <input type="checkbox" checked={selected.has(u.uid || u.id)}
                      onChange={e=>{
                        const s = new Set(selected);
                        const key = u.uid || u.id;
                        e.target.checked ? s.add(key) : s.delete(key);
                        setSelected(s);
                      }}/>
                  </td>
                  <td><UserCell user={u}/></td>
                  <td className="muted">{u.childName || "—"}</td>
                  <td><PlanBadge plan={u.plan}/></td>
                  <td><ProviderBadge provider={u.provider}/></td>
                  <td className="num">{u.plan==="unlimited"?"∞":u.credits}</td>
                  <td className="num">{u.stories}</td>
                  <td className="muted">{fmtRelative(u.lastActive)}</td>
                  <td className="muted">{fmtDate(u.signup)}</td>
                  <td><button className="btn ghost icon sm" onClick={e=>{e.stopPropagation(); setOpenUser(u);}}><Icon.chevRight size={13}/></button></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        <div style={{padding:"10px 14px", display:"flex", alignItems:"center", color:"var(--ink-3)", fontSize:12, borderTop:"1px solid var(--border)"}}>
          Showing {filtered.length} of {KPIS.users.toLocaleString()} users
          <div className="spacer"/>
          <button className="btn ghost sm"><Icon.chevLeft size={12}/></button>
          <span className="mono" style={{margin:"0 8px"}}>Showing {Math.min(filtered.length, 80)} of {KPIS.users}</span>
          <button className="btn ghost sm"><Icon.chevRight size={12}/></button>
        </div>
      </div>

      <UserDrawer user={openUser} onClose={()=>setOpenUser(null)} onEmail={u => setEmailTarget([{ email: u.email, name: u.name }])}/>
      {emailTarget && <SendEmailModal to={emailTarget} onClose={() => setEmailTarget(null)}/>}
    </>
  );
}

function UserDrawer({ user, onClose, onEmail }) {
  if (!user) return null;
  const userStories = STORIES.filter(s => (s.userId || s.user?.uid) === user.uid).slice(0,4);
  const userTx = TRANSACTIONS.filter(t => t.user.uid === user.uid).slice(0,6);
  const [tab, setTab] = React.useState("profile");

  return (
    <>
      <div className="drawer-backdrop" onClick={onClose}/>
      <div className="drawer">
        <header>
          <div className="avatar" style={{width:32, height:32, fontSize:12}}>{(user.name||user.email||user.uid||"?").split(/[\s@]/).filter(Boolean).map(n=>n[0]).slice(0,2).join('').toUpperCase()}</div>
          <div style={{minWidth:0}}>
            <div style={{fontWeight:600}}>{user.name || user.email || "Guest"}</div>
            <div className="muted" style={{fontSize:11, fontFamily:"var(--mono)"}}>{user.uid}</div>
          </div>
          <div className="spacer"/>
          <button className="btn ghost icon sm" onClick={onClose}><Icon.close size={14}/></button>
        </header>
        <div className="body">
          <div className="hstack" style={{marginBottom:14, flexWrap:"wrap"}}>
            <PlanBadge plan={user.plan || "free"}/>
            {user.platform && <PlatformBadge p={user.platform}/>}
            {user.anonymous ? <span className="badge">Guest</span> : <span className="badge green"><Icon.check size={10}/> Signed in</span>}
            {user.flagged && <span className="badge red"><Icon.flag size={10}/> Flagged</span>}
          </div>

          <div className="card" style={{marginBottom:14}}>
            <div className="card-body">
              <div className="inline-stat">
                <div><div className="v">{user.plan==="unlimited"?"∞":user.credits}</div><div className="l">Credits</div></div>
                <div><div className="v">{user.stories}</div><div className="l">Stories</div></div>
                <div><div className="v">{money(user.ltv)}</div><div className="l">LTV</div></div>
                <div><div className="v">{user.signup ? Math.round((Date.now()-new Date(user.signup))/86400000)+"d" : "—"}</div><div className="l">Tenure</div></div>
              </div>
            </div>
          </div>

          <div className="tabs">
            {["profile","stories","payments","credits","activity"].map(t=>(
              <button key={t} data-active={tab===t} onClick={()=>setTab(t)} style={{textTransform:"capitalize"}}>{t}</button>
            ))}
          </div>

          {tab==="profile" && <div className="vstack" style={{gap:12}}>
            <FieldRow label="Email" value={user.email || "—"}/>
            <FieldRow label="Kid's name" value={user.childName || "—"}/>
            <FieldRow label="Age group" value={user.ageGroup || "—"}/>
            <FieldRow label="Signed up" value={fmtDate(user.signup)}/>
            <FieldRow label="Last active" value={fmtRelative(user.lastActive)}/>
            <FieldRow label="Plan" value={user.plan || "free"}/>
            <FieldRow label="Credits" value={user.credits != null ? String(user.credits) : "—"}/>
          </div>}

          {tab==="stories" && <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:10}}>
            {userStories.length ? userStories.map(s=>(
              <StoryCard key={s.id} story={s} compact/>
            )) : <div className="muted" style={{gridColumn:"span 2"}}>No stories yet.</div>}
          </div>}

          {tab==="payments" && <table className="tbl">
            <thead><tr><th>Date</th><th>Item</th><th>Provider</th><th style={{textAlign:"right"}}>Amount</th></tr></thead>
            <tbody>
              {userTx.length ? userTx.map(t=>(
                <tr key={t.id}>
                  <td className="muted">{fmtDate(t.date)}</td>
                  <td>{t.item}</td>
                  <td className="muted">{t.provider}</td>
                  <td className="num" style={{color: t.amount<0?"var(--red)":undefined}}>{money(t.amount)}</td>
                </tr>
              )) : <tr><td colSpan="4" className="muted" style={{padding:14}}>No transactions.</td></tr>}
            </tbody>
          </table>}

          {tab==="credits" && <div>
            <div className="card" style={{marginBottom:12}}>
              <div className="card-body" style={{display:"flex", gap:8, alignItems:"center"}}>
                <input className="input" placeholder="Amount (e.g. 5)" style={{height:32, width:120}}/>
                <input className="input" placeholder="Reason (visible in audit log)" style={{height:32, flex:1}}/>
                <button className="btn accent sm"><Icon.plus size={12}/> Grant</button>
              </div>
            </div>
            <div className="muted" style={{fontSize:12, marginBottom:8}}>Recent credit activity</div>
            <div className="vstack">
              {[
                {t:"Story generated",d:"-1",ago:"2h"},{t:"Purchase: 25-pack",d:"+25",ago:"3d"},
                {t:"Story generated",d:"-1",ago:"5d"},{t:"Admin grant (Adi)",d:"+5",ago:"12d"},
                {t:"Welcome bonus",d:"+3",ago:fmtDate(user.signup)},
              ].map((r,i)=>(
                <div key={i} className="event-item">
                  <div className="icon"><Icon.coin size={13}/></div>
                  <div style={{flex:1}}><div className="t">{r.t}</div></div>
                  <div className="mono" style={{color: r.d.startsWith('+')?"var(--green)":"var(--ink-2)"}}>{r.d}</div>
                  <div className="ago">{r.ago}</div>
                </div>
              ))}
            </div>
          </div>}

          {tab==="activity" && <div className="vstack">
            {["Opened app","Viewed story","Generated story","Shared story","Rated 5 stars","Opened Get More modal"].map((a,i)=>(
              <div key={i} className="event-item">
                <div className="icon"><Icon.sparkle size={13}/></div>
                <div style={{flex:1}}><div className="t">{a}</div><div className="m">{user.platform || "app"}</div></div>
                <div className="ago">{i+1}h ago</div>
              </div>
            ))}
          </div>}
        </div>
        <footer>
          <button className="btn sm" onClick={() => onEmail && onEmail(user)}><Icon.mail size={12}/> Message</button>
          <button className="btn sm"><Icon.eye size={12}/> Impersonate</button>
          <div className="spacer"/>
          <button className="btn danger sm"><Icon.x size={12}/> Suspend</button>
          <button className="btn accent sm"><Icon.coin size={12}/> Grant credits</button>
        </footer>
      </div>
    </>
  );
}

function FieldRow({ label, value }) {
  return (
    <div style={{display:"grid", gridTemplateColumns:"140px 1fr", gap:12, fontSize:13, alignItems:"center"}}>
      <div className="muted">{label}</div>
      <div style={{fontWeight:500}}>{value}</div>
    </div>
  );
}

function storyHue(id) {
  let h = 0;
  for (let i = 0; i < (id||"").length; i++) h = (h * 31 + (id||"").charCodeAt(i)) & 0xffff;
  return h % 360;
}

function StoryCard({ story, compact, onClick }) {
  const hue  = story.coverHue ?? storyHue(story.id);
  const c1   = `hsl(${hue}, 65%, 62%)`;
  const c2   = `hsl(${(hue+60)%360}, 70%, 45%)`;
  const kid  = story.childName || story.kid;
  const theme = story.therapeuticTheme || story.theme || "—";
  const pages = story.pages || 5;
  const lang  = story.language || "—";
  const label = kid ? `${kid}'s story` : (story.title || "Story");
  return (
    <div className="story-card" onClick={onClick}>
      <div className="story-cover" style={{"--c1":c1, "--c2":c2, aspectRatio: compact? "16/9":"16/10", background:`linear-gradient(135deg, ${c1}, ${c2})`}}>
        {story.coverUrl ? (
          <img src={story.coverUrl} alt="" style={{position:"absolute", inset:0, width:"100%", height:"100%", objectFit:"cover", borderRadius:"inherit"}}/>
        ) : (
          <div style={{position:"absolute", inset:0, background:"radial-gradient(circle at 30% 30%, rgba(255,255,255,.25), transparent 60%)"}}/>
        )}
        <span style={{position:"relative", zIndex:1, textShadow: story.coverUrl ? "0 1px 4px rgba(0,0,0,.6)" : "none"}}>{label}</span>
      </div>
      <div className="story-meta">
        <div className="t" style={{overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap"}}>{theme}</div>
        <div className="s">
          <span>{pages}p</span>
          <span>·</span>
          <span>{lang}</span>
          {story.flagged && <span className="badge red" style={{marginLeft:"auto"}}><Icon.flag size={9}/></span>}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { PageUsers, UserDrawer, StoryCard, storyHue });
