// admin.jsx — AFEX PAY admin panel
function AdminDashboard({ go }) {
  const [period, setPeriod] = React.useState("mes");
  const { data: ov } = useApi(() => api.admin.overview(period), [period]);
  const { data: vol } = useApi(() => api.admin.volumeDaily(30), []);
  const { data: rev } = useApi(() => api.admin.revenueMonthly(12), []);
  const { data: sl } = useApi(() => api.admin.sellers({ pageSize: 6 }), []);
  const m = ov && ov.metrics;
  const top = sl ? [...sl.data].sort((a, b) => b.paidVolumeCents - a.paidVolumeCents) : [];
  const OWNER = { own_cnpj: ["CNPJ próprio", "badge-orange"], seller: ["Sub-seller", "badge-gray"] };

  return (
    <div className="col gap-24 fade-up">
      <PageHead title="Visão geral" sub="Plataforma AFEX Pay · todos os sellers">
        <Segmented options={[{ value: "hoje", label: "Hoje" }, { value: "mes", label: "Mês" }, { value: "ano", label: "Ano" }]} value={period} onChange={setPeriod} />
        <button className="btn btn-ghost" onClick={() => exportCsv("volume-diario", (vol || []).map(v => ({ data: v.date || "", valor_cents: v.valueCents })))}><I.download size={16} /> Relatório</button>
      </PageHead>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 16 }} className="kpi-grid">
        <KPI label="Volume processado" value={m ? fmtMetric(m.volumeProcessed, { cents: false }) : "—"} delta={m && m.volumeProcessed.deltaPct} icon="bolt" accent="var(--accent)" />
        <KPI label="Receita AFEX Pay" value={m ? fmtMetric(m.afexRevenue, { cents: false }) : "—"} delta={m && m.afexRevenue.deltaPct} icon="money" accent="var(--green)" />
        <KPI label="Sellers ativos" value={m ? fmtMetric(m.activeSellers) : "—"} delta={m && m.activeSellers.deltaPct} icon="users" accent="var(--blue)" />
        <KPI label="Taxa média aprovação" value={m ? fmtMetric(m.avgApprovalRate) : "—"} delta={m && m.avgApprovalRate.deltaPct} icon="checkCircle" accent="var(--green)" />
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16 }} className="kpi-grid">
        <KPI label="Sellers pendentes" value={m ? fmtMetric(m.pendingSellers) : "—"} icon="clock" accent="var(--amber)" hint="aguardando KYC" />
        <KPI label="Chargebacks (mês)" value={m ? fmtMetric(m.chargebackRate, { d: 2 }) : "—"} delta={m && m.chargebackRate.deltaPct} icon="warn" accent="var(--red)" />
        <KPI label="Repasses pendentes" value={m ? fmtMetric(m.pendingPayouts, { cents: false }) : "—"} icon="bank" accent="var(--blue)" hint="próximas 24h" />
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "1.7fr 1fr", gap: 16 }} className="chart-grid">
        <SCard title="Volume diário processado" sub="Plataforma · 30 dias" right={<span className="row gap-6" style={{ fontSize: 12.5 }}><span style={{ width: 8, height: 8, borderRadius: 2, background: "var(--accent)" }} />Volume</span>}>
          <AreaChart data={vol ? vol.map(v => v.valueCents / 100) : DATA.series30} height={210} color="var(--accent)" />
        </SCard>
        <SCard title="Receita AFEX Pay" sub="Crescimento mensal">
          <Bars data={rev ? rev.map(r => r.valueCents / 100000) : DATA.seriesMonthly.map(v => v / 1000)} labels={["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]} height={180} color="var(--green)" />
          <div className="row between" style={{ marginTop: 16, paddingTop: 14, borderTop: "1px solid var(--line)" }}>
            <div className="col"><span className="faint" style={{ fontSize: 11.5 }}>MRR atual</span><span className="num" style={{ fontWeight: 600, fontSize: 18 }}>{m ? fmtMetric(m.afexRevenue, { cents: false }) : "—"}</span></div>
            <span className="delta delta-up"><I.arrowUp size={13} />28,4% YoY</span>
          </div>
        </SCard>
      </div>
      <SCard title="Top sellers" sub="Maior volume processado no mês" pad={false} right={<button className="btn btn-subtle btn-sm" onClick={() => go("a/sellers")}>Ver todos <I.chevR size={15} /></button>}>
        <table className="tbl"><thead><tr><th>#</th><th>Empresa</th><th>Tipo</th><th>Comissão AFEX</th><th>Status</th><th style={{ textAlign: "right" }}>Volume</th></tr></thead>
          <tbody>{top.map((s, i) => (
            <tr key={s.id} className="clickable" onClick={() => go("a/sellers")}>
              <td className="num faint" style={{ fontWeight: 600 }}>{i + 1}</td>
              <td><div className="row gap-10"><Avatar name={s.legalName} size={32} /><span style={{ fontWeight: 600 }}>{s.legalName}</span></div></td>
              <td><span className={"badge " + OWNER[s.ownerType][1]}>{OWNER[s.ownerType][0]}</span></td>
              <td className="num muted">{cBRL(s.myCommissionCents, { cents: false })}</td>
              <td><Status s={s.kycStatus} /></td>
              <td className="num" style={{ textAlign: "right", fontWeight: 600 }}>{cBRL(s.paidVolumeCents, { cents: false })}</td>
            </tr>))}</tbody></table>
      </SCard>
    </div>
  );
}

/* ---------------- Sellers ---------------- */
const KYC_FILTERS = [{ value: "", label: "Todos" }, { value: "approved", label: "Ativo" }, { value: "pending", label: "Pendente" }, { value: "blocked", label: "Bloqueado" }];
const OWNER_TYPE = { own_cnpj: ["CNPJ próprio", "badge-orange"], seller: ["Sub-seller", "badge-gray"] };
function AdminSellers() {
  const [sel, setSel] = React.useState(null);
  const [kyc, setKyc] = React.useState("");
  const [q, setQ] = React.useState("");
  const [page, setPage] = React.useState(1);
  const [newOpen, setNewOpen] = React.useState(false);
  const [tick, setTick] = React.useState(0);
  const { data } = useApi(() => api.admin.sellers({ q, kycStatus: kyc, page, pageSize: 10 }), [q, kyc, page, tick]);
  const { data: all } = useApi(() => api.admin.sellers({ pageSize: 999 }), [tick]);
  const rows = data ? data.data : [];
  const allRows = all ? all.data : [];
  const cnt = (k) => allRows.filter(s => s.kycStatus === k).length;
  const totalVol = allRows.reduce((a, s) => a + s.paidVolumeCents, 0);
  return (
    <div className="col gap-24 fade-up">
      <PageHead title="Sellers" sub={`${all ? all.pagination.total : "—"} contas na plataforma`}>
        <button className="btn btn-ghost" onClick={() => exportCsv("sellers", allRows.map(s => ({ id: s.id, empresa: s.legalName, documento: s.document, tipo: s.ownerType, kyc: s.kycStatus, comissao_cents: s.myCommissionCents, volume_cents: s.paidVolumeCents })))}><I.download size={16} /> Exportar</button>
        <button className="btn btn-primary" onClick={() => setNewOpen(true)}><I.plus size={16} /> Novo seller</button>
      </PageHead>
      <div className="row gap-16 wrap">
        <KPI label="Ativos" value={cnt("approved")} icon="checkCircle" accent="var(--green)" />
        <KPI label="Pendentes" value={cnt("pending")} icon="clock" accent="var(--amber)" />
        <KPI label="Bloqueados" value={cnt("blocked")} icon="xCircle" accent="var(--red)" />
        <KPI label="Volume total" value={cBRL(totalVol, { cents: false })} icon="bolt" accent="var(--accent)" />
      </div>
      <div className="card col" style={{ overflow: "hidden" }}>
        <div className="row between wrap gap-12" style={{ padding: 16, borderBottom: "1px solid var(--line)" }}>
          <div className="input-affix" style={{ width: 280 }}><I.search size={16} className="affix affix-l" /><input className="input" placeholder="Buscar empresa ou documento" value={q} onChange={e => { setQ(e.target.value); setPage(1); }} /></div>
          <Segmented options={KYC_FILTERS} value={kyc} onChange={v => { setKyc(v); setPage(1); }} />
        </div>
        <div style={{ overflowX: "auto" }}>
          <table className="tbl"><thead><tr><th>Empresa</th><th>Documento</th><th>Tipo</th><th>KYC</th><th>Comissão AFEX</th><th style={{ textAlign: "right" }}>Volume</th><th></th></tr></thead>
            <tbody>{rows.map(s => (
              <tr key={s.id} className="clickable" onClick={() => setSel(s)}>
                <td><div className="row gap-10"><Avatar name={s.legalName} size={34} /><div className="col" style={{ lineHeight: 1.2 }}><span style={{ fontWeight: 600, fontSize: 13.5 }}>{s.legalName}</span><span className="faint mono" style={{ fontSize: 11.5 }}>{s.id}</span></div></div></td>
                <td className="muted mono" style={{ fontSize: 13 }}>{s.document}</td>
                <td><span className={"badge " + OWNER_TYPE[s.ownerType][1]}>{OWNER_TYPE[s.ownerType][0]}</span></td>
                <td><Status s={s.kycStatus} /></td>
                <td className="num muted">{cBRL(s.myCommissionCents, { cents: false })}</td>
                <td className="num" style={{ textAlign: "right", fontWeight: 600 }}>{cBRL(s.paidVolumeCents, { cents: false })}</td>
                <td><I.chevR size={16} style={{ color: "var(--ink-faint)" }} /></td>
              </tr>))}</tbody></table>
        </div>
        <div className="row between" style={{ padding: "14px 20px", borderTop: "1px solid var(--line)" }}>
          <span className="faint" style={{ fontSize: 13 }}>{data ? `Página ${data.pagination.page} de ${data.pagination.totalPages}` : "Carregando…"}</span>
          <div className="row gap-8">
            <button className="btn btn-ghost btn-sm" disabled={page <= 1} onClick={() => setPage(page - 1)}><I.chevL size={15} /></button>
            <button className="btn btn-ghost btn-sm" disabled={data && page >= data.pagination.totalPages} onClick={() => setPage(page + 1)}>Próximo <I.chevR size={15} /></button>
          </div>
        </div>
      </div>
      <SellerDetail seller={sel} onClose={() => setSel(null)} />
      {newOpen && <NewSellerModal onClose={() => setNewOpen(false)} onCreated={() => { setNewOpen(false); setTick(t => t + 1); }} />}
    </div>
  );
}

function NewSellerModal({ onClose, onCreated }) {
  const { data: plans } = useApi(() => api.admin.feePlans(), []);
  const [f, setF] = React.useState({ ownerType: "seller", legalName: "", document: "", email: "", feePlanId: "" });
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState(null);
  React.useEffect(() => { if (plans && plans.length && !f.feePlanId) setF(s => ({ ...s, feePlanId: plans[0].id })); }, [plans]);
  const doc = f.document.replace(/\D/g, "");
  const can = f.legalName.trim() && doc.length === 14 && f.feePlanId;
  const save = async () => {
    setBusy(true); setErr(null);
    try {
      await api.admin.createSubmerchant({
        ownerType: f.ownerType, legalName: f.legalName.trim(), document: doc, feePlanId: f.feePlanId,
        ...(f.email.trim() ? { email: f.email.trim() } : {}),
      });
      onCreated();
    } catch (e) { setErr(e.message); setBusy(false); }
  };
  return (
    <Modal open onClose={onClose} width={480} title="Novo seller" sub="Cadastrar uma loja na plataforma">
      <div className="col gap-16" style={{ padding: 22 }}>
        <div className="field"><label className="label">Tipo de conta</label>
          <Segmented options={[{ value: "seller", label: "Sub-seller (terceiro)" }, { value: "own_cnpj", label: "CNPJ próprio" }]} value={f.ownerType} onChange={v => setF(s => ({ ...s, ownerType: v }))} /></div>
        <div className="field"><label className="label">Razão social</label>
          <input className="input" value={f.legalName} onChange={e => setF(s => ({ ...s, legalName: e.target.value }))} placeholder="Loja Exemplo LTDA" autoFocus /></div>
        <div className="field"><label className="label">CNPJ</label>
          <input className="input mono" value={f.document} onChange={e => setF(s => ({ ...s, document: e.target.value }))} placeholder="00.000.000/0000-00" /></div>
        <div className="field"><label className="label">E‑mail (opcional)</label>
          <input className="input" value={f.email} onChange={e => setF(s => ({ ...s, email: e.target.value }))} placeholder="contato@loja.com" /></div>
        <div className="field"><label className="label">Tabela de taxa</label>
          <select className="input" value={f.feePlanId} onChange={e => setF(s => ({ ...s, feePlanId: e.target.value }))}>
            {!plans ? <option>Carregando…</option> : plans.length === 0 ? <option value="">Crie uma tabela em Gestão de taxas</option> : plans.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
          </select></div>
        <span className="faint" style={{ fontSize: 12 }}>{f.ownerType === "own_cnpj" ? "Loja própria: aprovada na hora, sem split." : "Sub-seller: entra como pendente para análise de KYC em Compliance."}</span>
        {err && <span style={{ color: "var(--red)", fontSize: 13 }}>{err}</span>}
        <div className="row gap-10" style={{ justifyContent: "flex-end" }}>
          <button className="btn btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn btn-primary" disabled={busy || !can} onClick={save}>{busy ? "Criando…" : "Criar seller"}</button>
        </div>
      </div>
    </Modal>
  );
}

const DOC_LABEL = { company_doc: "Documento da empresa", rep_doc: "Documento do responsável", selfie_with_doc: "Selfie com documento", address_proof: "Comprovante de endereço" };
function SellerDetail({ seller, onClose }) {
  const [tab, setTab] = React.useState("Dados");
  const [kyc, setKyc] = React.useState(null);
  const [docs, setDocs] = React.useState(null);
  const [fee, setFee] = React.useState(null);
  React.useEffect(() => {
    if (seller) {
      setTab("Dados"); setKyc(seller.kycStatus); setDocs(null); setFee(null);
      api.admin.sellerDocuments(seller.id).then(setDocs).catch(() => setDocs([]));
      api.admin.sellerFee(seller.id).then(setFee).catch(() => setFee(null));
    }
  }, [seller]);
  const decide = async (status) => { setKyc(status); try { await api.admin.kycDecision(seller.id, status); } catch (e) { /* keep UI state */ } };
  if (!seller) return null;
  const tabs = ["Dados", "Documentos", "Taxas", "Histórico"];
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, zIndex: 200, background: "rgba(0,0,0,0.55)", backdropFilter: "blur(4px)", display: "flex", justifyContent: "flex-end" }} className="fade-in">
      <div onClick={e => e.stopPropagation()} style={{ width: 560, maxWidth: "100%", height: "100%", background: "var(--surface)", borderLeft: "1px solid var(--line)", overflow: "auto" }}>
        <div style={{ padding: "24px 28px", borderBottom: "1px solid var(--line)", position: "sticky", top: 0, background: "var(--surface)", zIndex: 2 }}>
          <div className="row between" style={{ marginBottom: 18 }}>
            <button className="iconbtn" onClick={onClose}><I.x size={18} /></button>
            <div className="row gap-8">
              <button className="btn btn-danger btn-sm" onClick={() => decide("rejected")}><I.lock size={14} /> Reprovar</button>
              <button className="btn btn-primary btn-sm" onClick={() => decide("approved")}><I.check size={14} /> Aprovar</button>
            </div>
          </div>
          <div className="row gap-16">
            <Avatar name={seller.legalName} size={56} />
            <div className="col gap-4"><h2 style={{ fontSize: 22 }}>{seller.legalName}</h2><span className="faint mono" style={{ fontSize: 13 }}>{seller.id} · {seller.document}</span><Status s={kyc || seller.kycStatus} /></div>
          </div>
        </div>
        <div className="row gap-6" style={{ padding: "0 28px", borderBottom: "1px solid var(--line)" }}>
          {tabs.map(t => <button key={t} onClick={() => setTab(t)} style={{ background: "none", border: "none", padding: "14px 4px", marginRight: 20, fontSize: 14, fontWeight: 600, color: tab === t ? "var(--ink)" : "var(--ink-faint)", borderBottom: tab === t ? "2px solid var(--accent)" : "2px solid transparent", marginBottom: -1 }}>{t}</button>)}
        </div>
        <div style={{ padding: 28 }}>
          {tab === "Dados" && <div className="col gap-20 fade-up">
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
              {[["Saldo disponível", cBRL(seller.availableCents)], ["Saldo reservado", cBRL(seller.reservedCents)], ["Volume liquidado", cBRL(seller.paidVolumeCents, { cents: false })], ["Comissão AFEX", cBRL(seller.myCommissionCents, { cents: false })]].map(([k, v]) => (
                <div key={k} className="card card-pad col gap-4" style={{ padding: 16 }}><span className="faint" style={{ fontSize: 12 }}>{k}</span><span className="num" style={{ fontSize: 20, fontWeight: 600 }}>{v}</span></div>))}
            </div>
            <div className="card" style={{ overflow: "hidden" }}>{[["Documento", seller.document], ["Tipo de conta", OWNER_TYPE[seller.ownerType][0]], ["KYC", kyc || seller.kycStatus], ["Cadastro", new Date(seller.createdAt).toLocaleDateString("pt-BR")]].map(([k, v], i) => (
              <div key={k} className="row between" style={{ padding: "14px 18px", borderTop: i ? "1px solid var(--line)" : "none" }}><span className="muted" style={{ fontSize: 13.5 }}>{k}</span><span style={{ fontSize: 13.5, fontWeight: 600 }}>{v}</span></div>))}</div>
          </div>}
          {tab === "Documentos" && <div className="col gap-12 fade-up">
            {!docs ? <span className="faint">Carregando…</span>
              : docs.length === 0 ? <span className="faint">Nenhum documento enviado por este seller.</span>
              : docs.map(d => (
              <div key={d.id} className="card card-pad row between" style={{ padding: 16 }}>
                <div className="row gap-12"><I.doc size={20} style={{ color: "var(--ink-soft)" }} /><div className="col"><span style={{ fontSize: 14, fontWeight: 500 }}>{DOC_LABEL[d.type] || d.type}</span><span className="faint" style={{ fontSize: 12 }}>{d.filename}</span></div></div>
                <button className="iconbtn" title="Abrir documento" onClick={() => api.admin.openDocument(seller.id, d.id).catch(e => alert(e.message))}><I.eye size={16} /></button>
              </div>))}</div>}
          {tab === "Taxas" && <SellerFeeTab seller={seller} fee={fee} onFee={setFee} />}
          {tab === "Histórico" && <div className="col gap-2 fade-up">{[["Conta aprovada", "há 4 meses", "green"], ["Taxas ajustadas para 3,49%", "há 2 meses", "blue"], ["Limite aumentado", "há 1 mês", "blue"], ["Alerta de chargeback resolvido", "há 12 dias", "amber"]].map(([t, time, c], i) => (
            <div key={i} className="row gap-12" style={{ padding: "14px 0", borderTop: i ? "1px solid var(--line)" : "none" }}><div style={{ width: 8, height: 8, borderRadius: "50%", background: `var(--${c})`, marginTop: 6, flexShrink: 0 }} /><div className="col"><span style={{ fontSize: 14 }}>{t}</span><span className="faint" style={{ fontSize: 12 }}>{time}</span></div></div>))}</div>}
        </div>
      </div>
    </div>
  );
}

/* ---------------- Transações (admin) ---------------- */
const A_METH = [{ value: "", label: "Todos" }, { value: "pix", label: "PIX" }, { value: "card", label: "Crédito" }];
const A_STAT = [{ value: "", label: "Todas" }, { value: "paid", label: "Paga" }, { value: "pending", label: "Pendente" }, { value: "refunded", label: "Estornada" }, { value: "charged_back", label: "Chargeback" }, { value: "failed", label: "Falha" }];
function AdminTransacoes() {
  const [status, setStatus] = React.useState("");
  const [method, setMethod] = React.useState("");
  const [page, setPage] = React.useState(1);
  const { data } = useApi(() => api.admin.transactions({ status, method, page, pageSize: 20 }), [status, method, page]);
  const [acted, setActed] = React.useState({});
  const rows = data ? data.data : [];
  const refund = async (id) => {
    setActed(a => ({ ...a, [id]: "busy" }));
    try { await api.admin.refund(id); setActed(a => ({ ...a, [id]: "refunded" })); }
    catch (e) { alert(e.message); setActed(a => ({ ...a, [id]: undefined })); }
  };
  return (
    <div className="col gap-24 fade-up">
      <PageHead title="Transações" sub="Monitoramento global da plataforma">
        <Segmented options={A_METH} value={method} onChange={v => { setMethod(v); setPage(1); }} />
        <Segmented options={A_STAT} value={status} onChange={v => { setStatus(v); setPage(1); }} />
      </PageHead>
      <div className="card" style={{ overflow: "hidden" }}>
        <div style={{ overflowX: "auto" }}>
          <table className="tbl"><thead><tr><th>ID</th><th>Seller</th><th>Método</th><th>Status</th><th>Líquido</th><th style={{ textAlign: "right" }}>Valor</th><th style={{ textAlign: "right" }}>Ação</th></tr></thead>
            <tbody>{!data ? <tr><td colSpan={7} className="faint" style={{ padding: 28, textAlign: "center" }}>Carregando…</td></tr>
              : rows.length === 0 ? <tr><td colSpan={7} className="faint" style={{ padding: 28, textAlign: "center" }}>Nenhuma transação.</td></tr>
              : rows.map(t => {
              const st = acted[t.id] === "refunded" ? "refunded" : t.status;
              return (
              <tr key={t.id}>
                <td className="mono" style={{ color: "var(--accent)", fontWeight: 600 }}>{t.id.slice(-8)}</td>
                <td style={{ fontWeight: 600 }}>{t.sellerName}</td>
                <td><Method m={t.method} /></td><td><Status s={st} /></td>
                <td className="num muted">{cBRL(t.netToSubmerchantCents)}</td>
                <td className="num" style={{ textAlign: "right", fontWeight: 600 }}>{cBRL(t.amountCents)}</td>
                <td style={{ textAlign: "right" }}>{st === "paid"
                  ? <button className="btn btn-subtle btn-sm" disabled={acted[t.id] === "busy"} onClick={() => refund(t.id)}>{acted[t.id] === "busy" ? "…" : "Estornar"}</button>
                  : <span className="faint" style={{ fontSize: 12 }}>—</span>}</td>
              </tr>);})}</tbody></table>
        </div>
        <div className="row between" style={{ padding: "14px 20px", borderTop: "1px solid var(--line)" }}>
          <span className="faint" style={{ fontSize: 13 }}>{data ? `Página ${data.pagination.page} de ${data.pagination.totalPages} · ${data.pagination.total} transações` : "Carregando…"}</span>
          <div className="row gap-8">
            <button className="btn btn-ghost btn-sm" disabled={page <= 1} onClick={() => setPage(page - 1)}><I.chevL size={15} /></button>
            <button className="btn btn-ghost btn-sm" disabled={data && page >= data.pagination.totalPages} onClick={() => setPage(page + 1)}>Próximo <I.chevR size={15} /></button>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------------- Taxas (admin gestão) ---------------- */
const CB_LIABILITY = { submerchant: "Risco no seller", marketplace: "Risco na Afex" };

// Stable (module-scope) number field. Defining it here — not inside the modal —
// keeps the input from remounting on each keystroke (which would drop focus).
function FeeNumField({ label, value, onChange, affix = "%", step = "0.01", side = "r" }) {
  return (
    <div className="field"><label className="label">{label}</label>
      <div className="input-affix">
        {side === "l" && <span className="affix affix-l">{affix}</span>}
        <input className="input num" type="number" step={step} value={value} onChange={onChange} />
        {side === "r" && <span className="affix affix-r">{affix}</span>}
      </div>
    </div>
  );
}

function FeePlanModal({ plan, onClose, onSaved }) {
  const editing = !!plan;
  const [f, setF] = React.useState(() => ({
    name: plan ? plan.name : "",
    pixSpreadPercent: plan ? plan.pixSpreadPercent : 2.99,
    cardSpreadPercent: plan ? plan.cardSpreadPercent : 3.99,
    fixedFeeReais: plan ? plan.fixedFeeCents / 100 : 0,
    pixReservePercent: plan ? plan.pixReservePercent : 0,
    cardReservePercent: plan ? plan.cardReservePercent : 0,
    reserveReleaseDays: plan ? plan.reserveReleaseDays : 120,
    cardReleaseDays: plan ? plan.cardReleaseDays : 30,
    chargebackLiability: plan ? plan.chargebackLiability : "submerchant",
  }));
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState(null);
  const num = (k) => (e) => setF(s => ({ ...s, [k]: e.target.value === "" ? "" : +e.target.value }));
  const save = async () => {
    setBusy(true); setErr(null);
    const body = {
      name: f.name.trim(),
      pixSpreadPercent: +f.pixSpreadPercent || 0,
      cardSpreadPercent: +f.cardSpreadPercent || 0,
      fixedFeeCents: Math.round((+f.fixedFeeReais || 0) * 100),
      pixReservePercent: +f.pixReservePercent || 0,
      cardReservePercent: +f.cardReservePercent || 0,
      reserveReleaseDays: Math.round(+f.reserveReleaseDays || 0),
      cardReleaseDays: Math.round(+f.cardReleaseDays || 0),
      chargebackLiability: f.chargebackLiability,
    };
    try {
      if (editing) await api.admin.updateFeePlan(plan.id, body);
      else await api.admin.createFeePlan(body);
      onSaved();
    } catch (e) { setErr(e.message); setBusy(false); }
  };
  return (
    <Modal open onClose={onClose} width={540} title={editing ? "Editar tabela" : "Nova tabela"} sub="Taxa efetiva — cobrada nas transações">
      <div className="col gap-16" style={{ padding: 22 }}>
        <div className="field"><label className="label">Nome da tabela</label>
          <input className="input" value={f.name} onChange={e => setF(s => ({ ...s, name: e.target.value }))} placeholder="Tabela Padrão" /></div>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
          <FeeNumField label="Spread PIX" value={f.pixSpreadPercent} onChange={num("pixSpreadPercent")} />
          <FeeNumField label="Spread Crédito" value={f.cardSpreadPercent} onChange={num("cardSpreadPercent")} />
          <FeeNumField label="Taxa fixa / transação" value={f.fixedFeeReais} onChange={num("fixedFeeReais")} affix="R$" side="l" />
          <FeeNumField label="Liberação cartão" value={f.cardReleaseDays} onChange={num("cardReleaseDays")} affix="dias" step="1" />
          <FeeNumField label="Reserva PIX" value={f.pixReservePercent} onChange={num("pixReservePercent")} />
          <FeeNumField label="Reserva Crédito" value={f.cardReservePercent} onChange={num("cardReservePercent")} />
          <FeeNumField label="Liberação reserva" value={f.reserveReleaseDays} onChange={num("reserveReleaseDays")} affix="dias" step="1" />
          <div className="field"><label className="label">Chargeback</label>
            <Segmented options={[{ value: "submerchant", label: "Seller" }, { value: "marketplace", label: "Afex" }]} value={f.chargebackLiability} onChange={v => setF(s => ({ ...s, chargebackLiability: v }))} /></div>
        </div>
        {err && <span style={{ color: "var(--red)", fontSize: 13 }}>{err}</span>}
        <div className="row gap-10" style={{ justifyContent: "flex-end" }}>
          <button className="btn btn-ghost" onClick={onClose}>Cancelar</button>
          <button className="btn btn-primary" disabled={busy || !f.name.trim()} onClick={save}>{busy ? "Salvando…" : "Salvar tabela"}</button>
        </div>
      </div>
    </Modal>
  );
}

function AdminTaxas() {
  const [tick, setTick] = React.useState(0);
  const { data: plans, loading } = useApi(() => api.admin.feePlans(), [tick]);
  const [modal, setModal] = React.useState(null); // null | "new" | plan
  const list = plans || [];
  const refresh = () => { setModal(null); setTick(t => t + 1); };
  return (
    <div className="col gap-24 fade-up">
      <PageHead title="Gestão de taxas" sub="Tabelas comerciais — taxa efetiva cobrada nas transações">
        <button className="btn btn-primary" onClick={() => setModal("new")}><I.plus size={16} /> Nova tabela</button>
      </PageHead>
      {loading ? <div className="faint">Carregando…</div>
        : list.length === 0 ? <div className="card card-pad faint" style={{ textAlign: "center", padding: 40 }}>Nenhuma tabela criada ainda.</div>
        : <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(290px, 1fr))", gap: 16 }} className="kpi-grid">
          {list.map(p => (
            <div key={p.id} className="card card-pad col gap-12">
              <div className="row between"><span className="section-title">{p.name}</span><span className="badge badge-gray">{CB_LIABILITY[p.chargebackLiability] || p.chargebackLiability}</span></div>
              <div className="divider" />
              <div className="col gap-8">
                {[["PIX", PCT(p.pixSpreadPercent, 2)], ["Crédito", PCT(p.cardSpreadPercent, 2)], ["Taxa fixa", cBRL(p.fixedFeeCents)], ["Reserva PIX / Créd.", PCT(p.pixReservePercent, 1) + " / " + PCT(p.cardReservePercent, 1)], ["Liberação cartão", "D+" + p.cardReleaseDays], ["Liberação reserva", "D+" + p.reserveReleaseDays]].map(([k, v]) => (
                  <div key={k} className="row between" style={{ fontSize: 13 }}><span className="muted">{k}</span><span className="num" style={{ fontWeight: 600 }}>{v}</span></div>))}
              </div>
              <button className="btn btn-ghost btn-sm" onClick={() => setModal(p)}>Editar tabela</button>
            </div>))}
        </div>}
      <SCard title="Valor exibido ≠ valor cobrado" sub="Ajuste por loja na ficha do seller (Sellers → abrir → Taxas)" pad={false}>
        <span className="faint" style={{ fontSize: 13.5, display: "block", padding: "16px 18px" }}>Sellers terceiros sempre exibem a taxa real (transparência). Apenas lojas próprias (own_cnpj) podem exibir um valor diferente do cobrado.</span>
      </SCard>
      {modal && <FeePlanModal plan={modal === "new" ? null : modal} onClose={() => setModal(null)} onSaved={refresh} />}
    </div>
  );
}

function SellerFeeTab({ seller, fee, onFee }) {
  const [d, setD] = React.useState(null);
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState(null);
  React.useEffect(() => {
    if (fee) setD({ pixPercent: fee.displayed.pixPercent, cardPercent: fee.displayed.cardPercent, fixedFeeReais: fee.displayed.fixedFeeCents / 100 });
  }, [fee]);
  if (!fee || !d) return <span className="faint">Carregando…</span>;
  const own = fee.ownerType === "own_cnpj";
  const apply = async (body) => {
    setBusy(true); setErr(null);
    try { onFee(await api.admin.setFeeDisplay(seller.id, body)); }
    catch (e) { setErr(e.message); } finally { setBusy(false); }
  };
  const save = () => apply({ pixPercent: +d.pixPercent || 0, cardPercent: +d.cardPercent || 0, fixedFeeCents: Math.round((+d.fixedFeeReais || 0) * 100) });
  const clear = () => apply({ pixPercent: null, cardPercent: null, fixedFeeCents: null });
  return (
    <div className="col gap-18 fade-up">
      <div className="card card-pad col gap-10">
        <span className="section-title">Valor cobrado (efetivo)</span>
        <span className="faint" style={{ fontSize: 12.5 }}>O que realmente sai nas transações.</span>
        <div className="divider" />
        {[["PIX", PCT(fee.effective.pixPercent, 2)], ["Crédito", PCT(fee.effective.cardPercent, 2)], ["Taxa fixa", cBRL(fee.effective.fixedFeeCents)]].map(([k, v]) => (
          <div key={k} className="row between" style={{ fontSize: 13.5 }}><span className="muted">{k}</span><span className="num" style={{ fontWeight: 600 }}>{v}</span></div>))}
      </div>
      {own ? (
        <div className="card card-pad col gap-14" style={{ borderColor: "var(--accent-line)" }}>
          <div className="row between"><span className="section-title">Valor exibido no painel</span>{fee.isCustomDisplay && <span className="badge badge-orange">Personalizado</span>}</div>
          <span className="faint" style={{ fontSize: 12.5 }}>Loja própria (own_cnpj): o número exibido pode diferir do cobrado.</span>
          <FeeNumField label="PIX exibido" value={d.pixPercent} onChange={e => setD(s => ({ ...s, pixPercent: e.target.value }))} />
          <FeeNumField label="Crédito exibido" value={d.cardPercent} onChange={e => setD(s => ({ ...s, cardPercent: e.target.value }))} />
          <FeeNumField label="Taxa fixa exibida" value={d.fixedFeeReais} onChange={e => setD(s => ({ ...s, fixedFeeReais: e.target.value }))} affix="R$" side="l" />
          {err && <span style={{ color: "var(--red)", fontSize: 13 }}>{err}</span>}
          <div className="row gap-10">
            <button className="btn btn-primary" disabled={busy} onClick={save}>{busy ? "Salvando…" : "Salvar exibição"}</button>
            {fee.isCustomDisplay && <button className="btn btn-ghost" disabled={busy} onClick={clear}>Limpar (usar cobrado)</button>}
          </div>
        </div>
      ) : (
        <div className="card card-pad row gap-12" style={{ background: "var(--blue-wash)" }}>
          <I.shield size={18} style={{ color: "var(--blue)", flexShrink: 0, marginTop: 1 }} />
          <div className="col"><span style={{ fontSize: 13.5, fontWeight: 600 }}>Taxa exibida = taxa cobrada</span><span className="faint" style={{ fontSize: 12.5 }}>Sellers terceiros sempre veem a taxa real. O valor exibido só pode diferir em lojas próprias (own_cnpj).</span></div>
        </div>
      )}
    </div>
  );
}

/* ---------------- Compliance ---------------- */
function AdminCompliance() {
  const [queue, setQueue] = React.useState(null);
  const [done, setDone] = React.useState({});
  React.useEffect(() => { api.admin.sellers({ kycStatus: "pending", pageSize: 50 }).then(r => setQueue(r.data)).catch(() => setQueue([])); }, []);
  const decide = async (id, decision) => {
    setDone(d => ({ ...d, [id]: decision }));
    try { await api.admin.kycDecision(id, decision); } catch (e) { /* keep visible */ }
    setTimeout(() => setQueue(q => (q || []).filter(s => s.id !== id)), 650);
  };
  const list = queue || [];
  return (
    <div className="col gap-24 fade-up">
      <PageHead title="Compliance & KYC" sub="Análise de risco, documentos e monitoramento" />
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 16 }} className="kpi-grid">
        <KPI label="Aguardando KYC" value={queue ? list.length : "—"} icon="clock" accent="var(--amber)" />
        <KPI label="Aprovados (mês)" value="—" icon="checkCircle" accent="var(--green)" />
        <KPI label="Alertas de risco" value="—" icon="warn" accent="var(--red)" />
        <KPI label="Score médio" value="—" icon="shield" accent="var(--blue)" />
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr", gap: 16 }} className="chart-grid">
        <SCard title="Fila de aprovação KYC" sub="Sellers aguardando análise" pad={false}>
          <div className="col">{!queue ? <div className="faint" style={{ padding: 28, textAlign: "center" }}>Carregando…</div>
            : list.length === 0 ? <div className="faint" style={{ padding: 28, textAlign: "center" }}>Nenhum seller aguardando KYC ✓</div>
            : list.map((s, i) => (
            <div key={s.id} className="row between" style={{ padding: "16px 22px", borderTop: i ? "1px solid var(--line)" : "none", opacity: done[s.id] ? 0.5 : 1 }}>
              <div className="row gap-12"><Avatar name={s.legalName} size={38} /><div className="col"><span style={{ fontWeight: 600, fontSize: 14 }}>{s.legalName}</span><span className="faint mono" style={{ fontSize: 12 }}>{s.document}</span></div></div>
              {done[s.id] ? <Status s={done[s.id]} />
                : <div className="row gap-8"><button className="btn btn-danger btn-sm" onClick={() => decide(s.id, "rejected")}><I.x size={14} /></button><button className="btn btn-primary btn-sm" onClick={() => decide(s.id, "approved")}><I.check size={14} /> Aprovar</button></div>}
            </div>))}</div>
        </SCard>
        <SCard title="Alertas de risco" sub="Monitoramento ativo">
          <div className="col gap-12">{[["Volume atípico detectado", "NorthPeak", "red"], ["Chargeback acima do limite", "Acme Eletro", "red"], ["Documento divergente", "Pixel Games", "amber"], ["Múltiplos cartões mesmo IP", "Onyx Wear", "amber"]].map(([t, s, c], i) => (
            <div key={i} className="row gap-12" style={{ padding: "12px 14px", background: `var(--${c}-wash)`, borderRadius: "var(--r)", border: `1px solid var(--${c}-wash)` }}>
              <I.warn size={18} style={{ color: `var(--${c})`, flexShrink: 0, marginTop: 1 }} />
              <div className="col grow"><span style={{ fontSize: 13.5, fontWeight: 600 }}>{t}</span><span className="faint" style={{ fontSize: 12 }}>{s}</span></div>
              <button className="btn btn-subtle btn-sm">Revisar</button>
            </div>))}</div>
        </SCard>
      </div>
    </div>
  );
}

/* ---------------- Integrações monitoramento (admin) ---------------- */
function AdminIntegracoes() {
  return (
    <div className="col gap-24 fade-up">
      <PageHead title="Integrações" sub="Monitoramento de conectores da plataforma" />
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))", gap: 16 }}>
        {DATA.integrations.map(it => (
          <div key={it.id} className="card card-pad col gap-12">
            <div className="row between"><div className="row gap-10"><div style={{ width: 38, height: 38, borderRadius: 10, background: it.color + "22", color: it.color, display: "flex", alignItems: "center", justifyContent: "center" }}><I.plug size={19} /></div><span style={{ fontWeight: 600 }}>{it.name}</span></div><span className={"badge " + (it.status === "conectado" ? "badge-green" : it.status === "ajustes" ? "badge-amber" : "badge-gray")}><span className="dot" />{it.status === "conectado" ? "Operacional" : it.status === "ajustes" ? "Degradado" : "Offline"}</span></div>
            <div className="row between"><span className="faint" style={{ fontSize: 12 }}>Uptime 30d</span><span className="num" style={{ fontWeight: 600, fontSize: 13.5, color: "var(--green)" }}>{it.status === "conectado" ? "99,98%" : it.status === "ajustes" ? "97,2%" : "—"}</span></div>
            <Spark data={DATA.helpers.series(20, 100, it.status === "conectado" ? 0.02 : 0.18)} color={it.status === "conectado" ? "var(--green)" : "var(--amber)"} w={200} h={36} />
          </div>))}
      </div>
      <SCard title="Logs do sistema" sub="Eventos recentes de integração" pad={false}>
        <table className="tbl"><thead><tr><th>Timestamp</th><th>Conector</th><th>Evento</th><th>Nível</th></tr></thead>
          <tbody>{[["WooCommerce", "Timeout no webhook", "warn"], ["Shopify", "Sincronização concluída", "ok"], ["API própria", "Token rotacionado", "ok"], ["Loja Integrada", "Reconexão necessária", "warn"], ["Shopify", "1.842 pedidos importados", "ok"]].map(([conn, ev, lv], i) => (
            <tr key={i}><td className="mono faint" style={{ fontSize: 13 }}>2026‑05‑29 1{i}:0{i}:2{i}</td><td style={{ fontWeight: 600 }}>{conn}</td><td className="muted">{ev}</td>
              <td><span className={"badge " + (lv === "ok" ? "badge-green" : "badge-amber")} style={{ height: 22 }}>{lv === "ok" ? "info" : "warn"}</span></td></tr>))}</tbody></table>
      </SCard>
    </div>
  );
}

/* ---------------- light admin pages reusing patterns ---------------- */
function AdminRepasses() {
  const [pending, setPending] = React.useState(null);
  const [done, setDone] = React.useState({});
  React.useEffect(() => { api.admin.transfersPending().then(setPending); }, []);
  const act = async (id, kind) => {
    setDone(d => ({ ...d, [id]: kind === "approve" ? "approved" : "rejected" }));
    await (kind === "approve" ? api.transfers.approve(id) : api.transfers.reject(id));
    setTimeout(() => setPending(p => p.filter(t => t.id !== id)), 650);
  };
  const list = pending || [];
  const totalPending = list.reduce((a, t) => a + t.amountCents, 0);
  return (
    <div className="col gap-24 fade-up">
      <PageHead title="Repasses" sub="Aprovação de saques solicitados pelos sellers">
        <button className="btn btn-primary" disabled={!list.length} onClick={async () => { if (!confirm(`Aprovar ${list.length} repasse(s) pendente(s)?`)) return; for (const t of [...list]) { try { await act(t.id, "approve"); } catch (e) { /* keep going */ } } }}><I.bolt size={16} /> Processar lote</button>
      </PageHead>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16 }} className="kpi-grid">
        <KPI label="Aguardando aprovação" value={cBRL(totalPending, { cents: false })} icon="clock" accent="var(--amber)" hint={`${list.length} solicitações`} />
        <KPI label="Processado hoje" value={cBRL(192000000, { cents: false })} icon="checkCircle" accent="var(--green)" />
        <KPI label="Em falha" value={cBRL(1240000, { cents: false })} icon="warn" accent="var(--red)" hint="3 repasses" />
      </div>
      <SCard title="Repasses pendentes" sub="Revise e aprove os saques solicitados" pad={false}>
        <table className="tbl"><thead><tr><th>ID</th><th>Seller</th><th>Solicitado em</th><th style={{ textAlign: "right" }}>Valor</th><th style={{ textAlign: "right", width: 220 }}>Ação</th></tr></thead>
          <tbody>{!pending ? <tr><td colSpan={5} className="faint" style={{ padding: 28, textAlign: "center" }}>Carregando…</td></tr>
            : list.length === 0 ? <tr><td colSpan={5} className="faint" style={{ padding: 28, textAlign: "center" }}>Nenhum repasse pendente. Tudo em dia ✓</td></tr>
            : list.map(t => (
            <tr key={t.id} style={done[t.id] ? { opacity: 0.5 } : {}}>
              <td className="mono" style={{ fontWeight: 600 }}>{t.id}</td>
              <td><div className="row gap-10"><Avatar name={t.subMerchantName} size={30} /><span style={{ fontWeight: 600, fontSize: 13.5 }}>{t.subMerchantName}</span></div></td>
              <td className="faint mono" style={{ fontSize: 13 }}>{fmtDate(new Date(t.requestedAt))}</td>
              <td className="num" style={{ textAlign: "right", fontWeight: 600 }}>{cBRL(t.amountCents)}</td>
              <td style={{ textAlign: "right" }}>
                {done[t.id] ? <Status s={done[t.id] === "approved" ? "approved" : "refused"} />
                  : <div className="row gap-8" style={{ justifyContent: "flex-end" }}>
                      <button className="btn btn-danger btn-sm" onClick={() => act(t.id, "reject")}><I.x size={14} /> Reprovar</button>
                      <button className="btn btn-primary btn-sm" onClick={() => act(t.id, "approve")}><I.check size={14} /> Aprovar</button>
                    </div>}
              </td>
            </tr>))}</tbody></table>
      </SCard>
    </div>
  );
}

function AdminRelatorios() {
  return (
    <div className="col gap-24 fade-up">
      <PageHead title="Relatórios" sub="Inteligência de negócio da plataforma">
        <button className="btn btn-primary" onClick={async () => { const r = await api.admin.revenueMonthly(12); exportCsv("receita-mensal", (r || []).map(x => ({ mes: x.month || x.label || "", valor_cents: x.valueCents }))); }}><I.download size={16} /> Exportar</button>
      </PageHead>
      <div style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr", gap: 16 }} className="chart-grid">
        <SCard title="Crescimento da plataforma" sub="Volume processado · 12 meses">
          <Bars data={DATA.seriesMonthly.map(v => v / 1000)} labels={["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"]} height={240} color="var(--accent)" />
        </SCard>
        <SCard title="Distribuição de sellers" sub="Por tabela comercial">
          <div className="col center gap-16">
            <Donut size={150} thickness={18} segments={[{ value: 1180, color: "var(--ink-faint)" }, { value: 84, color: "var(--blue)" }, { value: 20, color: "var(--accent)" }]}
              center={<div className="col center"><span className="num" style={{ fontSize: 22, fontWeight: 600 }}>1.284</span><span className="faint" style={{ fontSize: 10.5 }}>sellers</span></div>} />
            <div className="row gap-14 wrap center">{[["Padrão", "var(--ink-faint)"], ["Pro", "var(--blue)"], ["Enterprise", "var(--accent)"]].map(([l, c]) => <span key={l} className="row gap-6" style={{ fontSize: 12.5 }}><span style={{ width: 8, height: 8, borderRadius: 3, background: c }} />{l}</span>)}</div>
          </div>
        </SCard>
      </div>
    </div>
  );
}

const ADMIN_PREFS = [["Aprovação automática de KYC", "auto_kyc", false], ["Antecipação automática", "auto_advance", true], ["Notificações por e‑mail", "email_notif", true], ["Modo manutenção", "maintenance", false]];
function AdminConfig() {
  const [prefs, setPrefs] = React.useState(() => {
    const def = {}; ADMIN_PREFS.forEach(([, k, v]) => (def[k] = v));
    try { return { ...def, ...JSON.parse(localStorage.getItem("afex_admin_prefs") || "{}") }; } catch (e) { return def; }
  });
  const toggle = (k) => setPrefs(p => { const n = { ...p, [k]: !p[k] }; localStorage.setItem("afex_admin_prefs", JSON.stringify(n)); return n; });
  return (
    <div className="col gap-24 fade-up">
      <PageHead title="Configurações" sub="Parâmetros da plataforma AFEX Pay" />
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, maxWidth: 900 }}>
        <SCard title="Parâmetros gerais">
          <div className="col gap-14">
            {ADMIN_PREFS.map(([l, k]) => (
              <div key={k} className="row between"><span style={{ fontSize: 14 }}>{l}</span><Toggle on={!!prefs[k]} onChange={() => toggle(k)} /></div>))}
          </div>
        </SCard>
        <SCard title="Equipe AFEX">
          <div className="col">{[["Roberto Lima", "Super admin"], ["Patrícia Souza", "Compliance"], ["André Castro", "Financeiro"]].map(([n, r], i) => (
            <div key={n} className="row between" style={{ padding: "12px 0", borderTop: i ? "1px solid var(--line)" : "none" }}>
              <div className="row gap-10"><Avatar name={n} size={34} /><span style={{ fontSize: 14, fontWeight: 600 }}>{n}</span></div><span className="badge badge-gray">{r}</span></div>))}</div>
        </SCard>
      </div>
    </div>
  );
}

function STATUS_TXT(s) { return ({ ativo: "Ativo", pendente: "Pendente", bloqueado: "Bloqueado" })[s] || s; }

Object.assign(window, { AdminDashboard, AdminSellers, AdminTransacoes, AdminTaxas, AdminCompliance, AdminIntegracoes, AdminRepasses, AdminRelatorios, AdminConfig });
