/* ============================================================
   PCP — Screens part 3: Clientes, Notas, Relatórios, Config
   ============================================================ */

// ---------------------------------------------------------------
// CLIENTES
// ---------------------------------------------------------------
function Clientes({ app }) {
  const [sel, setSel] = useState(app.clientes[0] ? app.clientes[0]._id : null);
  const [q, setQ] = useState("");
  const rows = app.clientes.filter((c) => !q || (c.nome + c.doc + c.email + c.tel).toLowerCase().includes(q.toLowerCase()));
  const cli = app.clientes.find((c) => c._id === sel) || app.clientes[0];
  const totalCarteira = app.clientes.reduce((s, c) => s + c.total, 0);

  return (
    <div className="view-inner">
      <div className="page-head head-row">
        <div><div className="crumb">Cadastros</div><h1 className="page-title">Clientes</h1>
          <p className="page-sub">{app.clientes.length} clientes · {DB.BRL(totalCarteira).replace("R$\u00a0", "R$ ")} em carteira</p></div>
        <div className="spacer" />
        <div className="row gap8"><Btn icon="upload" onClick={() => app.openModal("importar", { entity: "clientes" })}>Importar</Btn><Btn icon="download" onClick={() => { PCPExport.modelo("clientes"); app.toast("Modelo de clientes baixado", "ok"); }}>Modelo</Btn><Btn icon="download" onClick={() => app.openModal("exportar", { entity: "clientes" })}>Exportar</Btn><Btn icon="plus" variant="primary" onClick={() => app.openModal("novoCliente")}>Novo cliente</Btn></div>
      </div>

      <div className="detail-grid">
        <div className="card">
          <div className="card-head">
            <div className="input" style={{ width: 280, height: 32 }}><Icon name="search" size={15} /><input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Buscar por nome, CNPJ, e-mail ou telefone…" /></div>
            <span className="spacer" /><span className="small muted">{rows.length} clientes</span>
          </div>
          <div className="tbl-wrap">
            <table className="tbl">
              <thead><tr><th>Cliente</th><th>Cidade</th><th className="num">Pedidos</th><th className="num">Total gasto</th><th>Último</th><th></th></tr></thead>
              <tbody>
                {rows.map((c) => (
                  <tr key={c._id} className={"clickable" + (sel === c._id ? " selected" : "")} onClick={() => setSel(c._id)}>
                    <td><div className="strong">{c.nome}</div><div className="small muted mono">{c.doc}</div></td>
                    <td className="muted">{c.cidade}/{c.uf}</td>
                    <td className="num">{c.pedidos}</td>
                    <td className="num strong">{DB.BRL(c.total)}</td>
                    <td className="muted">{c.ultimo}</td>
                    <td onClick={(e) => e.stopPropagation()}>
                      <RowMenu items={[
                        { icon: "eye", label: "Ver perfil", onClick: () => setSel(c._id) },
                        { icon: "edit", label: "Editar", onClick: () => app.openModal("novoCliente", { edit: c }) },
                        { icon: "fileText", label: "Novo pedido", onClick: () => app.openModal("novoPedido") },
                        { sep: true },
                        { icon: "trash", label: "Excluir", danger: true, onClick: () => app.openModal("confirm", { title: "Excluir cliente?", message: c.pedidos > 0 ? <><b>{c.nome}</b> tem {c.pedidos} pedidos vinculados e não pode ser excluído.</> : <><b>{c.nome}</b> será removido.</>, confirmLabel: c.pedidos > 0 ? "Entendi" : "Excluir", danger: c.pedidos === 0, successMsg: c.pedidos === 0 ? "Cliente excluído" : null, onConfirm: () => { if (c.pedidos === 0) app.clientesApi.remove(c._id); } }) },
                      ]} />
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
        <div className="side-panel">
          {cli && (
            <div className="card">
              <div className="card-head"><span className="avatar" style={{ width: 32, height: 32 }}>{cli.nome.split(" ").map((w) => w[0]).slice(0, 2).join("")}</span><span className="spacer" /><IconBtn icon="edit" onClick={() => app.openModal("novoCliente", { edit: cli })} /><RowMenu up items={[{ icon: "edit", label: "Editar cliente", onClick: () => app.openModal("novoCliente", { edit: cli }) }, { icon: "fileText", label: "Novo pedido", onClick: () => app.openModal("novoPedido") }, { sep: true }, { icon: "trash", label: "Excluir", danger: true, onClick: () => app.openModal("confirm", { title: "Excluir cliente?", message: cli.pedidos > 0 ? <><b>{cli.nome}</b> tem {cli.pedidos} pedidos e não pode ser excluído.</> : <><b>{cli.nome}</b> será removido.</>, confirmLabel: cli.pedidos > 0 ? "Entendi" : "Excluir", danger: cli.pedidos === 0, successMsg: cli.pedidos === 0 ? "Cliente excluído" : null, onConfirm: () => { if (cli.pedidos === 0) app.clientesApi.remove(cli._id); } }) }]} /></div>
              <div className="card-pad">
                <div style={{ fontSize: 16, fontWeight: 650 }}>{cli.nome}</div>
                <div className="small muted mono" style={{ marginBottom: 14 }}>{cli.doc}</div>
                <dl className="kv">
                  <dt>Telefone</dt><dd>{cli.tel}</dd>
                  <dt>E-mail</dt><dd style={{ fontSize: 12 }}>{cli.email}</dd>
                  <dt>Cidade</dt><dd>{cli.cidade}/{cli.uf}</dd>
                </dl>
                <div className="divider" />
                <div className="grid2" style={{ gridTemplateColumns: "1fr 1fr", gap: 10 }}>
                  <div className="sumbox" style={{ padding: "11px 13px" }}><div className="small muted">Pedidos</div><div style={{ fontSize: 22, fontWeight: 650 }}>{cli.pedidos}</div></div>
                  <div className="sumbox" style={{ padding: "11px 13px" }}><div className="small muted">Total gasto</div><div style={{ fontSize: 18, fontWeight: 650 }}>{DB.BRL(cli.total).replace("R$\u00a0", "R$ ")}</div></div>
                </div>
                <div className="sec-label">Histórico</div>
                {app.pedidos.filter((p) => p.cliente === cli.nome).slice(0, 4).map((p) => (
                  <div key={p._id} className="row" style={{ padding: "8px 0", borderBottom: "1px solid var(--line-soft)" }}>
                    <span className="mono small strong">{p.os}</span>
                    <span className="small muted" style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{p.produto}</span>
                    <span className="small mono strong">{DB.BRL(p.valor)}</span>
                  </div>
                ))}
                {app.pedidos.filter((p) => p.cliente === cli.nome).length === 0 && <div className="small muted" style={{ padding: "8px 0" }}>Sem pedidos recentes.</div>}
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------
// NOTAS FISCAIS
// ---------------------------------------------------------------
function Notas({ app }) {
  const [sel, setSel] = useState(app.notas[0] ? app.notas[0]._id : null);
  const nota = app.notas.find((n) => n._id === sel) || app.notas[0];
  const total = app.notas.reduce((s, n) => s + n.valor, 0);
  const fileRef = useRef(null);
  const [attachId, setAttachId] = useState(null);
  const pickFor = (id) => { setAttachId(id); setSel(id); setTimeout(() => fileRef.current && fileRef.current.click(), 0); };
  const onAttach = (e) => { const f = e.target.files && e.target.files[0]; const id = attachId || (nota && nota._id); if (f && id) { app.notasApi.update(id, { anexo: true, anexoUrl: URL.createObjectURL(f), anexoName: f.name, anexoType: f.type }); app.toast("Anexo adicionado", "ok"); } e.target.value = ""; };
  return (
    <div className="view-inner">
      <div className="page-head head-row">
        <div><div className="crumb">Gestão</div><h1 className="page-title">Notas Fiscais</h1><p className="page-sub">{app.notas.length} notas · {DB.BRL(total).replace("R$\u00a0", "R$ ")}</p></div>
        <div className="spacer" /><Btn icon="plus" variant="primary" onClick={() => app.openModal("novaNota")}>Nova nota</Btn>
      </div>
      <div className="detail-grid">
        <div className="card">
          <div className="card-head"><h3>Documentos</h3><span className="spacer" /><Btn size="sm" icon="filter" onClick={() => app.openModal("filtros", { kind: "notas" })}>Filtrar</Btn></div>
          <div className="tbl-wrap">
            <table className="tbl">
              <thead><tr><th>Nº</th><th>Fornecedor</th><th>Emissão</th><th className="num">Valor</th><th>Compra</th><th>Anexo</th><th></th></tr></thead>
              <tbody>
                {app.notas.map((n) => (
                  <tr key={n._id} className={"clickable" + (sel === n._id ? " selected" : "")} onClick={() => setSel(n._id)}>
                    <td className="mono strong">{n.num}</td>
                    <td className="strong">{n.forn}</td>
                    <td className="muted">{n.emissao}</td>
                    <td className="num strong">{DB.BRL(n.valor)}</td>
                    <td><span className="sku">{n.compra}</span></td>
                    <td>{n.anexo ? <Badge tone="ok" dotted>PDF</Badge> : <Badge tone="warn" dotted>Pendente</Badge>}</td>
                    <td onClick={(e) => e.stopPropagation()}>
                      <RowMenu items={[
                        { icon: "eye", label: "Visualizar", onClick: () => setSel(n._id) },
                        { icon: "download", label: "Baixar PDF", onClick: () => PCPExport.printNota(n) },
                        { icon: "paperclip", label: n.anexo ? "Substituir anexo" : "Anexar arquivo", onClick: () => pickFor(n._id) },
                        { sep: true },
                        { icon: "trash", label: "Excluir", danger: true, onClick: () => app.openModal("confirm", { title: "Excluir NF " + n.num + "?", message: <>A nota de <b>{n.forn}</b> será removida.</>, successMsg: "NF " + n.num + " excluída", onConfirm: () => app.notasApi.remove(n._id) }) },
                      ]} />
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
        <div className="side-panel">
          {nota ? (
          <div className="card">
            <div className="card-head"><Icon name="receipt" size={15} /><h3>NF {nota.num}</h3><span className="spacer" /><IconBtn icon="download" title="Baixar PDF" onClick={() => PCPExport.printNota(nota)} /></div>
            <div className="card-pad">
              <input ref={fileRef} type="file" accept="application/pdf,image/*" style={{ display: "none" }} onChange={onAttach} />
              {nota.anexoUrl ? (
                (nota.anexoType || "").startsWith("image") ? (
                  <div className="img-slot" style={{ height: 230, marginBottom: 14, padding: 0, overflow: "hidden" }}>
                    <img src={nota.anexoUrl} alt={nota.anexoName} style={{ width: "100%", height: "100%", objectFit: "contain" }} />
                  </div>
                ) : (
                  <div style={{ height: 280, marginBottom: 14, border: "1px solid var(--line)", borderRadius: "var(--radius)", overflow: "hidden" }}>
                    <iframe src={nota.anexoUrl} title={nota.anexoName} style={{ width: "100%", height: "100%", border: "none", background: "#fff" }} />
                  </div>
                )
              ) : nota.anexo ? (
                <div className="img-slot" style={{ height: 220, marginBottom: 14, flexDirection: "column", gap: 8, cursor: "pointer" }} onClick={() => pickFor(nota._id)}>
                  <Icon name="fileText" size={28} /><span>pré-visualização do PDF</span><span className="small muted">clique para anexar o arquivo real</span>
                </div>
              ) : (
                <div className="upzone" style={{ marginBottom: 14, cursor: "pointer" }} onClick={() => pickFor(nota._id)}><div className="uz-ico"><Icon name="paperclip" size={18} /></div><div className="uz-t">Anexar documento</div><div className="uz-s">PDF ou imagem</div></div>
              )}
              <dl className="kv">
                <dt>Fornecedor</dt><dd>{nota.forn}</dd>
                <dt>Emissão</dt><dd>{nota.emissao}</dd>
                <dt>Valor total</dt><dd>{DB.BRL(nota.valor)}</dd>
                <dt>Compra vinculada</dt><dd><span className="sku">{nota.compra}</span></dd>
              </dl>
            </div>
          </div>
          ) : (
            <div className="card"><Empty icon="receipt" title="Nenhuma nota">As notas excluídas somem da lista. Cadastre uma nova nota fiscal.</Empty></div>
          )}
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------
// RELATÓRIOS
// ---------------------------------------------------------------
function Relatorios({ app }) {
  const [periodo, setPeriodo] = useState("6m");
  const fmtK = (n) => DB.BRL(n).replace("R$\u00a0", "R$ ");

  // faturamento por período (12 ou 6 meses)
  const fatData = periodo === "ano" ? DB.FATUR12 : DB.FATUR;
  const periodoSub = (() => {
    const fim = new Date();
    const meses = periodo === "ano" ? 12 : 6;
    const inicio = new Date(fim); inicio.setMonth(fim.getMonth() - (meses - 1));
    const fmt = (d) => d.toLocaleDateString("pt-BR", { month: "short" }).replace(".", "") + " " + d.getFullYear();
    return fmt(inicio) + " – " + fmt(fim);
  })();
  const fatDelta = fatData.length > 1 ? Math.round((fatData[fatData.length - 1].v / fatData[0].v - 1) * 100) : 0;

  // produtos mais vendidos — agregado AO VIVO dos pedidos
  const prodRank = useMemo(() => {
    const m = {};
    app.pedidos.filter((p) => p.status !== "cancelado").forEach((p) => {
      if (!m[p.produto]) m[p.produto] = { nome: p.produto, qtd: 0, valor: 0 };
      m[p.produto].qtd += p.qtd; m[p.produto].valor += p.valor;
    });
    return Object.values(m).sort((a, b) => b.valor - a.valor).slice(0, 5);
  }, [app.pedidos]);

  // melhores clientes — AO VIVO pela carteira
  const cliRank = useMemo(() => [...app.clientes].sort((a, b) => b.total - a.total).slice(0, 5), [app.clientes]);

  // performance de produção — AO VIVO das OPs
  const totalOps = app.ops.length;
  const atrasadas = app.ops.filter((o) => o.atrasada).length;
  const noPrazo = totalOps - atrasadas;
  const pctPrazo = totalOps ? Math.round((noPrazo / totalOps) * 100) : 0;

  const maxProd = Math.max(1, ...prodRank.map((p) => p.valor));
  const maxCli = Math.max(1, ...cliRank.map((c) => c.total));

  return (
    <div className="view-inner">
      <div className="page-head head-row">
        <div><div className="crumb">Gestão</div><h1 className="page-title">Relatórios</h1><p className="page-sub">Indicadores consolidados · {periodoSub}</p></div>
        <div className="spacer" />
        <div className="row gap8">
          <div className="seg">
            {[["6m", "6 meses"], ["ano", "Ano"], ["custom", "Personalizado"]].map(([k, l]) => (
              <button key={k} className={periodo === k ? "on" : ""} onClick={() => { setPeriodo(k); if (k === "custom") app.openModal("filtros", { kind: "relatorios" }); }}>{l}</button>
            ))}
          </div>
          <Btn icon="download" onClick={() => app.openModal("exportar", { entity: "relatório" })}>Exportar</Btn>
        </div>
      </div>

      <div className="grid2" style={{ gridTemplateColumns: "1.5fr 1fr", marginBottom: 16, alignItems: "start" }}>
        <div className="card">
          <div className="card-head"><h3>Faturamento mês a mês</h3><span className="sub">milhares de R$ · {fatData.length} meses</span><span className="spacer" /><Badge tone={fatDelta >= 0 ? "ok" : "crit"} dotted>{fatDelta >= 0 ? "+" : ""}{fatDelta}%</Badge></div>
          <div className="card-pad"><MiniBars data={fatData} height={150} /></div>
        </div>
        <div className="card card-pad">
          <SectionLabel>Performance de produção</SectionLabel>
          <div className="row" style={{ gap: 18, alignItems: "center", marginTop: 6 }}>
            <Donut pct={pctPrazo} />
            <div className="col gap8">
              <div className="row gap8"><span style={{ width: 9, height: 9, borderRadius: 3, background: "var(--ok)" }} /><span className="small">No prazo</span><span className="mono strong">{noPrazo}</span></div>
              <div className="row gap8"><span style={{ width: 9, height: 9, borderRadius: 3, background: "var(--crit)" }} /><span className="small">Atrasadas</span><span className="mono strong">{atrasadas}</span></div>
              <div className="small muted mt8">{totalOps} OPs no período</div>
            </div>
          </div>
        </div>
      </div>

      <div className="grid2" style={{ alignItems: "start" }}>
        <div className="card">
          <div className="card-head"><Icon name="package" size={15} /><h3>Produtos mais vendidos</h3><span className="spacer" /><span className="small muted">por valor em pedidos</span></div>
          <div className="card-pad col" style={{ gap: 13 }}>
            {prodRank.length === 0 && <div className="small muted">Sem pedidos no período.</div>}
            {prodRank.map((p, i) => (
              <div key={i}>
                <div className="row" style={{ justifyContent: "space-between", marginBottom: 5 }}>
                  <span className="small"><span className="muted mono" style={{ marginRight: 8 }}>{i + 1}</span>{p.nome}</span>
                  <span className="small mono strong">{fmtK(p.valor)}</span>
                </div>
                <Bar value={(p.valor / maxProd) * 100} />
              </div>
            ))}
          </div>
        </div>
        <div className="card">
          <div className="card-head"><Icon name="users" size={15} /><h3>Melhores clientes</h3><span className="spacer" /><span className="small muted">por total em carteira</span></div>
          <div className="card-pad col" style={{ gap: 13 }}>
            {cliRank.length === 0 && <div className="small muted">Sem clientes cadastrados.</div>}
            {cliRank.map((c, i) => (
              <div key={i}>
                <div className="row" style={{ justifyContent: "space-between", marginBottom: 5 }}>
                  <span className="small"><span className="muted mono" style={{ marginRight: 8 }}>{i + 1}</span>{c.nome}</span>
                  <span className="small mono strong">{fmtK(c.total)}</span>
                </div>
                <Bar value={(c.total / maxCli) * 100} tone="ok" />
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

function Donut({ pct }) {
  const R = 34, C = 2 * Math.PI * R;
  return (
    <svg width="92" height="92" viewBox="0 0 92 92">
      <circle cx="46" cy="46" r={R} fill="none" stroke="var(--line)" strokeWidth="10" />
      <circle cx="46" cy="46" r={R} fill="none" stroke="var(--ok)" strokeWidth="10" strokeLinecap="round"
        strokeDasharray={`${C * pct / 100} ${C}`} transform="rotate(-90 46 46)" />
      <text x="46" y="50" textAnchor="middle" fontSize="20" fontWeight="700" fill="var(--ink)" fontFamily="var(--num)">{pct}%</text>
    </svg>
  );
}

// ---------------------------------------------------------------
// CONFIGURAÇÕES
// ---------------------------------------------------------------
function Configuracoes({ app }) {
  const fileRef = useRef(null);
  const [novaEtapa, setNovaEtapa] = useState("");
  const [novoTerc, setNovoTerc] = useState("");
  const [tercExpand, setTercExpand] = useState(null);
  const empresaSch = (app.ws && app.ws.schedule) || { seg:{ativo:true,horas:8}, ter:{ativo:true,horas:8}, qua:{ativo:true,horas:8}, qui:{ativo:true,horas:8}, sex:{ativo:true,horas:8}, sab:{ativo:false,horas:0}, dom:{ativo:false,horas:0} };
  const DIAS = [["seg","Segunda"],["ter","Terça"],["qua","Quarta"],["qui","Quinta"],["sex","Sexta"],["sab","Sábado"],["dom","Domingo"]];
  const setEmpDia = (k, patch) => app.setEmpresaSchedule({ ...empresaSch, [k]: { ...(empresaSch[k] || {ativo:false,horas:0}), ...patch } });
  const empresaTotalSemana = DIAS.reduce((s, [k]) => s + (empresaSch[k] && empresaSch[k].ativo ? (+empresaSch[k].horas || 0) : 0), 0);
  const addTerc = () => {
    const n = novoTerc.trim();
    if (!n) return;
    if (app.terceirizados.some((t) => t.nome.toLowerCase() === n.toLowerCase())) {
      app.toast("Esse terceirizado já existe", "warn"); return;
    }
    app.terceirizadosApi.add({ nome: n, schedule: { seg:{ativo:true,horas:8}, ter:{ativo:true,horas:8}, qua:{ativo:true,horas:8}, qui:{ativo:true,horas:8}, sex:{ativo:true,horas:8}, sab:{ativo:false,horas:0}, dom:{ativo:false,horas:0} } }, true);
    setNovoTerc(""); app.toast(`Terceirizado "${n}" cadastrado`, "ok");
  };
  const setTercDia = (id, k, patch) => {
    const t = app.terceirizados.find((x) => x._id === id);
    if (!t) return;
    const sch = t.schedule || {};
    app.terceirizadosApi.update(id, { schedule: { ...sch, [k]: { ...(sch[k] || {ativo:false,horas:0}), ...patch } } });
  };
  const removeTerc = (id, nome) => {
    const emUso = app.produtos.some((p) => Array.isArray(p.etapas) && p.etapas.some((e) => e.terceirizadoId === id));
    if (emUso) {
      app.openModal("confirm", { title: `Remover "${nome}"?`, message: <>Esse terceirizado está vinculado a produtos. Remover desativa o vínculo mas mantém as etapas como "terceirizado sem definição".</>, confirmLabel: "Remover", successMsg: `"${nome}" removido`, onConfirm: () => app.terceirizadosApi.remove(id) });
    } else {
      app.terceirizadosApi.remove(id); app.toast(`"${nome}" removido`, "ok");
    }
  };
  const onRestoreFile = (e) => {
    const file = e.target.files && e.target.files[0];
    if (!file) return;
    PCPExport.restoreFromFile(file, app, (ok, n) => ok
      ? app.toast(n + " registros restaurados", "ok", { sub: "backup importado com sucesso" })
      : app.toast("Arquivo de backup inválido", "crit"));
    e.target.value = "";
  };
  const addEtapa = () => {
    const n = novaEtapa.trim();
    if (!n) return;
    if (app.etapasCatalogo.some((e) => e.nome.toLowerCase() === n.toLowerCase())) {
      app.toast("Essa etapa já existe", "warn"); return;
    }
    app.etapasApi.add({ nome: n }, true);
    setNovaEtapa("");
    app.toast(`Etapa "${n}" adicionada`, "ok");
  };
  const removeEtapa = (id, nome) => {
    const emUso = app.produtos.some((p) => Array.isArray(p.etapas) && p.etapas.some((e) => e.nome === nome));
    if (emUso) {
      app.openModal("confirm", { title: `Remover "${nome}"?`, message: <>Essa etapa está em uso por um ou mais produtos. Remover do catálogo <b>não</b> afeta os produtos já cadastrados, mas ela some das opções para novos produtos.</>, confirmLabel: "Remover do catálogo", successMsg: `"${nome}" removida`, onConfirm: () => app.etapasApi.remove(id) });
    } else {
      app.etapasApi.remove(id);
      app.toast(`"${nome}" removida`, "ok");
    }
  };
  return (
    <div className="view-inner" style={{ maxWidth: 820 }}>
      <div className="page-head"><div className="crumb">Sistema</div><h1 className="page-title">Configurações</h1><p className="page-sub">Perfil, aparência e empresas</p></div>

      <div className="sec-label">Perfil</div>
      <div className="card card-pad row" style={{ gap: 16 }}>
        <span className="avatar" style={{ width: 52, height: 52, fontSize: 17 }}>{((app.user && (app.user.name || app.user.email)) || "?").trim().split(/\s+/).map((p) => p[0]).slice(0, 2).join("").toUpperCase()}</span>
        <div className="grow">
          <div style={{ fontSize: 15, fontWeight: 600 }}>{(app.user && (app.user.name || app.user.email)) || "Usuário"}</div>
          <div className="small muted">{app.user && app.user.email}{app.user && app.user.name && app.user.name !== app.user.email ? " · " + app.user.name : ""}</div>
        </div>
        <Btn icon="edit" onClick={() => app.openModal("editarPerfil")}>Editar perfil</Btn>
      </div>

      <div className="sec-label">Aparência</div>
      <div className="card">
        <div className="card-pad row"><div className="grow"><div className="strong">Tema</div><div className="small muted">Claro segue sua paleta; escuro é o padrão.</div></div>
          <Choice value={app.theme} onChange={app.setTheme} options={[{ v: "dark", l: "Escuro" }, { v: "light", l: "Claro" }]} /></div>
        <div className="divider" style={{ margin: 0 }} />
        <div className="card-pad row"><div className="grow"><div className="strong">Densidade</div><div className="small muted">Compacto cabe mais linhas por tela.</div></div>
          <Choice value={app.density} onChange={app.setDensity} options={[{ v: "compact", l: "Compacto" }, { v: "regular", l: "Padrão" }, { v: "comfortable", l: "Amplo" }]} /></div>
      </div>

      <div className="sec-label">Empresas <span style={{ marginLeft: "auto", textTransform: "none", letterSpacing: 0 }}><Btn size="sm" icon="plus" onClick={() => app.openModal("novaEmpresa")}>Adicionar</Btn></span></div>
      <div className="card">
        {app.workspaces.map((w, i) => (
          <div key={w.id} className="card-pad row" style={{ gap: 12, borderTop: i ? "1px solid var(--line)" : "none" }}>
            <span className="ws-logo" style={{ width: 38, height: 38 }}>{w.logo}</span>
            <div className="grow"><div className="strong">{w.name}</div><div className="small muted">{w.sub}</div></div>
            {w.current ? <Badge tone="accent" dotted>Atual</Badge> : <Btn size="sm" onClick={() => app.switchWorkspace(w.id)}>Acessar</Btn>}
          </div>
        ))}
      </div>

      <div className="sec-label">Horário de funcionamento{app.ws ? <span style={{ marginLeft: 8, fontWeight: 400, textTransform: "none", letterSpacing: 0, color: "var(--muted)" }}>· {app.ws.name}</span> : null}</div>
      <div className="card">
        <div className="card-pad">
          <div className="small muted">
            Define a capacidade de produção interna. O sistema usa essas horas pra estimar se um pedido cabe no prazo. Total semanal: <b style={{ color: "var(--ink)" }}>{empresaTotalSemana}h</b>.
          </div>
        </div>
        {DIAS.map(([k, l], i) => {
          const d = empresaSch[k] || { ativo: false, horas: 0 };
          return (
            <div key={k} className="card-pad row" style={{ gap: 12, borderTop: "1px solid var(--line)", padding: "10px 14px" }}>
              <div style={{ width: 90, fontWeight: 600, fontSize: 13 }}>{l}</div>
              <Toggle on={d.ativo} onClick={() => setEmpDia(k, { ativo: !d.ativo })} />
              <div className="grow" />
              {d.ativo ? (
                <div className="row gap6" style={{ alignItems: "center" }}>
                  <input className="fld right mono" type="number" step="0.5" min="0" max="24" value={d.horas} onChange={(e) => setEmpDia(k, { horas: +e.target.value || 0 })} style={{ width: 80, height: 32 }} />
                  <span className="small muted">h/dia</span>
                </div>
              ) : <span className="small muted">fechado</span>}
            </div>
          );
        })}
      </div>

      <div className="sec-label">Terceirizados</div>
      <div className="card">
        <div className="card-pad">
          <div className="small muted" style={{ marginBottom: 10 }}>
            Cadastre as empresas que executam etapas externas (ex.: corte a laser, usinagem). O horário de cada uma é usado pra calcular o prazo de entrega quando o produto depende delas.
          </div>
          <div className="row gap8">
            <div className="input grow" style={{ height: 34 }}>
              <Icon name="building" size={15} />
              <input value={novoTerc} onChange={(e) => setNovoTerc(e.target.value)} placeholder="Nome do terceirizado (ex.: Corte Laser SP)" onKeyDown={(e) => e.key === "Enter" && addTerc()} />
            </div>
            <Btn variant="primary" icon="plus" onClick={addTerc} disabled={!novoTerc.trim()}>Adicionar</Btn>
          </div>
        </div>
        {app.terceirizados.length === 0 ? (
          <div className="card-pad" style={{ borderTop: "1px solid var(--line)" }}>
            <div className="small muted">Nenhum terceirizado cadastrado ainda.</div>
          </div>
        ) : (
          app.terceirizados.map((t) => {
            const sch = t.schedule || {};
            const totalSem = DIAS.reduce((s, [k]) => s + (sch[k] && sch[k].ativo ? (+sch[k].horas || 0) : 0), 0);
            const aberto = tercExpand === t._id;
            return (
              <div key={t._id} style={{ borderTop: "1px solid var(--line)" }}>
                <div className="card-pad row" style={{ gap: 12 }}>
                  <span className="m-ico" style={{ width: 30, height: 30, borderRadius: 8, background: "var(--info-tint, var(--accent-tint))", color: "var(--info, var(--accent))", display: "grid", placeItems: "center", flex: "none" }}>
                    <Icon name="building" size={15} />
                  </span>
                  <div className="grow">
                    <div className="strong">{t.nome}</div>
                    <div className="small muted">{totalSem}h/semana</div>
                  </div>
                  <Btn size="sm" icon={aberto ? "chevronUp" : "edit"} onClick={() => setTercExpand(aberto ? null : t._id)}>{aberto ? "Fechar" : "Horário"}</Btn>
                  <IconBtn icon="trash" title="Remover" onClick={() => removeTerc(t._id, t.nome)} />
                </div>
                {aberto && (
                  <div style={{ borderTop: "1px dashed var(--line)", background: "var(--bg)" }}>
                    {DIAS.map(([k, l]) => {
                      const d = sch[k] || { ativo: false, horas: 0 };
                      return (
                        <div key={k} className="row" style={{ gap: 12, padding: "8px 14px", borderTop: "1px solid var(--line-soft, var(--line))" }}>
                          <div style={{ width: 90, fontWeight: 600, fontSize: 12.5 }}>{l}</div>
                          <Toggle on={d.ativo} onClick={() => setTercDia(t._id, k, { ativo: !d.ativo })} />
                          <div className="grow" />
                          {d.ativo ? (
                            <div className="row gap6" style={{ alignItems: "center" }}>
                              <input className="fld right mono" type="number" step="0.5" min="0" max="24" value={d.horas} onChange={(e) => setTercDia(t._id, k, { horas: +e.target.value || 0 })} style={{ width: 80, height: 30 }} />
                              <span className="small muted">h/dia</span>
                            </div>
                          ) : <span className="small muted">fechado</span>}
                        </div>
                      );
                    })}
                  </div>
                )}
              </div>
            );
          })
        )}
      </div>

      <div className="sec-label">Etapas de produção</div>
      <div className="card">
        <div className="card-pad">
          <div className="small muted" style={{ marginBottom: 10 }}>
            Defina aqui as etapas usadas nos seus produtos (ex.: Impressão 3D, Corte Laser, Usinagem, Dobra). No cadastro do produto você escolhe quais etapas ele passa, quantas horas em cada uma e se é local ou terceirizado.
          </div>
          <div className="row gap8">
            <div className="input grow" style={{ height: 34 }}>
              <Icon name="layers" size={15} />
              <input value={novaEtapa} onChange={(e) => setNovaEtapa(e.target.value)} placeholder="Nome da etapa (ex.: Corte Laser)" onKeyDown={(e) => e.key === "Enter" && addEtapa()} />
            </div>
            <Btn variant="primary" icon="plus" onClick={addEtapa} disabled={!novaEtapa.trim()}>Adicionar</Btn>
          </div>
        </div>
        {app.etapasCatalogo.length === 0 ? (
          <div className="card-pad" style={{ borderTop: "1px solid var(--line)" }}>
            <div className="small muted">Nenhuma etapa cadastrada ainda.</div>
          </div>
        ) : (
          <div>
            {app.etapasCatalogo.map((et, i) => {
              const usos = app.produtos.filter((p) => Array.isArray(p.etapas) && p.etapas.some((e) => e.nome === et.nome)).length;
              return (
                <div key={et._id} className="card-pad row" style={{ gap: 12, borderTop: "1px solid var(--line)" }}>
                  <span className="m-ico" style={{ width: 30, height: 30, borderRadius: 8, background: "var(--accent-tint)", color: "var(--accent)", display: "grid", placeItems: "center", flex: "none" }}>
                    <Icon name="layers" size={15} />
                  </span>
                  <div className="grow">
                    <div className="strong">{et.nome}</div>
                    <div className="small muted">{usos === 0 ? "sem produtos vinculados" : usos + " produto" + (usos === 1 ? "" : "s") + " usando"}</div>
                  </div>
                  <IconBtn icon="trash" title="Remover" onClick={() => removeEtapa(et._id, et.nome)} />
                </div>
              );
            })}
          </div>
        )}
      </div>

      <div className="sec-label">Integrações</div>
      <div className="card card-pad row" style={{ gap: 14 }}>
        <span className="ws-logo" style={{ width: 40, height: 40, flex: "none" }}><Icon name="refresh" size={19} /></span>
        <div className="grow"><div className="strong">Canais de venda</div><div className="small muted">Mercado Livre e Shopee conectados · 3 anúncios a vincular</div></div>
        <Btn icon="chevronRight" onClick={() => app.setRoute("integracoes")}>Gerenciar</Btn>
      </div>


      <div className="sec-label">Backup &amp; conta</div>
      <div className="card card-pad">
        <div className="small muted" style={{ marginBottom: 12 }}>
          Exporte um arquivo JSON com tudo (estoque, pedidos, OPs, clientes, terceirizados…) ou restaure a partir de um backup.
        </div>
        <input ref={fileRef} type="file" accept="application/json,.json" style={{ display: "none" }} onChange={onRestoreFile} />
        <div className="row gap8">
          <Btn icon="download" onClick={() => { const n = PCPExport.backup(app); app.toast("Backup gerado", "ok", { sub: n + " registros · download iniciado" }); }}>Fazer backup</Btn>
          <Btn icon="upload" onClick={() => app.openModal("confirm", { title: "Restaurar de um backup?", icon: "refresh", danger: true, confirmLabel: "Escolher arquivo", message: <>Isto <b>substitui os dados atuais</b> pelos do arquivo selecionado. As alterações não salvas serão perdidas.</>, onConfirm: () => fileRef.current && fileRef.current.click() })}>Restaurar de arquivo</Btn>
          <span className="spacer" />
          <Btn icon="logout" variant="danger" onClick={app.logout}>Sair da conta</Btn>
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------
// AUDITORIA
// ---------------------------------------------------------------
const ACAO_LABEL = {
  criar_pedido: "Criar pedido",
  mover_pedido_status: "Mudar status pedido",
  criar_op: "Criar OP",
  finalizar_op: "Finalizar OP",
  registrar_producao_op: "Registrar produção",
  cancelar_op: "Cancelar OP",
  concluir_etapa_op: "Concluir etapa",
  reabrir_etapa_op: "Reabrir etapa",
  receber_compra: "Receber compra",
  ajuste_estoque: "Ajuste estoque",
  importar_planilha: "Importar planilha",
  importar_relatorio_canal: "Importar relatório canal",
  limpar_movimentacoes: "Limpar movimentações",
  limpar_lancamentos: "Limpar financeiro",
  limpar_lancamentos_importados: "Limpar lanç. importados",
  limpar_compras: "Limpar compras",
  limpar_compras_sugeridas: "Limpar sugestões",
  limpar_analytics_canal: "Limpar analytics",
};

function Auditoria({ app }) {
  const [q, setQ] = useState("");
  const [acao, setAcao] = useState("todos");
  const [usuario, setUsuario] = useState("todos");
  const [tipoAlvo, setTipoAlvo] = useState("todos");
  const [dataIni, setDataIni] = useState("");
  const [dataFim, setDataFim] = useState("");

  const lista = app.eventos || [];
  // valores para filtros
  const acoes = [...new Set(lista.map((e) => e.acao).filter(Boolean))].sort();
  const usuarios = [...new Set(lista.map((e) => e.email).filter(Boolean))].sort();
  const tiposAlvo = [...new Set(lista.map((e) => e.alvo && e.alvo.tipo).filter(Boolean))].sort();

  const filtrados = lista.filter((e) => {
    if (acao !== "todos" && e.acao !== acao) return false;
    if (usuario !== "todos" && e.email !== usuario) return false;
    if (tipoAlvo !== "todos" && (!e.alvo || e.alvo.tipo !== tipoAlvo)) return false;
    if (dataIni) {
      const dt = new Date(e.ts);
      const di = new Date(dataIni + "T00:00:00");
      if (!isNaN(dt.getTime()) && dt < di) return false;
    }
    if (dataFim) {
      const dt = new Date(e.ts);
      const df = new Date(dataFim + "T23:59:59");
      if (!isNaN(dt.getTime()) && dt > df) return false;
    }
    if (q) {
      const t = q.toLowerCase();
      const bag = [
        e.acao || "",
        e.email || "",
        e.alvo ? e.alvo.tipo + ":" + e.alvo.id : "",
        e.detalhes ? JSON.stringify(e.detalhes) : "",
      ].join(" ").toLowerCase();
      if (!bag.includes(t)) return false;
    }
    return true;
  });

  const exportar = () => {
    if (typeof PCPExport === "undefined") return;
    const cols = [
      { key: "ts", label: "Data/Hora" },
      { key: "email", label: "Usuário" },
      { key: "acao", label: "Ação" },
      { key: "alvo", label: "Alvo" },
      { key: "detalhes", label: "Detalhes" },
    ];
    const rows = filtrados.map((e) => ({
      ts: e.ts ? new Date(e.ts).toLocaleString("pt-BR") : "",
      email: e.email || "",
      acao: ACAO_LABEL[e.acao] || e.acao,
      alvo: e.alvo ? `${e.alvo.tipo}:${e.alvo.id}` : "",
      detalhes: e.detalhes ? JSON.stringify(e.detalhes) : "",
    }));
    PCPExport.download("auditoria-" + new Date().toISOString().slice(0, 10) + ".csv", PCPExport.csv(cols, rows), "text/csv;charset=utf-8");
    app.toast("Auditoria exportada", "ok");
  };

  const limpar = () => {
    app.openModal("confirm", {
      title: "Limpar histórico de auditoria?",
      danger: true,
      message: <>Remove <b>{lista.length} eventos</b> registrados. Essa ação também fica registrada como evento (ironicamente).</>,
      confirmLabel: "Limpar tudo",
      successMsg: "Auditoria limpa",
      onConfirm: () => {
        const total = lista.length;
        app.eventosApi.replaceAll([]);
        if (app.logEvento) app.logEvento("limpar_auditoria", null, { quantidade: total });
      },
    });
  };

  return (
    <div className="view-inner">
      <div className="page-head head-row">
        <div>
          <div className="crumb">Gestão</div>
          <h1 className="page-title">Auditoria</h1>
          <p className="page-sub">{lista.length} eventos registrados · histórico das ações de cada usuário</p>
        </div>
        <div className="spacer" />
        <div className="row gap8">
          <Btn icon="download" onClick={exportar} disabled={filtrados.length === 0}>Exportar CSV</Btn>
          {lista.length > 0 && <Btn icon="trash" onClick={limpar}>Limpar tudo</Btn>}
        </div>
      </div>

      <div className="metrics" style={{ gridTemplateColumns: "repeat(4, 1fr)", marginBottom: 18 }}>
        <MetricCard icon="list" label="Total" value={lista.length} />
        <MetricCard icon="filter" label="Filtrados" value={filtrados.length} state={filtrados.length !== lista.length ? "warn" : undefined} />
        <MetricCard icon="users" label="Usuários" value={usuarios.length} />
        <MetricCard icon="layers" label="Tipos de ação" value={acoes.length} />
      </div>

      <div className="card" style={{ marginBottom: 16 }}>
        <div className="card-pad">
          <div className="field-grid c2" style={{ marginBottom: 12 }}>
            <Field label="Buscar">
              <div className="fld-wrap">
                <Icon name="search" size={15} className="ico-in" />
                <input className="fld" value={q} onChange={(e) => setQ(e.target.value)} placeholder="Texto livre (ação, email, alvo, detalhes…)" />
              </div>
            </Field>
            <Field label="Período">
              <div className="row gap8">
                <input className="fld" type="date" value={dataIni} onChange={(e) => setDataIni(e.target.value)} placeholder="de" />
                <input className="fld" type="date" value={dataFim} onChange={(e) => setDataFim(e.target.value)} placeholder="até" />
              </div>
            </Field>
          </div>
          <div className="field-grid c3">
            <Field label="Ação">
              <select className="fld" value={acao} onChange={(e) => setAcao(e.target.value)}>
                <option value="todos">Todas</option>
                {acoes.map((a) => <option key={a} value={a}>{ACAO_LABEL[a] || a}</option>)}
              </select>
            </Field>
            <Field label="Usuário">
              <select className="fld" value={usuario} onChange={(e) => setUsuario(e.target.value)}>
                <option value="todos">Todos</option>
                {usuarios.map((u) => <option key={u} value={u}>{u}</option>)}
              </select>
            </Field>
            <Field label="Tipo de alvo">
              <select className="fld" value={tipoAlvo} onChange={(e) => setTipoAlvo(e.target.value)}>
                <option value="todos">Todos</option>
                {tiposAlvo.map((t) => <option key={t} value={t}>{t}</option>)}
              </select>
            </Field>
          </div>
          {(q || acao !== "todos" || usuario !== "todos" || tipoAlvo !== "todos" || dataIni || dataFim) && (
            <div className="row" style={{ marginTop: 10 }}>
              <Btn size="sm" icon="x" onClick={() => { setQ(""); setAcao("todos"); setUsuario("todos"); setTipoAlvo("todos"); setDataIni(""); setDataFim(""); }}>Limpar filtros</Btn>
            </div>
          )}
        </div>
      </div>

      <div className="card">
        <div className="tbl-wrap">
          <table className="tbl">
            <thead><tr><th>Quando</th><th>Usuário</th><th>Ação</th><th>Alvo</th><th>Detalhes</th></tr></thead>
            <tbody>
              {filtrados.length === 0 ? (
                <tr><td colSpan="5"><div className="muted small" style={{ padding: "20px 4px", textAlign: "center" }}>
                  {lista.length === 0 ? "Nenhum evento registrado ainda." : "Nenhum evento corresponde aos filtros."}
                </div></td></tr>
              ) : filtrados.map((e) => {
                const dt = new Date(e.ts);
                const quando = isNaN(dt.getTime()) ? e.ts : dt.toLocaleString("pt-BR", { day: "2-digit", month: "short", year: "2-digit", hour: "2-digit", minute: "2-digit" });
                return (
                  <tr key={e._id}>
                    <td className="muted small" style={{ whiteSpace: "nowrap" }}>{quando}</td>
                    <td className="small">{e.email || "—"}</td>
                    <td><span className="mono small strong">{ACAO_LABEL[e.acao] || e.acao}</span></td>
                    <td className="small muted">{e.alvo ? <><span className="muted">{e.alvo.tipo}:</span> <span className="mono">{e.alvo.id}</span></> : "—"}</td>
                    <td className="small muted" style={{ maxWidth: 320, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                      {e.detalhes ? Object.entries(e.detalhes).map(([k, v]) => `${k}: ${typeof v === "object" ? JSON.stringify(v) : v}`).join(" · ") : "—"}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Clientes, Notas, Relatorios, Configuracoes, Auditoria });
