/* VBOUT email marketing — bulk sendouts.
   - Sync a customer segment into a VBOUT contact list (then compose & send the
     campaign inside VBOUT; list membership + an optional tag trigger automations).
   - Read campaign performance (open / click rates) back from VBOUT.
   Talks to /api/vbout/*  (see server/vbout.js). */

function pct(a, b) { return b > 0 ? Math.round((a / b) * 1000) / 10 : 0; }

function CampaignStats({ id }) {
  const [s, setS] = useState(null);
  const [err, setErr] = useState(null);
  useEffect(() => {
    let a = true;
    fetch("/api/vbout/campaigns/" + encodeURIComponent(id) + "/stats")
      .then(r => r.json()).then(j => { if (!a) return; if (j && j.error) setErr(j.error); else setS(j); })
      .catch(e => a && setErr(e.message));
    return () => { a = false; };
  }, [id]);
  if (err) return <span className="dim" title={err}>stats unavailable</span>;
  if (!s) return <span className="dim">…</span>;
  return (
    <span>
      <b>{s.sent}</b> sent · {s.opens} opened <span className="dim">({s.openRate}%)</span>
      {" · "}{s.clicks} clicked <span className="dim">({s.clickRate}%)</span>
      {s.unsubs ? <span className="dim"> · {s.unsubs} unsub</span> : null}
    </span>
  );
}

function MarketingView({ go }) {
  const [status, setStatus] = useState(null);        // { configured }
  const [lists, setLists] = useState(null);
  const [listId, setListId] = useState("");
  const [consentOnly, setConsentOnly] = useState(true);
  const [query, setQuery] = useState("");
  const [tag, setTag] = useState("");
  const [max, setMax] = useState("");
  const [syncing, setSyncing] = useState(false);
  const [result, setResult] = useState(null);
  const [err, setErr] = useState(null);
  const [campaigns, setCampaigns] = useState(null);
  const [openStats, setOpenStats] = useState({});     // campaignId → true

  useEffect(() => { fetch("/api/vbout/status").then(r => r.json()).then(setStatus).catch(() => setStatus({ configured: false })); }, []);
  useEffect(() => {
    if (!status || !status.configured) return;
    fetch("/api/vbout/lists").then(r => r.json()).then(j => {
      const ls = (j && j.lists) || [];
      setLists(ls);
      if (ls.length && !listId) setListId(ls[0].id);
    }).catch(e => setErr(e.message));
    fetch("/api/vbout/campaigns?filter=sent&limit=25").then(r => r.json())
      .then(j => setCampaigns((j && j.campaigns) || [])).catch(() => setCampaigns([]));
  }, [status]);

  // Client-side estimate of how many customers the current filters would sync —
  // the server re-queries Shopify at push time, so this is just a preview.
  const estimate = useMemo(() => {
    const all = (DTF && DTF.customers) || [];
    let seg = all.filter(c => c && c.email);
    if (consentOnly) seg = seg.filter(c => c.subscribed);
    if (query.trim()) {
      const q = query.trim().toLowerCase();
      seg = seg.filter(c => [c.name, c.email, c.country, (c.tags || []).join(" ")].filter(Boolean).join(" ").toLowerCase().includes(q));
    }
    return max ? Math.min(seg.length, Number(max)) : seg.length;
  }, [consentOnly, query, max, status]);

  async function runSync() {
    setSyncing(true); setErr(null); setResult(null);
    try {
      const body = { listId, consentOnly, query: query.trim(), tag: tag.trim(), max: max ? Number(max) : undefined };
      const j = await fetch("/api/vbout/sync", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) }).then(r => r.json());
      if (j && j.error) throw new Error(j.error);
      setResult(j);
    } catch (e) { setErr(e.message); }
    finally { setSyncing(false); }
  }

  if (status && !status.configured) {
    return (
      <div className="board">
        <div className="empty">
          <Icon name="mail" />
          <div className="t">VBOUT not connected</div>
          <div className="m">Add <code>VBOUT_API_KEY</code> to the server <code>.env</code> (Settings → API integration in VBOUT), then restart.</div>
        </div>
      </div>
    );
  }
  if (!status || !lists) return <SkeletonRows rows={6} />;

  const list = lists.find(l => l.id === listId);

  return (
    <div className="board">
      <div className="card">
        <div className="card__head"><h3>Push a customer segment to a VBOUT list</h3></div>
        <div className="card__body">
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <label className="out-field"><span>List</span>
              <select className="rm-in" value={listId} onChange={e => setListId(e.target.value)}>
                {lists.map(l => <option key={l.id} value={l.id}>{l.name}{l.count ? ` · ${l.count}` : ""}</option>)}
              </select>
            </label>
            <label className="out-field"><span>Tag synced contacts (optional — triggers automations)</span>
              <input className="rm-in" value={tag} onChange={e => setTag(e.target.value)} placeholder="e.g. dtf-crm-2026" /></label>
            <label className="out-field"><span>Filter customers (name · email · country · tag)</span>
              <input className="rm-in" value={query} onChange={e => setQuery(e.target.value)} placeholder="blank = everyone" /></label>
            <label className="out-field"><span>Cap (optional)</span>
              <input className="rm-in" value={max} onChange={e => setMax(e.target.value.replace(/[^\d]/g, ""))} placeholder="no cap" inputMode="numeric" /></label>
          </div>
          <label style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 12 }}>
            <input type="checkbox" checked={consentOnly} onChange={e => setConsentOnly(e.target.checked)} />
            <span>Only marketing-subscribed customers <span className="dim">(recommended for promotional sends)</span></span>
          </label>
          {list && list.fields && (
            <div className="dim" style={{ marginTop: 10, fontSize: 12 }}>
              Mapping into <b>{list.name}</b>: {list.fields.map(f => f.label).join(" · ")}
            </div>
          )}
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginTop: 14 }}>
            <button className="btn btn--primary" disabled={syncing || !listId} onClick={runSync}>
              {syncing ? "Syncing…" : `Push ~${estimate} contact${estimate === 1 ? "" : "s"}`}
            </button>
            <span className="dim">≈ {estimate} match the current filters in loaded data (server re-checks at push time).</span>
          </div>
          {err && <div className="warn-banner" style={{ marginTop: 12 }}><Icon name="spark" /> {err}</div>}
          {result && (
            <div className="card" style={{ marginTop: 14, background: "#f6fdf9" }}>
              <div className="card__body">
                <b>{result.synced}</b> synced to {result.list && result.list.name}
                {result.tagged ? <> · <b>{result.tagged}</b> tagged</> : null}
                {result.skippedNoEmail ? <> · {result.skippedNoEmail} skipped (no email)</> : null}
                {result.failed ? <span style={{ color: "#e03131" }}> · {result.failed} failed</span> : null}
                {result.errors && result.errors.length > 0 && (
                  <details style={{ marginTop: 8 }}>
                    <summary className="dim">show {result.errors.length} error{result.errors.length === 1 ? "" : "s"}</summary>
                    <ul style={{ margin: "6px 0 0", fontSize: 12 }}>{result.errors.map((e, i) => <li key={i}>{e.email}: {e.error}</li>)}</ul>
                  </details>
                )}
                <div className="dim" style={{ marginTop: 8, fontSize: 12 }}>Now compose and send the campaign to this list in VBOUT.</div>
              </div>
            </div>
          )}
        </div>
      </div>

      <div className="card" style={{ marginTop: 14 }}>
        <div className="card__head"><h3>Recent campaigns</h3><span className="right kick">{campaigns ? campaigns.length : ""}</span></div>
        <div className="card__body--flush tbl-wrap">
          {!campaigns ? <SkeletonRows rows={4} /> : campaigns.length === 0 ? (
            <div className="empty" style={{ padding: 24 }}><div className="t">No sent campaigns yet</div></div>
          ) : (
            <table className="tbl">
              <thead><tr><th>Campaign</th><th>Sent</th><th>Performance</th></tr></thead>
              <tbody>
                {campaigns.map(c => (
                  <tr key={c.id}>
                    <td style={{ maxWidth: 380, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }} title={c.subject || c.name}>{c.name}</td>
                    <td className="dim" style={{ whiteSpace: "nowrap" }}>{c.sentDate || "—"}</td>
                    <td>
                      {openStats[c.id]
                        ? <CampaignStats id={c.id} />
                        : <button className="linklike" onClick={() => setOpenStats(s => ({ ...s, [c.id]: true }))}>view stats</button>}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>
      </div>
    </div>
  );
}
