// =================================================================
// pw-screens-engagement.jsx — Publisher Admin · Engagement Rules
// =================================================================

const ruleLabel = (r) => r.label || String(r.event_type || "").replace(/[_-]/g, " ").replace(/\b\w/g, c => c.toUpperCase());
const eventSlug = (s) => String(s || "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");

const EngagementRuleDrawer = ({ open, onClose, rule, existing, onSave }) => {
  const blank = { event_type: "", label: "", coins: 5, daily_cap: 50, status: "active" };
  const [f, setF] = React.useState(blank);
  const isEdit = !!rule;
  React.useEffect(() => { if (open) setF(rule ? { ...blank, ...rule, label: ruleLabel(rule) } : blank); }, [open, rule]);
  const set = (patch) => setF(prev => ({ ...prev, ...patch }));
  const slug = eventSlug(f.event_type);
  const exists = !isEdit && slug && existing.includes(slug);
  const canSave = slug && f.label.trim() && Number(f.coins) >= 0 && !exists;
  return (
    <Drawer open={open} onClose={onClose} title={isEdit ? "Edit engagement rule" : "Create engagement rule"} width={620}
      footer={<><Btn kind="secondary" onClick={onClose}>Cancel</Btn>
        <Btn kind="primary" disabled={!canSave} onClick={() => { onSave({ ...f, event_type: slug }); onClose(); }}>{isEdit ? "Save rule" : "Create rule"}</Btn></>}>
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        <FieldRow label="Event type" hint="Stable event key sent by the website or app SDK.">
          <Input disabled={isEdit} value={f.event_type} onChange={e => set({ event_type: eventSlug(e.target.value) })} placeholder="article_read"/>
          {exists && <div style={{ fontSize: 11.5, color: "var(--bad)", marginTop: 5 }}>This event type already exists.</div>}
        </FieldRow>
        <FieldRow label="Display name">
          <Input value={f.label} onChange={e => set({ label: e.target.value })} placeholder="Article read"/>
        </FieldRow>
        <FieldGroup cols={2}>
          <FieldRow label="Coins per event">
            <NumberStepper value={Number(f.coins || 0)} onChange={v => set({ coins: v })} min={0} max={100000} step={1} suffix="coins"/>
          </FieldRow>
          <FieldRow label="Daily cap" hint="Maximum coins a reader can earn from this rule per day.">
            <NumberStepper value={Number(f.daily_cap || 0)} onChange={v => set({ daily_cap: v || null })} min={0} max={100000} step={5} suffix="coins"/>
          </FieldRow>
        </FieldGroup>
        <FieldRow label="Status">
          <SegmentedControl value={f.status} onChange={v => set({ status: v })} options={[{ label: "Active", value: "active" }, { label: "Paused", value: "paused" }]}/>
        </FieldRow>
        <InlineHelp icon={<IconInfo size={13}/>}>Rules control event-based earning. Manual reader adjustments happen from the reader wallet detail panel.</InlineHelp>
      </div>
    </Drawer>
  );
};

const BulkGrantDrawer = ({ open, onClose, users, onGrant }) => {
  const [f, setF] = React.useState({ from: "2026-06-01", to: "2026-06-30", coins: 50, reason: "Registration period bonus" });
  React.useEffect(() => { if (open) setF({ from: "2026-06-01", to: "2026-06-30", coins: 50, reason: "Registration period bonus" }); }, [open]);
  const set = (patch) => setF(prev => ({ ...prev, ...patch }));
  const from = `${f.from}T00:00:00.000Z`;
  const to = `${f.to}T23:59:59.999Z`;
  const eligible = (users || []).filter(u => {
    const t = new Date(u.created_at || 0).getTime();
    return t >= new Date(from).getTime() && t <= new Date(to).getTime();
  });
  const canGrant = f.from && f.to && f.reason.trim() && Number(f.coins) > 0 && new Date(from) <= new Date(to);
  return (
    <Drawer open={open} onClose={onClose} title="Grant coins by registration date" width={560}
      footer={<><Btn kind="secondary" onClick={onClose}>Cancel</Btn>
        <Btn kind="primary" disabled={!canGrant} onClick={() => { onGrant({ ...f, from, to, eligible }); onClose(); }}>Grant to {eligible.length} readers</Btn></>}>
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        <FieldGroup cols={2}>
          <FieldRow label="Registered from"><Input type="date" value={f.from} onChange={e => set({ from: e.target.value })}/></FieldRow>
          <FieldRow label="Registered to"><Input type="date" value={f.to} onChange={e => set({ to: e.target.value })}/></FieldRow>
        </FieldGroup>
        <FieldRow label="Coins">
          <NumberStepper value={Number(f.coins || 0)} onChange={v => set({ coins: v })} min={1} max={100000} step={10} suffix="coins"/>
        </FieldRow>
        <FieldRow label="Audit reason">
          <Input value={f.reason} onChange={e => set({ reason: e.target.value })} placeholder="Why these readers receive coins"/>
        </FieldRow>
        <Banner tone="info" icon={<IconInfo size={15}/>}>
          {eligible.length} current readers match this registration window. The live API applies the grant idempotently and records an audit campaign.
        </Banner>
      </div>
    </Drawer>
  );
};

const EngagementRulesScreen = ({ data, setData }) => {
  const [q, setQ] = React.useState("");
  const [status, setStatus] = React.useState("all");
  const [drawer, setDrawer] = React.useState(false);
  const [editing, setEditing] = React.useState(null);
  const [bulkOpen, setBulkOpen] = React.useState(false);
  const rules = data.engagementRules || [];
  const active = rules.filter(r => r.status === "active").length;
  const paused = rules.filter(r => r.status === "paused").length;
  const avgCoins = rules.length ? Math.round(rules.reduce((a, r) => a + Number(r.coins || 0), 0) / rules.length) : 0;
  const maxCap = rules.reduce((m, r) => Math.max(m, Number(r.daily_cap || 0)), 0);
  const rows = rules.filter(r => {
    const hay = `${r.event_type} ${ruleLabel(r)} ${r.status}`.toLowerCase();
    return (!q || hay.includes(q.toLowerCase())) && (status === "all" || r.status === status);
  });

  const saveRule = (f) => {
    const body = { label: f.label, coins: Number(f.coins || 0), daily_cap: f.daily_cap == null ? null : Number(f.daily_cap), status: f.status || "active" };
    window.__api.write("updateEngagementRule",
      d => {
        const current = d.engagementRules || [];
        const existing = current.some(r => r.event_type === f.event_type);
        return { ...d, engagementRules: existing
          ? current.map(r => r.event_type === f.event_type ? { ...r, ...body, event_type: f.event_type } : r)
          : [{ ...body, event_type: f.event_type }, ...current] };
      },
      { params: { event_type: f.event_type }, body, ok: editing ? "Rule updated" : "Rule created", err: "Couldn’t save rule" });
  };

  const grantBulk = (f) => {
    const id = `bulk:${f.from}:${f.to}:${f.coins}:${Date.now()}`;
    window.__api.write("bulkGrantCoins",
      d => ({ ...d, users: (d.users || []).map(u => f.eligible.some(e => e.id === u.id || e.user_id === u.user_id)
        ? { ...u, balance_coins: Number(u.balance_coins || 0) + Number(f.coins || 0), ledger: [{ at: new Date().toISOString(), event: "bulk_coin_grant", delta: Number(f.coins || 0) }, ...(u.ledger || [])] }
        : u) }),
      { body: { from: f.from, to: f.to, coins: Number(f.coins), reason: f.reason, idempotency_key: id }, ok: "Bulk grant submitted", err: "Bulk grant failed" });
  };

  return (
    <Screen>
      <PageHead icon={IconGauge} title="Engagement Rules" subtitle="Configure reader earning events and run one-time registration-period bonuses."
        actions={<div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
          <Btn kind="secondary" icon={<IconCoin size={15}/>} onClick={() => setBulkOpen(true)}>Bulk grant</Btn>
          <Btn kind="primary" icon={<IconPlus size={15}/>} onClick={() => { setEditing(null); setDrawer(true); }}>Create Rule</Btn>
        </div>}/>

      <KpiGrid>
        <StatCard label="Active rules" value={active} sub={`${rules.length} total`} icon={<IconCheck size={16}/>}/>
        <StatCard label="Paused rules" value={paused} sub="not earning" icon={<IconInfo size={16}/>}/>
        <StatCard label="Avg coins" value={avgCoins} sub="per event" icon={<IconCoin size={16}/>}/>
        <StatCard label="Highest cap" value={fmt.compact(maxCap)} sub="coins per day" icon={<IconGauge size={16}/>}/>
      </KpiGrid>

      <Toolbar search={q} onSearchChange={setQ} searchPlaceholder="Search rules">
        <Select value={status} onChange={setStatus} style={{ width: 150 }} options={[{ label: "All statuses", value: "all" }, { label: "Active", value: "active" }, { label: "Paused", value: "paused" }]}/>
      </Toolbar>

      <Card padded={false}>
        <DataTable rows={rows} keyField="event_type" rowsPerPage={8} defaultSort={{ key: "event_type", dir: "asc" }} onRowClick={(r) => { setEditing(r); setDrawer(true); }}
          empty={<EmptyState icon={<IconGauge size={30}/>} title="No engagement rules" description="Create earning rules for reader events."/>}
          columns={[
            { key: "label", label: "Rule", render: r => <div><div style={{ fontWeight: 600, color: "var(--ink)" }}>{ruleLabel(r)}</div><div style={{ fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--muted)" }}>{r.event_type}</div></div> },
            { key: "coins", label: "Coins", align: "right", render: r => <CoinChip amount={r.coins} tone="pos"/> },
            { key: "daily_cap", label: "Daily cap", align: "right", render: r => <span style={{ fontFamily: "var(--mono)", fontSize: 12.5 }}>{r.daily_cap == null ? "No cap" : fmt.number(r.daily_cap)}</span> },
            { key: "status", label: "Status", render: r => <StatusPill status={r.status}/> },
            { key: "_e", label: "", sortable: false, align: "right", render: r => <Btn kind="ghost" size="sm" icon={<IconPencil size={13}/>} onClick={() => { setEditing(r); setDrawer(true); }}>Edit</Btn> },
          ]}/>
      </Card>

      <EngagementRuleDrawer open={drawer} onClose={() => setDrawer(false)} rule={editing} existing={rules.map(r => r.event_type)} onSave={saveRule}/>
      <BulkGrantDrawer open={bulkOpen} onClose={() => setBulkOpen(false)} users={data.users || []} onGrant={grantBulk}/>
    </Screen>
  );
};

Object.assign(window, { EngagementRulesScreen, EngagementRuleDrawer, BulkGrantDrawer });
