// CRM (Resend), Announcements, Banner Builder

function useResend(path) {
  const [data, setData] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState(null);

  React.useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setError(null);

    fetch("http://localhost:3099" + path)
      .then(r => { if (!r.ok) throw new Error("HTTP " + r.status); return r.json(); })
      .then(d  => { if (!cancelled) { setData(d); setLoading(false); } })
      .catch(err => { if (!cancelled) { setError(err.message); setLoading(false); } });

    return () => { cancelled = true; };
  }, [path]);

  return { data, loading, error };
}

function ResendEmpty({ message }) {
  return (
    <div style={{padding:"48px 0", textAlign:"center", color:"var(--ink-3)"}}>
      <Icon.mail size={28} style={{opacity:.3, marginBottom:10}}/>
      <div style={{fontSize:13}}>{message || "No data yet"}</div>
    </div>
  );
}

function ResendError({ error }) {
  return (
    <div style={{padding:"32px", textAlign:"center", color:"var(--red)", fontSize:13}}>
      <Icon.flag size={16} style={{marginBottom:8}}/><br/>
      Failed to load from Resend: {error}
    </div>
  );
}

function ResendLoading() {
  return (
    <div style={{padding:"48px 0", textAlign:"center", color:"var(--ink-3)", fontSize:13}}>
      Loading from Resend…
    </div>
  );
}

function BroadcastsTab() {
  const { data, loading, error } = useResend("/broadcasts");
  const broadcasts = data?.data || [];

  function fmtStatus(status) {
    if (status === "sent")      return <span className="badge green"><Icon.check size={10}/> Sent</span>;
    if (status === "sending")   return <span className="badge blue"><span className="pulse"/> Sending</span>;
    if (status === "draft")     return <span className="badge">Draft</span>;
    if (status === "scheduled") return <span className="badge amber">Scheduled</span>;
    return <span className="badge plum" style={{textTransform:"capitalize"}}>{status}</span>;
  }

  function fmtDate(d) {
    if (!d) return "—";
    return new Date(d).toLocaleDateString("en-US", { month:"short", day:"numeric", year:"numeric" });
  }

  return (
    <div className="card">
      <div className="table-wrap">
        <table className="tbl">
          <thead>
            <tr>
              <th>Broadcast</th>
              <th>Status</th>
              <th style={{textAlign:"right"}}>Recipients</th>
              <th>Sent at</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {loading && <tr><td colSpan={5}><ResendLoading/></td></tr>}
            {error   && <tr><td colSpan={5}><ResendError error={error}/></td></tr>}
            {!loading && !error && broadcasts.length === 0 && (
              <tr><td colSpan={5}><ResendEmpty message="No broadcasts yet. Send your first campaign from Resend."/></td></tr>
            )}
            {broadcasts.map(b => (
              <tr key={b.id}>
                <td>
                  <div className="hstack">
                    <div style={{width:28, height:28, borderRadius:7, background:"var(--bg-soft)", display:"grid", placeItems:"center"}}>
                      <Icon.mail size={13}/>
                    </div>
                    <b>{b.name || b.subject || b.id}</b>
                  </div>
                </td>
                <td>{fmtStatus(b.status)}</td>
                <td className="num">{b.metrics?.recipients != null ? b.metrics.recipients.toLocaleString() : "—"}</td>
                <td className="muted">{fmtDate(b.sent_at || b.created_at)}</td>
                <td><button className="btn ghost icon sm"><Icon.more size={14}/></button></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function AudiencesTab() {
  const { data, loading, error } = useResend("/audiences");
  const audiences = data?.data || [];

  const COLORS = ["var(--accent)","var(--plum)","var(--blue)","var(--green)","var(--amber)","var(--red)"];

  return (
    <div style={{display:"grid", gridTemplateColumns:"repeat(auto-fill, minmax(240px,1fr))", gap:14}}>
      {loading && <div style={{gridColumn:"1/-1"}}><ResendLoading/></div>}
      {error   && <div style={{gridColumn:"1/-1"}}><ResendError error={error}/></div>}
      {!loading && !error && audiences.length === 0 && (
        <div style={{gridColumn:"1/-1"}}><ResendEmpty message="No audiences yet. Create one in Resend to get started."/></div>
      )}
      {audiences.map((a, i) => (
        <div key={a.id} className="card">
          <div className="card-body">
            <div className="hstack">
              <div style={{width:8, height:8, borderRadius:999, background: COLORS[i % COLORS.length]}}/>
              <b style={{fontSize:13}}>{a.name}</b>
            </div>
            <div style={{fontFamily:"var(--display)", fontSize:26, fontWeight:600, marginTop:8}}>
              {a.contact_count != null ? a.contact_count.toLocaleString() : "—"}
            </div>
            <div className="muted" style={{fontSize:11, marginTop:2}}>contacts</div>
            <div className="hstack" style={{marginTop:10}}>
              <button className="btn sm" style={{flex:1, justifyContent:"center"}}><Icon.mail size={11}/> Email</button>
              <button className="btn ghost icon sm"><Icon.more size={13}/></button>
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

function DomainsTab() {
  const { data, loading, error } = useResend("/domains");
  const domains = data?.data || [];

  function fmtDomainStatus(status) {
    if (status === "verified") return <span className="badge green"><Icon.check size={10}/> Verified</span>;
    if (status === "pending")  return <span className="badge amber">Pending</span>;
    if (status === "failed")   return <span className="badge" style={{color:"var(--red)"}}>Failed</span>;
    return <span className="badge" style={{textTransform:"capitalize"}}>{status}</span>;
  }

  return (
    <div className="card">
      {loading && <ResendLoading/>}
      {error   && <ResendError error={error}/>}
      {!loading && !error && domains.length === 0 && <ResendEmpty message="No domains configured in Resend."/>}
      {!loading && !error && domains.length > 0 && (
        <div className="card-body">
          {domains.map((d, i) => (
            <div key={d.id} className="settings-row" style={i > 0 ? {borderTop:"1px solid var(--border)", paddingTop:16, marginTop:16} : {}}>
              <div>
                <h4 style={{fontFamily:"var(--mono)", fontWeight:500}}>{d.name}</h4>
                <p className="d" style={{marginTop:4}}>
                  Region: {d.region || "—"} &nbsp;·&nbsp; Created {new Date(d.created_at).toLocaleDateString("en-US", {month:"short", day:"numeric", year:"numeric"})}
                </p>
              </div>
              <div className="hstack">{fmtDomainStatus(d.status)}</div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function NewsletterTab() {
  const [segment, setSegment]       = React.useState("signed-in");
  const [search, setSearch]         = React.useState("");
  const [picked, setPicked]         = React.useState(new Set());   // DB user ids
  const [manualEmails, setManualEmails] = React.useState([]);      // arbitrary emails
  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 [progress, setProgress]     = React.useState(null);
  const [result, setResult]         = React.useState(null);

  const allUsers = (window.USERS || []);
  const isValidEmail = s => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s.trim());

  const commitSearch = () => {
    // supports "a@b.com, c@d.com" or single email
    const parts = search.split(/[,;\s]+/).map(s => s.trim()).filter(isValidEmail);
    if (!parts.length) return;
    setManualEmails(prev => {
      const next = [...prev];
      parts.forEach(e => { if (!next.includes(e)) next.push(e); });
      return next;
    });
    setSearch("");
  };

  const removeManual = email => setManualEmails(prev => prev.filter(e => e !== email));

  const dbRecipients = React.useMemo(() => {
    if (segment === "all")       return allUsers.filter(u => u.email);
    if (segment === "signed-in") return allUsers.filter(u => u.email && !u.anonymous);
    if (segment === "free")      return allUsers.filter(u => u.email && (u.plan === "free" || !u.plan));
    if (segment === "paid")      return allUsers.filter(u => u.email && u.plan && u.plan !== "free");
    if (segment === "custom")    return allUsers.filter(u => u.email && picked.has(u.id));
    return [];
  }, [segment, picked, allUsers]);

  // search suggestions (only in custom mode, only for DB users not yet picked)
  const suggestions = React.useMemo(() => {
    if (segment !== "custom" || !search.trim()) return [];
    const q = search.toLowerCase();
    return allUsers.filter(u => u.email && !picked.has(u.id) && (
      (u.name || "").toLowerCase().includes(q) || u.email.toLowerCase().includes(q)
    )).slice(0, 20);
  }, [segment, search, picked, allUsers]);

  // merge DB recipients + manual emails (dedup)
  const recipients = React.useMemo(() => {
    const dbEmails = new Set(dbRecipients.map(u => u.email));
    const extras = manualEmails
      .filter(e => !dbEmails.has(e))
      .map(e => ({ id: e, email: e, name: null, manual: true }));
    return [...dbRecipients, ...extras];
  }, [dbRecipients, manualEmails]);

  const SEGMENTS = [
    { id:"signed-in", label:"Signed-in users" },
    { id:"all",       label:"All (incl. anon)" },
    { id:"free",      label:"Free plan" },
    { id:"paid",      label:"Paid plan" },
    { id:"custom",    label:"Custom" },
  ];

  const send = async () => {
    if (!subject.trim() || !body.trim() || recipients.length === 0) return;
    setSending(true);
    setResult(null);
    setProgress({ sent: 0, total: recipients.length });

    const htmlBody = body.replace(/\n/g, "<br/>");
    const emails = recipients.map(u => ({
      from,
      to: u.name ? `${u.name} <${u.email}>` : u.email,
      subject,
      html: htmlBody,
    }));

    let sent = 0;
    let failed = 0;
    try {
      for (let i = 0; i < emails.length; i += 100) {
        const chunk = emails.slice(i, i + 100);
        const res = await fetch("http://localhost:3099/emails/batch", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(chunk),
        });
        if (res.ok) { sent += chunk.length; }
        else        { failed += chunk.length; }
        setProgress({ sent, total: recipients.length });
      }
      setResult({ ok: failed === 0, message: `Sent to ${sent} recipient${sent !== 1 ? "s" : ""}${failed ? ` · ${failed} 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 style={{display:"grid", gridTemplateColumns:"1fr 340px", gap:16, alignItems:"start"}}>
      {/* Left: compose */}
      <div className="card">
        <div className="card-body" style={{display:"flex", flexDirection:"column", gap:16}}>
          <div>
            <label style={{fontSize:11, fontWeight:500, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Audience</label>
            <div className="hstack" style={{marginTop:8, flexWrap:"wrap", gap:6}}>
              {SEGMENTS.map(s => (
                <button key={s.id} className="btn sm" onClick={() => { setSegment(s.id); setPicked(new Set()); }}
                  style={{ background: segment===s.id ? "var(--accent-soft)" : undefined,
                           borderColor: segment===s.id ? "transparent" : undefined,
                           color: segment===s.id ? "var(--accent-ink)" : undefined }}>
                  {s.label}
                </button>
              ))}
            </div>

            {segment === "custom" && (
              <div style={{marginTop:10, display:"flex", flexDirection:"column", gap:8}}>
                {/* Input row */}
                <div className="hstack" style={{gap:6}}>
                  <div className="input search" style={{flex:1}}>
                    <Icon.search size={13}/>
                    <input
                      placeholder="Search users or type any email, comma-separate multiple…"
                      value={search}
                      onChange={e => setSearch(e.target.value)}
                      onKeyDown={e => { if (e.key === "Enter") { e.preventDefault(); commitSearch(); } }}
                    />
                  </div>
                  <button className="btn sm" onClick={commitSearch}
                    disabled={!search.trim()}
                    style={{flexShrink:0}}>
                    <Icon.plus size={12}/> Add
                  </button>
                </div>

                {/* DB suggestions dropdown */}
                {suggestions.length > 0 && (
                  <div style={{border:"1px solid var(--border)", borderRadius:8, overflow:"hidden"}}>
                    {suggestions.map(u => (
                      <div key={u.id} className="hstack" style={{padding:"7px 12px", borderBottom:"1px solid var(--border)", fontSize:12, cursor:"pointer", background:"var(--bg-elev)"}}
                        onClick={() => { const s = new Set(picked); s.add(u.id); setPicked(s); setSearch(""); }}>
                        <div className="avatar" style={{width:22,height:22,fontSize:9,flexShrink:0}}>{(u.name||u.email)[0].toUpperCase()}</div>
                        <span style={{flex:1, marginLeft:8, fontWeight:500}}>{u.name || u.email}</span>
                        <span className="muted" style={{fontSize:11}}>{u.name ? u.email : ""}</span>
                      </div>
                    ))}
                  </div>
                )}

                {/* Chips: picked DB users + manual emails */}
                {(picked.size > 0 || manualEmails.length > 0) && (
                  <div style={{display:"flex", flexWrap:"wrap", gap:5}}>
                    {allUsers.filter(u => picked.has(u.id)).map(u => (
                      <span key={u.id} style={{display:"inline-flex", alignItems:"center", gap:4, background:"var(--accent-soft)", color:"var(--accent-ink)", borderRadius:999, padding:"3px 10px", fontSize:11, fontWeight:500}}>
                        {u.name || u.email}
                        <button onClick={() => { const s=new Set(picked); s.delete(u.id); setPicked(s); }}
                          style={{background:"none",border:"none",cursor:"pointer",padding:0,lineHeight:1,color:"inherit",opacity:.7}}>×</button>
                      </span>
                    ))}
                    {manualEmails.map(e => (
                      <span key={e} style={{display:"inline-flex", alignItems:"center", gap:4, background:"var(--bg-soft)", border:"1px solid var(--border)", borderRadius:999, padding:"3px 10px", fontSize:11}}>
                        {e}
                        <button onClick={() => removeManual(e)}
                          style={{background:"none",border:"none",cursor:"pointer",padding:0,lineHeight:1,opacity:.6}}>×</button>
                      </span>
                    ))}
                  </div>
                )}
              </div>
            )}
          </div>

          <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)}/>
          </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 subject line…"/>
          </div>
          <div>
            <label style={{fontSize:11, fontWeight:500, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Message</label>
            <textarea style={{...inputStyle, minHeight:200, resize:"vertical"}} value={body} onChange={e=>setBody(e.target.value)} placeholder="Write your newsletter here…"/>
          </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 className="hstack">
            <div className="spacer"/>
            <button className="btn accent sm" onClick={send}
              disabled={sending || !subject.trim() || !body.trim() || recipients.length === 0}
              style={{minWidth:160, justifyContent:"center"}}>
              {sending
                ? <><span className="pulse" style={{width:7,height:7,borderRadius:"50%",background:"white",display:"inline-block"}}/> {progress ? `${progress.sent}/${progress.total} sent…` : "Sending…"}</>
                : <><Icon.mail size={12}/> Send to {recipients.length} user{recipients.length!==1?"s":""}</>}
            </button>
          </div>
        </div>
      </div>

      {/* Right: recipients preview */}
      <div className="card">
        <div className="card-body">
          <div className="hstack" style={{marginBottom:12}}>
            <b style={{fontSize:13}}>Recipients</b>
            <span className="badge" style={{marginLeft:6}}>{recipients.length}</span>
          </div>
          {recipients.length === 0 ? (
            <div className="muted" style={{fontSize:12, textAlign:"center", padding:"24px 0"}}>
              {segment === "custom" && picked.size === 0 ? "Search and select users above" : "No users match this segment"}
            </div>
          ) : (
            <div style={{maxHeight:400, overflowY:"auto"}}>
              {recipients.slice(0,50).map((u,i) => (
                <div key={u.id} className="hstack" style={{padding:"6px 0", borderBottom: i<recipients.length-1?"1px solid var(--border)":undefined, fontSize:12}}>
                  <div className="avatar" style={{width:26,height:26,fontSize:10,flexShrink:0}}>{(u.name||u.email||"?")[0].toUpperCase()}</div>
                  <div style={{flex:1, minWidth:0, marginLeft:8}}>
                    <div style={{fontWeight:500, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap"}}>{u.name || u.email}</div>
                    {u.name && <div className="muted" style={{fontSize:10}}>{u.email}</div>}
                  </div>
                  {u.plan && u.plan !== "free" && <span className="badge blue" style={{fontSize:10}}>{u.plan}</span>}
                </div>
              ))}
              {recipients.length > 50 && (
                <div className="muted" style={{fontSize:11, textAlign:"center", padding:"8px 0"}}>+ {recipients.length-50} more</div>
              )}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function PageCRM() {
  const [tab, setTab] = React.useState("newsletter");

  return (
    <>
      <div className="page-header">
        <div>
          <h1>CRM <span style={{fontSize:12, color:"var(--ink-3)", fontFamily:"var(--mono)", marginLeft:8}}>powered by resend.com</span></h1>
          <div className="sub">Send newsletters, manage broadcasts, and view your Resend domains.</div>
        </div>
        <div className="actions">
          <span className="badge green"><Icon.check size={10}/> Resend connected</span>
        </div>
      </div>

      <div className="tabs">
        {["newsletter","broadcasts","audiences","domains"].map(t =>
          <button key={t} data-active={tab===t} onClick={()=>setTab(t)} style={{textTransform:"capitalize"}}>{t}</button>
        )}
      </div>

      {tab === "newsletter"  && <NewsletterTab/>}
      {tab === "broadcasts"  && <BroadcastsTab/>}
      {tab === "audiences"   && <AudiencesTab/>}
      {tab === "domains"     && <DomainsTab/>}
    </>
  );
}

// ---------- Announcements ----------
function PageAnnounce() {
  const [items, setItems] = React.useState([
    { id:1, title:"40% off Family plan · Summer sale!", body:"Unlock unlimited bedtime stories for the whole family.", type:"sale", audience:"Free users", status:"live", starts:"Now", ends:"Apr 26", views:8420, clicks:1284, channels:["in-app","push","email"] },
    { id:2, title:"✨ New theme: Ocean Adventure", body:"Dive into a brand new underwater theme with your kid's favorite character.", type:"news", audience:"All users", status:"live", starts:"Yesterday", ends:"—", views:12430, clicks:3120, channels:["in-app","banner"] },
    { id:3, title:"Scheduled maintenance", body:"We'll be updating story servers Apr 22 from 2–3am UTC.", type:"system", audience:"All users", status:"scheduled", starts:"Apr 22", ends:"Apr 22", views:0, clicks:0, channels:["in-app"] },
    { id:4, title:"Invite a friend, get 5 free stories", body:"Share Talio with a friend and you both get credits.", type:"promo", audience:"Active users", status:"draft", starts:"—", ends:"—", views:0, clicks:0, channels:["in-app","email"] },
    { id:5, title:"Happy Holidays from Talio 🎄", body:"A little gift for every family — 3 free credits through Jan 1.", type:"sale", audience:"All users", status:"ended", starts:"Dec 20", ends:"Jan 1", views:24120, clicks:8420, channels:["in-app","push","email","banner"] },
  ]);
  const [selected, setSelected] = React.useState(null);

  const typeColor = { sale:"accent", news:"plum", promo:"blue", system:"" };
  const channelIcons = { "in-app":<Icon.bell size={10}/>, push:<Icon.speaker size={10}/>, email:<Icon.mail size={10}/>, banner:<Icon.palette size={10}/> };

  return (
    <>
      <div className="page-header">
        <div><h1>Announcements</h1><div className="sub">Tell parents about sales, new themes, or updates — push, in-app, email, or banner.</div></div>
        <div className="actions">
          <button className="btn primary sm" onClick={()=>setSelected({id:Date.now(), title:"", body:"", type:"sale", audience:"All users", channels:["in-app"]})}><Icon.plus size={12}/> New announcement</button>
        </div>
      </div>

      <div className="kpi-grid">
        <KPI label="Active" value={items.filter(i=>i.status==="live").length}/>
        <KPI label="Scheduled" value={items.filter(i=>i.status==="scheduled").length}/>
        <KPI label="Impressions (30d)" value="52,410" delta={14.2}/>
        <KPI label="Click-through" value="15.2" unit="%" delta={2.1}/>
        <KPI label="Driven revenue" value="$4,120" delta={18.8}/>
      </div>

      <div className="card">
        <div className="table-wrap">
          <table className="tbl">
            <thead><tr><th>Announcement</th><th>Type</th><th>Audience</th><th>Channels</th><th>Status</th><th>Window</th><th style={{textAlign:"right"}}>Views</th><th style={{textAlign:"right"}}>Clicks</th><th></th></tr></thead>
            <tbody>
              {items.map(a=>(
                <tr key={a.id} onClick={()=>setSelected(a)}>
                  <td style={{maxWidth:340}}><b>{a.title}</b><div className="muted" style={{fontSize:11, whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>{a.body}</div></td>
                  <td><span className={"badge " + (typeColor[a.type]||"")} style={{textTransform:"capitalize"}}>{a.type}</span></td>
                  <td className="muted">{a.audience}</td>
                  <td><div className="hstack" style={{gap:3}}>{a.channels.map(c=><span key={c} className="badge" style={{padding:"0 5px"}} title={c}>{channelIcons[c]}</span>)}</div></td>
                  <td>{a.status==="live"?<span className="badge green"><span className="pulse"/> Live</span>:
                      a.status==="scheduled"?<span className="badge amber">Scheduled</span>:
                      a.status==="draft"?<span className="badge">Draft</span>:
                      <span className="badge" style={{opacity:.6}}>Ended</span>}</td>
                  <td className="muted" style={{fontSize:11}}>{a.starts}{a.ends!=="—"?" → "+a.ends:""}</td>
                  <td className="num">{a.views.toLocaleString()}</td>
                  <td className="num">{a.clicks.toLocaleString()}</td>
                  <td><button className="btn ghost icon sm" onClick={e=>{e.stopPropagation(); setSelected(a);}}><Icon.chevRight size={13}/></button></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      {selected && <AnnounceEditor item={selected} onClose={()=>setSelected(null)}/>}
    </>
  );
}

function AnnounceEditor({ item, onClose }) {
  const [draft, setDraft] = React.useState(item);
  const toggleCh = c => setDraft({...draft, channels: draft.channels.includes(c) ? draft.channels.filter(x=>x!==c) : [...draft.channels, c]});
  return (
    <>
      <div className="drawer-backdrop" onClick={onClose}/>
      <div className="drawer" style={{width:"min(720px, 95vw)"}}>
        <header>
          <div style={{fontWeight:600}}>{item.title ? "Edit announcement" : "New announcement"}</div>
          <div className="spacer"/>
          <button className="btn ghost icon sm" onClick={onClose}><Icon.close size={14}/></button>
        </header>
        <div className="body" style={{display:"grid", gridTemplateColumns:"1fr 280px", gap:20}}>
          <div className="vstack" style={{gap:14}}>
            <div>
              <label style={{fontSize:11, fontWeight:500, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Title</label>
              <input style={{width:"100%", marginTop:6, height:38, padding:"0 12px", background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:8, color:"var(--ink)", fontSize:14, fontWeight:500}}
                value={draft.title} onChange={e=>setDraft({...draft, title:e.target.value})} placeholder="Big, clear, kid-friendly headline…"/>
            </div>
            <div>
              <label style={{fontSize:11, fontWeight:500, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Body</label>
              <textarea style={{width:"100%", marginTop:6, minHeight:90, padding:"10px 12px", background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:8, color:"var(--ink)", fontSize:13, resize:"vertical", fontFamily:"inherit"}}
                value={draft.body} onChange={e=>setDraft({...draft, body:e.target.value})} placeholder="One or two sentences parents will see."/>
            </div>
            <div className="grid-2">
              <div>
                <label style={{fontSize:11, fontWeight:500, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Type</label>
                <select style={{width:"100%", marginTop:6, height:38, padding:"0 10px", background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:8, color:"var(--ink)", fontSize:13}}
                  value={draft.type} onChange={e=>setDraft({...draft, type:e.target.value})}>
                  <option value="sale">🎉 Sale</option>
                  <option value="news">✨ News</option>
                  <option value="promo">💌 Promo</option>
                  <option value="system">⚙️ System</option>
                </select>
              </div>
              <div>
                <label style={{fontSize:11, fontWeight:500, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Audience</label>
                <select style={{width:"100%", marginTop:6, height:38, padding:"0 10px", background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:8, color:"var(--ink)", fontSize:13}}
                  value={draft.audience} onChange={e=>setDraft({...draft, audience:e.target.value})}>
                  <option>All users</option><option>Free users</option><option>Paying subscribers</option>
                  <option>Low credits (&lt;2)</option><option>Inactive 14+ days</option><option>New this week</option>
                </select>
              </div>
            </div>
            <div>
              <label style={{fontSize:11, fontWeight:500, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em", marginBottom:8, display:"block"}}>Channels</label>
              <div className="hstack" style={{flexWrap:"wrap", gap:6}}>
                {["in-app","push","email","banner"].map(c=>(
                  <button key={c} className="btn sm" onClick={()=>toggleCh(c)}
                    style={{background: draft.channels.includes(c) ? "var(--accent-soft)" : undefined,
                            borderColor: draft.channels.includes(c) ? "transparent" : undefined,
                            color: draft.channels.includes(c) ? "var(--accent-ink)" : undefined}}>
                    {draft.channels.includes(c) && <Icon.check size={11}/>} {c}
                  </button>
                ))}
              </div>
            </div>
            <div className="grid-2">
              <div>
                <label style={{fontSize:11, fontWeight:500, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Starts</label>
                <input type="datetime-local" style={{width:"100%", marginTop:6, height:38, padding:"0 10px", background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:8, color:"var(--ink)"}}/>
              </div>
              <div>
                <label style={{fontSize:11, fontWeight:500, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Ends</label>
                <input type="datetime-local" style={{width:"100%", marginTop:6, height:38, padding:"0 10px", background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:8, color:"var(--ink)"}}/>
              </div>
            </div>
          </div>

          <div>
            <label style={{fontSize:11, fontWeight:500, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Preview · in-app</label>
            <div style={{marginTop:6, padding:18, borderRadius:14, background:"linear-gradient(180deg, oklch(0.96 0.03 20), oklch(0.94 0.04 340))", border:"1px solid var(--border)"}}>
              <div style={{background:"white", borderRadius:12, padding:14, boxShadow:"0 8px 20px -10px rgba(60,30,100,.2)"}}>
                <div style={{display:"flex", gap:10, alignItems:"start"}}>
                  <div style={{width:36, height:36, borderRadius:10, background:"linear-gradient(155deg, var(--accent), var(--plum))", display:"grid", placeItems:"center", color:"white", flexShrink:0}}>
                    {draft.type==="sale"?"🎉":draft.type==="news"?"✨":draft.type==="promo"?"💌":"⚙️"}
                  </div>
                  <div style={{minWidth:0, flex:1}}>
                    <div style={{fontFamily:"var(--fraunces)", fontWeight:700, fontSize:15, color:"oklch(0.32 0.13 330)", lineHeight:1.2}}>{draft.title || "Your headline here"}</div>
                    <div style={{fontSize:12, color:"var(--ink-2)", marginTop:6, lineHeight:1.5}}>{draft.body || "One or two sentences parents will see."}</div>
                    <button style={{marginTop:10, background:"var(--accent)", color:"white", border:0, height:30, padding:"0 14px", borderRadius:999, fontWeight:600, fontSize:12}}>Check it out →</button>
                  </div>
                </div>
              </div>
            </div>
            <div className="muted" style={{fontSize:11, marginTop:10}}>Preview renders in-app. Push & email adapt automatically.</div>
          </div>
        </div>
        <footer>
          <button className="btn sm">Save draft</button>
          <div className="spacer"/>
          <button className="btn ghost sm" onClick={onClose}>Cancel</button>
          <button className="btn accent sm"><Icon.speaker size={12}/> Publish</button>
        </footer>
      </div>
    </>
  );
}

// ---------- Banner Builder (fun, kid-style) ----------
function PageBanners() {
  const presets = [
    { id:"cloud", name:"Cloud party", bg:"linear-gradient(180deg, oklch(0.92 0.05 340), oklch(0.88 0.06 20))", ink:"oklch(0.35 0.15 330)"},
    { id:"sunny", name:"Sunny park", bg:"linear-gradient(180deg, oklch(0.94 0.08 90), oklch(0.88 0.1 55))", ink:"oklch(0.32 0.16 40)"},
    { id:"forest", name:"Enchanted forest", bg:"linear-gradient(180deg, oklch(0.90 0.08 150), oklch(0.78 0.14 160))", ink:"oklch(0.28 0.12 150)"},
    { id:"night", name:"Starry night", bg:"linear-gradient(180deg, oklch(0.30 0.10 270), oklch(0.42 0.14 300))", ink:"oklch(0.96 0.02 60)"},
    { id:"ocean", name:"Ocean", bg:"linear-gradient(180deg, oklch(0.82 0.10 220), oklch(0.62 0.14 235))", ink:"oklch(0.98 0.02 200)"},
    { id:"candy", name:"Candyland", bg:"linear-gradient(180deg, oklch(0.90 0.08 340), oklch(0.85 0.10 300))", ink:"oklch(0.35 0.18 330)"},
  ];
  const mascots = [
    { id:"owl", emoji:"🦉", name:"Owl Kiki" },
    { id:"fox", emoji:"🦊", name:"Fox" },
    { id:"deer", emoji:"🦌", name:"Deer" },
    { id:"bunny", emoji:"🐰", name:"Bunny" },
    { id:"whale", emoji:"🐳", name:"Whale" },
    { id:"none", emoji:"", name:"None" },
  ];
  const [banner, setBanner] = React.useState({
    preset:"cloud",
    title:"Summer Sale!",
    subtitle:"40% off Family plan this week only",
    cta:"Get the deal",
    sticker:"⭐",
    mascot:"owl",
    decor:true,
    shape:"cloud", // cloud | rounded | ribbon
    placement:"top",
  });
  const preset = presets.find(p=>p.id===banner.preset);

  const saved = [
    { name:"Summer Sale 40%", lastEdit:"2d ago", placement:"Home · top", live:true },
    { name:"Ocean Theme launch", lastEdit:"5d ago", placement:"Story picker", live:true },
    { name:"Holiday freebie", lastEdit:"Dec 18", placement:"Home · modal", live:false },
    { name:"Welcome · new user", lastEdit:"Last week", placement:"Onboarding", live:true },
  ];

  return (
    <>
      <div className="page-header">
        <div><h1>Banner Builder</h1><div className="sub">Design sale banners, announcement banners, and onboarding banners in Talio's playful style.</div></div>
        <div className="actions">
          <button className="btn sm"><Icon.download size={12}/> Export PNG</button>
          <button className="btn accent sm"><Icon.check size={12}/> Publish to app</button>
        </div>
      </div>

      <div style={{display:"grid", gridTemplateColumns:"1fr 320px", gap:16, marginBottom:24}}>
        {/* Preview */}
        <div>
          <div className="muted" style={{fontSize:11, marginBottom:8, textTransform:"uppercase", letterSpacing:".05em", fontWeight:500}}>Live preview · mobile</div>
          <div style={{background:"var(--bg-soft)", border:"1px solid var(--border)", borderRadius:18, padding:24, display:"grid", placeItems:"center"}}>
            <div style={{width:360, minHeight:340, background:preset.bg, borderRadius:24, padding:18, position:"relative", overflow:"hidden", boxShadow:"0 20px 40px -20px rgba(60,30,100,.25)"}}>
              {banner.decor && (
                <>
                  <div style={{position:"absolute", top:20, left:20, fontSize:20, opacity:.7}}>⭐</div>
                  <div style={{position:"absolute", top:52, right:40, fontSize:14, opacity:.6}}>✨</div>
                  <div style={{position:"absolute", bottom:80, left:32, fontSize:12, opacity:.5}}>⭐</div>
                  <div style={{position:"absolute", top:100, right:18, fontSize:18, opacity:.5}}>☁️</div>
                  <div style={{position:"absolute", top:180, left:10, fontSize:22, opacity:.4}}>☁️</div>
                </>
              )}

              <BannerShape banner={banner} preset={preset} mascot={mascots.find(m=>m.id===banner.mascot)}/>
            </div>
          </div>

          <div className="hstack" style={{marginTop:12, justifyContent:"center", gap:8}}>
            <button className="btn sm"><Icon.arrowUp size={11} style={{transform:"rotate(-90deg)"}}/> Mobile</button>
            <button className="btn ghost sm">Tablet</button>
            <button className="btn ghost sm">Web</button>
          </div>
        </div>

        {/* Controls */}
        <div className="card">
          <div className="card-body" style={{display:"flex", flexDirection:"column", gap:14}}>
            <div>
              <label style={{fontSize:11, fontWeight:600, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Scene</label>
              <div style={{display:"grid", gridTemplateColumns:"repeat(3,1fr)", gap:6, marginTop:8}}>
                {presets.map(p=>(
                  <div key={p.id} onClick={()=>setBanner({...banner, preset:p.id})}
                    style={{aspectRatio:"3/2", borderRadius:8, background:p.bg, cursor:"pointer",
                            boxShadow: banner.preset===p.id ? "0 0 0 2px var(--ink)" : "inset 0 0 0 1px var(--border)",
                            position:"relative"}}>
                      <span style={{position:"absolute", bottom:4, left:6, fontSize:9, color:"oklch(0.25 0.05 280)", fontWeight:700, background:"rgba(255,255,255,.85)", padding:"1px 5px", borderRadius:4, backdropFilter:"blur(2px)"}}>{p.name}</span>
                    </div>
                ))}
              </div>
            </div>

            <div>
              <label style={{fontSize:11, fontWeight:600, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Shape</label>
              <div className="seg" style={{marginTop:6, width:"100%"}}>
                {["cloud","rounded","ribbon"].map(s=>(
                  <button key={s} data-active={banner.shape===s} onClick={()=>setBanner({...banner, shape:s})} style={{flex:1, textTransform:"capitalize"}}>{s}</button>
                ))}
              </div>
            </div>

            <div>
              <label style={{fontSize:11, fontWeight:600, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Title</label>
              <input value={banner.title} onChange={e=>setBanner({...banner, title:e.target.value})}
                style={{width:"100%", marginTop:6, height:32, padding:"0 10px", background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:7, color:"var(--ink)", fontWeight:600}}/>
            </div>
            <div>
              <label style={{fontSize:11, fontWeight:600, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Subtitle</label>
              <input value={banner.subtitle} onChange={e=>setBanner({...banner, subtitle:e.target.value})}
                style={{width:"100%", marginTop:6, height:32, padding:"0 10px", background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:7, color:"var(--ink)"}}/>
            </div>
            <div>
              <label style={{fontSize:11, fontWeight:600, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Button</label>
              <input value={banner.cta} onChange={e=>setBanner({...banner, cta:e.target.value})}
                style={{width:"100%", marginTop:6, height:32, padding:"0 10px", background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:7, color:"var(--ink)"}}/>
            </div>

            <div>
              <label style={{fontSize:11, fontWeight:600, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Mascot</label>
              <div style={{display:"grid", gridTemplateColumns:"repeat(6,1fr)", gap:4, marginTop:6}}>
                {mascots.map(m=>(
                  <button key={m.id} className="btn sm" onClick={()=>setBanner({...banner, mascot:m.id})}
                    title={m.name}
                    style={{padding:0, fontSize:18, height:34,
                      background: banner.mascot===m.id ? "var(--accent-soft)" : undefined,
                      borderColor: banner.mascot===m.id ? "transparent" : undefined}}>{m.emoji || "∅"}</button>
                ))}
              </div>
            </div>

            <div>
              <label style={{fontSize:11, fontWeight:600, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Sticker</label>
              <div style={{display:"grid", gridTemplateColumns:"repeat(8,1fr)", gap:4, marginTop:6}}>
                {["⭐","✨","🎉","💫","🌈","🎁","❤️","🧁"].map(s=>(
                  <button key={s} className="btn sm" onClick={()=>setBanner({...banner, sticker:s})}
                    style={{padding:0, height:28, fontSize:14,
                      background: banner.sticker===s ? "var(--accent-soft)" : undefined,
                      borderColor: banner.sticker===s ? "transparent" : undefined}}>{s}</button>
                ))}
              </div>
            </div>

            <div className="hstack" style={{justifyContent:"space-between"}}>
              <label style={{fontSize:12, color:"var(--ink-2)"}}>Sparkly decorations</label>
              <Switch on={banner.decor} onChange={v=>setBanner({...banner, decor:v})}/>
            </div>

            <div>
              <label style={{fontSize:11, fontWeight:600, color:"var(--ink-2)", textTransform:"uppercase", letterSpacing:".05em"}}>Placement</label>
              <select value={banner.placement} onChange={e=>setBanner({...banner, placement:e.target.value})}
                style={{width:"100%", marginTop:6, height:32, padding:"0 10px", background:"var(--bg-elev)", border:"1px solid var(--border)", borderRadius:7, color:"var(--ink)"}}>
                <option value="top">Home · top banner</option>
                <option value="modal">Home · modal on launch</option>
                <option value="picker">Story picker</option>
                <option value="end">End-of-story</option>
                <option value="web">Website hero</option>
              </select>
            </div>
          </div>
        </div>
      </div>

      <h3 style={{fontSize:13, marginBottom:10}}>Saved banners</h3>
      <div className="card">
        <div className="table-wrap">
          <table className="tbl">
            <thead><tr><th>Name</th><th>Placement</th><th>Last edit</th><th>Status</th><th></th></tr></thead>
            <tbody>
              {saved.map((s,i)=>(
                <tr key={i}>
                  <td><b>{s.name}</b></td>
                  <td className="muted">{s.placement}</td>
                  <td className="muted">{s.lastEdit}</td>
                  <td>{s.live ? <span className="badge green"><span className="pulse"/> Live</span> : <span className="badge">Draft</span>}</td>
                  <td><div className="hstack"><button className="btn sm">Edit</button><button className="btn ghost icon sm"><Icon.more size={14}/></button></div></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </>
  );
}

function BannerShape({ banner, preset, mascot }) {
  // card sits on white — always use a dark, readable ink regardless of scene
  const common = {
    fontFamily: "var(--fraunces)",
    color: "oklch(0.28 0.12 330)",
    textAlign: "center",
    padding: "20px 22px",
    position: "relative",
  };
  const title = <div style={{fontSize:28, fontWeight:700, lineHeight:1.05, letterSpacing:"-0.02em"}}>{banner.title || "Your title"}</div>;
  const sub = <div style={{fontSize:13, marginTop:8, opacity:.85, fontFamily:"var(--sans)", fontWeight:500}}>{banner.subtitle || "A sentence for the kids."}</div>;
  const btn = <button style={{marginTop:14, background:"oklch(0.72 0.18 55)", color:"white", border:0, height:40, padding:"0 22px", borderRadius:999, fontWeight:700, fontSize:14, fontFamily:"var(--fraunces)", boxShadow:"0 4px 0 oklch(0.55 0.17 40), 0 8px 16px -6px rgba(180,80,20,.4)"}}>{banner.cta || "Tap me!"}</button>;
  const sticker = banner.sticker && <div style={{position:"absolute", top:-10, right:-10, width:48, height:48, background:"oklch(0.96 0.12 85)", borderRadius:999, display:"grid", placeItems:"center", fontSize:24, transform:"rotate(15deg)", boxShadow:"0 4px 10px rgba(180,120,40,.3)", border:"3px solid white"}}>{banner.sticker}</div>;

  const content = (
    <>
      {sticker}
      <div style={common}>
        {mascot && mascot.emoji && (
          <div style={{fontSize:64, marginBottom:6, filter:"drop-shadow(0 6px 12px rgba(0,0,0,.15))"}}>{mascot.emoji}</div>
        )}
        {title}
        {sub}
        {btn}
      </div>
    </>
  );

  if (banner.shape === "cloud") {
    return (
      <div style={{marginTop:40, position:"relative"}}>
        <div style={{background:"white", borderRadius:"50% 50% 48% 52% / 60% 55% 45% 40%", padding:"0", boxShadow:"0 10px 30px -10px rgba(80,40,140,.3), inset 0 -4px 0 rgba(0,0,0,.04)", position:"relative"}}>
          {content}
          {/* cloud puffs */}
          <div style={{position:"absolute", left:-14, top:28, width:40, height:40, background:"white", borderRadius:999}}/>
          <div style={{position:"absolute", right:-18, top:48, width:36, height:36, background:"white", borderRadius:999}}/>
          <div style={{position:"absolute", left:22, bottom:-12, width:30, height:30, background:"white", borderRadius:999}}/>
          <div style={{position:"absolute", right:34, bottom:-8, width:22, height:22, background:"white", borderRadius:999}}/>
        </div>
      </div>
    );
  }
  if (banner.shape === "ribbon") {
    return (
      <div style={{marginTop:48, position:"relative", background:"white", padding:0, borderRadius:22, boxShadow:"0 10px 30px -10px rgba(80,40,140,.3)", clipPath:"polygon(0 10%, 100% 0, 100% 90%, 0 100%)"}}>
        {content}
      </div>
    );
  }
  return (
    <div style={{marginTop:40, background:"white", borderRadius:26, boxShadow:"0 10px 30px -10px rgba(80,40,140,.3), inset 0 -5px 0 rgba(0,0,0,.05)", position:"relative"}}>
      {content}
    </div>
  );
}

Object.assign(window, { PageCRM, PageAnnounce, PageBanners });
