/* ============================================================
   PCP — Screens part 1: Dashboard, Estoque, Pedidos
   ============================================================ */

// ---------------------------------------------------------------
// DASHBOARD
// ---------------------------------------------------------------
function Dashboard({ app }) {
  const estoque = app.estoque;
  const criticos = estoque.filter((e) => e.status !== "ok");
  const aVencer = app.lancamentos.filter((l) => l.status === "pendente");
  const totalVencer = aVencer.reduce((s, l) => s + (l.tipo === "saida" ? l.valor : 0), 0);
  const faturMes = app.lancamentos
    .filter((l) => l.tipo === "entrada" && l.status === "pago")
    .reduce((s, l) => s + l.valor, 0);
  const opsProd = app.ops.filter((o) => o.status === "producao").length;

  // série de faturamento dos últimos 6 meses calculada a partir dos lançamentos
  const fatSerie = (() => {
    const hoje = new Date();
    const meses = [];
    for (let i = 5; i >= 0; i--) {
      const d = new Date(hoje.getFullYear(), hoje.getMonth() - i, 1);
      const label = d.toLocaleDateString("pt-BR", { month: "short" }).replace(".", "");
      meses.push({ m: label, y: d.getFullYear(), mn: d.getMonth(), v: 0 });
    }
    // tenta extrair mês de l.data (formato "DD MMM" ou "YYYY-MM-DD")
    const parseMes = (s) => {
      if (!s) return null;
      if (/^\d{4}-\d{2}/.test(s)) { const d = new Date(s + (s.length === 10 ? "T00:00:00" : "")); return { y: d.getFullYear(), mn: d.getMonth() }; }
      const m = /([a-zç]{3,})/i.exec(s);
      if (!m) return null;
      const ms = ["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez"];
      const ix = ms.indexOf(m[1].toLowerCase().slice(0, 3));
      if (ix < 0) return null;
      // ano = atual; se mês > atual, ano anterior (heurística simples)
      const y = ix > hoje.getMonth() ? hoje.getFullYear() - 1 : hoje.getFullYear();
      return { y, mn: ix };
    };
    app.lancamentos.filter((l) => l.tipo === "entrada" && l.status === "pago").forEach((l) => {
      const pm = parseMes(l.data);
      if (!pm) return;
      const b = meses.find((x) => x.y === pm.y && x.mn === pm.mn);
      if (b) b.v += (+l.valor || 0) / 1000; // em milhares
    });
    return meses.map((m) => ({ m: m.m, v: Math.round(m.v) }));
  })();
  const fatDelta = fatSerie.length > 1 && fatSerie[0].v > 0
    ? Math.round((fatSerie[fatSerie.length - 1].v / fatSerie[0].v - 1) * 100)
    : 0;

  // atividade recente: derivada de movimentos + mudanças em pedidos/ops/compras
  const atividade = (() => {
    const items = [];
    (app.movimentos || []).slice(0, 5).forEach((m) => {
      items.push({
        ico: m.tipo === "entrada" ? "arrowUp" : m.tipo === "saida" ? "arrowDown" : "list",
        tone: m.tipo === "entrada" ? "ok" : m.tipo === "saida" ? "info" : "muted",
        txt: `${m.tipo === "entrada" ? "Entrada" : m.tipo === "saida" ? "Baixa" : "Inventário"} de ${m.qtd} ${m.un || ""} — ${m.item || m.sku}`.trim(),
        meta: m.motivo ? `${m.motivo} · ${m.data || ""}` : (m.data || ""),
        key: m._id,
      });
    });
    (app.compras || []).filter((c) => c.status === "sugerida").slice(0, 3).forEach((c) => {
      items.push({ ico: "cart", tone: "info", txt: `Sugestão de compra: ${c.item}`, meta: `${c.motivo || "Compras"}`, key: "c" + c._id });
    });
    return items.slice(0, 8);
  })();

  return (
    <div className="view-inner">
      <div className="metrics">
        <MetricCard icon="dollar" label="Faturamento do mês" value={DB.BRL(faturMes).replace("R$\u00a0", "R$ ")} state="ok" />
        <MetricCard icon="factory" label="OPs abertas" value={app.counts.opsAbertas} foot={opsProd + " em produção"} onClick={() => app.setRoute("pcp")} />
        <MetricCard icon="box" label="Estoque crítico" value={criticos.length} foot="itens precisam de compra" state="crit" onClick={() => app.setRoute("estoque")} />
        <MetricCard icon="clock" label="Pedidos atrasados" value={app.counts.pedidosAtraso} state="warn" onClick={() => app.setRoute("pedidos")} />
        <MetricCard icon="wallet" label="A vencer em 7 dias" value={DB.BRL(totalVencer).replace("R$\u00a0", "R$ ")} foot={aVencer.length + " contas"} onClick={() => app.setRoute("financeiro")} />
      </div>

      <div className="grid2" style={{ marginTop: 22, gridTemplateColumns: "1.55fr 1fr" }}>
        {/* Faturamento */}
        <div className="card">
          <div className="card-head">
            <h3>Faturamento mês a mês</h3>
            <span className="sub">em milhares de R$</span>
            <span className="spacer" />
            {fatDelta !== 0 && <Badge tone={fatDelta >= 0 ? "ok" : "crit"} dotted>{fatDelta >= 0 ? "+" : ""}{fatDelta}% no semestre</Badge>}
          </div>
          <div className="card-pad">
            <MiniBars data={fatSerie} height={150} />
          </div>
        </div>

        {/* Estoque crítico */}
        <div className="card">
          <div className="card-head">
            <Icon name="alert" size={15} style={{ color: "var(--crit)" }} />
            <h3>Estoque crítico</h3>
            <span className="spacer" />
            <a className="small" style={{ color: "var(--accent)", cursor: "pointer", fontWeight: 600 }} onClick={() => app.setRoute("estoque")}>Ver tudo</a>
          </div>
          <div style={{ padding: "4px 0" }}>
            {criticos.slice(0, 5).map((e) => (
              <div key={e.sku} className="row" style={{ padding: "9px 16px", gap: 12, borderBottom: "1px solid var(--line-soft)" }}>
                <span className="sku" style={{ width: 42 }}>{e.sku}</span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, color: "var(--ink)", fontWeight: 500, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{e.nome}</div>
                  <div className="small muted">{e.saldo} {e.un} · mín. {e.min}</div>
                </div>
                <Badge tone={e.status} dotted>{e.status === "crit" ? "Zerado" : "Baixo"}</Badge>
              </div>
            ))}
          </div>
        </div>
      </div>

      <div className="grid2" style={{ marginTop: 16, gridTemplateColumns: "1.55fr 1fr", alignItems: "start" }}>
        {/* Atividade */}
        <div className="card">
          <div className="card-head"><h3>Atividade recente</h3></div>
          <div style={{ padding: "6px 0" }}>
            {atividade.length === 0 ? (
              <div className="small muted" style={{ padding: "16px" }}>Sem atividade ainda — mova estoque, receba uma compra ou finalize uma OP.</div>
            ) : atividade.map((a) => (
              <div key={a.key} className="row" style={{ padding: "10px 16px", gap: 12 }}>
                <span className="m-ico" style={{ width: 30, height: 30,
                  color: a.tone === "crit" ? "var(--crit)" : a.tone === "ok" ? "var(--ok)" : "var(--accent)",
                  background: a.tone === "crit" ? "var(--crit-tint)" : a.tone === "ok" ? "var(--ok-tint)" : "var(--accent-tint)",
                  borderColor: "transparent", borderRadius: 8, display: "grid", placeItems: "center", flex: "none", border: "1px solid" }}>
                  <Icon name={a.ico} size={15} />
                </span>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, color: "var(--ink)", fontWeight: 500, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.txt}</div>
                  <div className="small muted">{a.meta}</div>
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* Atalhos */}
        <div className="card card-pad">
          <SectionLabel>Atalhos rápidos</SectionLabel>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
            {[
              { icon: "arrowDown", t: "Dar baixa", r: "estoque" },
              { icon: "truck", t: "Receber compra", m: "receberCompra" },
              { icon: "fileText", t: "Novo pedido", m: "novoPedido" },
              { icon: "factory", t: "Planejar produção", r: "pcp" },
              { icon: "dollar", t: "Lançamento", m: "lancamento" },
              { icon: "chart", t: "Relatórios", r: "relatorios" },
            ].map((s) => (
              <button key={s.t} className="btn" style={{ height: 64, flexDirection: "column", gap: 7, justifyContent: "center" }} onClick={() => s.m ? app.openModal(s.m) : app.setRoute(s.r)}>
                <Icon name={s.icon} size={18} style={{ color: "var(--accent)" }} />
                <span style={{ fontSize: 12.5 }}>{s.t}</span>
              </button>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------
// ESTOQUE
// ---------------------------------------------------------------
function Estoque({ app }) {
  const [sel, setSel] = useState(app.estoque[0] ? app.estoque[0].sku : null);
  const [q, setQ] = useState("");
  const [filt, setFilt] = useState("todos");
  const [sort, setSort] = useState({ k: "status", dir: 1 });
  const estoque = app.estoque;

  const rows = useMemo(() => {
    let r = estoque.filter((e) => {
      if (filt === "crit" && e.status === "ok") return false;
      if (filt === "disp" && e.status !== "ok") return false;
      if (q && !(e.nome + " " + e.sku).toLowerCase().includes(q.toLowerCase())) return false;
      return true;
    });
    const ord = { crit: 0, warn: 1, ok: 2 };
    r = [...r].sort((a, b) => {
      let av, bv;
      if (sort.k === "status") { av = ord[a.status]; bv = ord[b.status]; }
      else if (sort.k === "saldo") { av = a.saldo; bv = b.saldo; }
      else if (sort.k === "valor") { av = a.saldo * a.preco; bv = b.saldo * b.preco; }
      else { av = a.nome; bv = b.nome; }
      return (av > bv ? 1 : av < bv ? -1 : 0) * sort.dir;
    });
    return r;
  }, [estoque, q, filt, sort]);

  const item = estoque.find((e) => e.sku === sel);
  const total = estoque.length;
  const disp = estoque.filter((e) => e.status === "ok").length;
  const crit = estoque.filter((e) => e.status !== "ok").length;
  const valorTotal = estoque.reduce((s, e) => s + e.saldo * e.preco, 0);
  const setSortK = (k) => setSort((s) => ({ k, dir: s.k === k ? -s.dir : 1 }));

  // Quick entrada/saída no item selecionado
  const [movQtd, setMovQtd] = useState(1);
  const moverSelecionado = (sinal) => {
    if (!item) { app.toast("Selecione um item da lista primeiro", "warn"); return; }
    const q = Math.abs(+movQtd || 0);
    if (q <= 0) { app.toast("Informe uma quantidade maior que zero", "warn"); return; }
    app.move(item.sku, sinal * q);
    setMovQtd(1);
  };

  return (
    <div className="view-inner">
      <div className="page-head head-row">
        <div>
          <div className="crumb">Operação</div>
          <h1 className="page-title">Estoque</h1>
          <p className="page-sub">{total} itens · {crit} abaixo do mínimo · {DB.BRL(valorTotal).replace("R$\u00a0", "R$ ")} em estoque</p>
        </div>
        <div className="spacer" />
        <div className="row gap8">
          <Btn icon="upload" onClick={() => app.openModal("importar", { entity: "estoque" })}>Importar</Btn>
          <Btn icon="download" onClick={() => { PCPExport.modelo("estoque"); app.toast("Modelo de estoque baixado", "ok"); }}>Modelo</Btn>
          <Btn icon="download" onClick={() => app.openModal("exportar", { entity: "estoque" })}>Exportar</Btn>
          <Btn icon="scan" onClick={() => app.openModal("scanner")}>Scanner</Btn>
          <Btn icon="plus" variant="primary" onClick={() => app.openModal("novoItem")}>Novo item</Btn>
        </div>
      </div>

      <div className="metrics" style={{ gridTemplateColumns: "repeat(4, 1fr)", marginBottom: 18 }}>
        <MetricCard icon="layers" label="Total de itens" value={total} />
        <MetricCard icon="checkCircle" label="Disponíveis" value={disp} state="ok" />
        <MetricCard icon="alert" label="Críticos" value={crit} state="crit" />
        <MetricCard icon="dollar" label="Valor em estoque" value={DB.BRL(valorTotal).replace("R$\u00a0", "R$ ")} />
      </div>

      <div className="detail-grid">
        <div className="card">
          <div className="card-head" style={{ flexWrap: "wrap", rowGap: 8 }}>
            <div className="input" style={{ width: 240, height: 32 }}>
              <Icon name="search" size={15} />
              <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Buscar por nome ou SKU…" />
            </div>
            <div className="seg">
              {[["todos", "Todos"], ["disp", "Disponíveis"], ["crit", "Críticos"]].map(([k, l]) => (
                <button key={k} className={filt === k ? "on" : ""} onClick={() => setFilt(k)}>{l}</button>
              ))}
            </div>
            <span className="spacer" />
            <div className="row gap6" style={{ alignItems: "center" }} title={item ? "Movimentar " + item.nome : "Selecione um item da lista primeiro"}>
              <input className="fld right mono" type="number" min="1" value={movQtd} onChange={(e) => setMovQtd(e.target.value)} style={{ width: 70, height: 32 }} disabled={!item} />
              <Btn size="sm" icon="arrowUp" variant="primary" disabled={!item} onClick={() => moverSelecionado(1)}>Entrada</Btn>
              <Btn size="sm" icon="arrowDown" disabled={!item} onClick={() => moverSelecionado(-1)}>Saída</Btn>
            </div>
            <span className="small muted" style={{ marginLeft: 10 }}>{rows.length} itens</span>
          </div>

          <div className="tbl-wrap">
            <table className="tbl">
              <thead>
                <tr>
                  <th className="sortable" onClick={() => setSortK("nome")}>Item</th>
                  <th className="num sortable" onClick={() => setSortK("saldo")}>Saldo</th>
                  <th className="num">Mín.</th>
                  <th className="num">Disp.</th>
                  <th className="sortable" onClick={() => setSortK("status")}>Status</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {rows.map((e) => (
                  <tr key={e.sku} className={(e.status !== "ok" ? "row-" + e.status + " " : "") + "clickable" + (sel === e.sku ? " selected" : "")}
                    onClick={() => setSel(e.sku)}>
                    <td>
                      <div className="row gap8">
                        <span className="sku">{e.sku}</span>
                        <span className="strong" style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", maxWidth: 230 }}>{e.nome}</span>
                      </div>
                    </td>
                    <td className="num"><span className="strong">{DB.NUM(e.saldo)}</span> <span className="muted small">{e.un}</span></td>
                    <td className="num muted">{e.min}</td>
                    <td className="num">{e.disp}</td>
                    <td><Badge tone={e.status} dotted>{e.status === "crit" ? "Zerado" : e.status === "warn" ? "Baixo" : "OK"}</Badge></td>
                    <td onClick={(ev) => ev.stopPropagation()}>
                      <RowMenu items={[
                        { icon: "eye", label: "Ver detalhes", onClick: () => setSel(e.sku) },
                        { icon: "edit", label: "Editar", onClick: () => app.openModal("novoItem", { edit: e }) },
                        { icon: "arrowUp", label: "Dar entrada", onClick: () => app.move(e.sku, 1) },
                        { icon: "qr", label: "Código de barras", onClick: () => app.openModal("scanner") },
                        { sep: true },
                        { icon: "trash", label: "Excluir", danger: true, onClick: () => app.openModal("confirm", { title: "Excluir " + e.sku + "?", message: <>O item <b>{e.nome}</b> será removido do estoque. Esta ação não pode ser desfeita.</>, successMsg: e.sku + " excluído", onConfirm: () => app.removeItem(e.sku) }) },
                      ]} />
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
            {rows.length === 0 && <Empty icon="box" title="Nenhum item encontrado" action={<Btn icon="x" size="sm" onClick={() => { setQ(""); setFilt("todos"); }}>Limpar filtros</Btn>}>Ajuste a busca ou os filtros acima.</Empty>}
          </div>
        </div>

        <div className="side-panel">
          {item ? <ItemDetail item={item} app={app} /> : (
            <div className="card"><Empty icon="eye" title="Selecione um item">Clique numa linha para ver detalhes, histórico e fornecedor.</Empty></div>
          )}
        </div>
      </div>
    </div>
  );
}

function Stepper({ item, app }) {
  const [flash, setFlash] = useState(false);
  const go = (delta) => { app.move(item.sku, delta); setFlash(true); setTimeout(() => setFlash(false), 600); };
  return (
    <span className={"stepper" + (flash ? " flash-ok" : "")}>
      <button className="minus" onClick={() => go(-1)} aria-label="Dar baixa">−</button>
      <span className="v">{DB.NUM(item.saldo)}</span>
      <button className="plus" onClick={() => go(1)} aria-label="Dar entrada">+</button>
    </span>
  );
}

function ItemDetail({ item, app }) {
  const pct = Math.min(100, Math.round((item.saldo / Math.max(item.min, 1)) * 100));
  return (
    <div className="card">
      <div className="card-head">
        <span className="sku">{item.sku}</span>
        <span className="spacer" />
        <IconBtn icon="edit" title="Editar" onClick={() => app.openModal("novoItem", { edit: item })} />
        <IconBtn icon="qr" title="QR / código de barras" onClick={() => app.openModal("scanner")} />
        <RowMenu up items={[
          { icon: "edit", label: "Editar item", onClick: () => app.openModal("novoItem", { edit: item }) },
          { icon: "scan", label: "Escanear código", onClick: () => app.openModal("scanner") },
          { sep: true },
          { icon: "trash", label: "Excluir", danger: true, onClick: () => app.openModal("confirm", { title: "Excluir " + item.sku + "?", message: <>O item <b>{item.nome}</b> será removido. Esta ação não pode ser desfeita.</>, successMsg: item.sku + " excluído", onConfirm: () => app.removeItem(item.sku) }) },
        ]} />
      </div>
      <div className="card-pad">
        <div className="img-slot" style={{ height: 260, marginBottom: 14, padding: 0, overflow: "hidden" }}>
          {item.imgUrl ? <img src={item.imgUrl} alt="" style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} /> : <span className="muted small">sem foto</span>}
        </div>
        <div style={{ fontSize: 15, fontWeight: 600, marginBottom: 2 }}>{item.nome}</div>
        <div className="small muted" style={{ marginBottom: 14 }}>Matéria-prima · {item.un}</div>

        <div className="row" style={{ justifyContent: "space-between", marginBottom: 6 }}>
          <span className="small muted">Saldo vs. mínimo</span>
          <span className="small"><b style={{ color: "var(--ink)" }}>{item.saldo}</b> / {item.min} {item.un}</span>
        </div>
        <Bar value={pct} tone={item.status} style={{ marginBottom: 16 }} />

        <dl className="kv">
          <dt>Disponível</dt><dd>{item.disp} {item.un}</dd>
          <dt>Reservado</dt><dd>{item.reservado} {item.un}</dd>
          <dt>Fornecedor</dt><dd>{item.forn}</dd>
        </dl>

        <div className="divider" />
        <SectionLabel>Movimentações recentes</SectionLabel>
        {(() => {
          const movs = (app.movimentos || []).filter((m) => m.sku === item.sku).slice(0, 5);
          if (movs.length === 0) return <div className="small muted" style={{ padding: "8px 0" }}>Sem movimentações ainda para este item.</div>;
          return movs.map((m, i) => {
            const tone = m.tipo === "entrada" ? "ok" : m.tipo === "saida" ? "crit" : "muted";
            return (
              <div key={m._id} className="row" style={{ padding: "7px 0", borderBottom: i < movs.length - 1 ? "1px solid var(--line-soft)" : "none" }}>
                <Icon name={m.tipo === "entrada" ? "arrowUp" : m.tipo === "saida" ? "arrowDown" : "list"} size={14} style={{ color: tone === "muted" ? "var(--muted)" : "var(--" + tone + ")" }} />
                <span className="small" style={{ flex: 1 }}>{m.motivo || (m.tipo === "entrada" ? "Entrada" : m.tipo === "saida" ? "Baixa" : "Inventário")}</span>
                <span className="small muted">{m.data}</span>
                {m.qtd > 0 && <span className="small mono" style={{ color: "var(--" + tone + ")", fontWeight: 600, width: 56, textAlign: "right" }}>{m.tipo === "entrada" ? "+" : m.tipo === "saida" ? "−" : ""}{m.qtd} {m.un || ""}</span>}
              </div>
            );
          });
        })()}
        <Btn size="sm" icon="list" style={{ width: "100%", marginTop: 12 }} onClick={() => app.setRoute("movimentacoes")}>Ver histórico completo</Btn>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------
// PEDIDOS (kanban)
// ---------------------------------------------------------------
const KCOLS = [
  { id: "aberto", label: "Em aberto", color: "var(--muted)" },
  { id: "andamento", label: "Em andamento", color: "var(--accent)" },
  { id: "concluido", label: "Concluído", color: "var(--ok)" },
  { id: "cancelado", label: "Cancelado", color: "var(--crit)" },
];

function Pedidos({ app }) {
  const [view, setView] = useState("kanban");
  const [q, setQ] = useState("");
  const [canal, setCanal] = useState("todos");
  const [dragId, setDragId] = useState(null);
  const [overCol, setOverCol] = useState(null);
  const CH_META = { loja: { label: "Loja", icon: "building" }, mercado_livre: { label: "Mercado Livre", icon: "tag" }, shopee: { label: "Shopee", icon: "cart" } };
  const MKT_TO_STATUS = { novo: "aberto", a_enviar: "aberto", enviado: "andamento", entregue: "concluido", cancelado: "cancelado" };
  const mktSrc = window.MKT_ORDERS || {};
  const mktPed = [["ml", "mercado_livre"], ["shopee", "shopee"]].flatMap(([key, cn]) =>
    (mktSrc[key] || []).map((o) => ({ _id: key + "-" + o.id, os: o.id, cliente: o.comprador, produto: o.produto, qtd: o.qtd, valor: o.valor, status: MKT_TO_STATUS[o.status], prio: 5, entrega: o.data, atrasado: false, canal: cn, _mkt: o, _ch: key })));
  const merged = [...app.pedidos.map((p) => ({ ...p, canal: p.canal || "loja" })), ...mktPed];
  const all = merged.filter((p) => canal === "todos" || p.canal === canal);
  const peds = all.filter((p) => !q || (p.os + p.cliente + p.produto).toLowerCase().includes(q.toLowerCase()));
  const ticket = Math.round(peds.reduce((s, p) => s + p.valor, 0) / Math.max(peds.length, 1));
  const atrasados = all.filter((p) => p.atrasado).length;
  const openPedido = (p) => p._mkt ? app.openModal("pedidoMktDetail", { o: p._mkt, channel: p._ch, name: CH_META[p.canal].label, icon: CH_META[p.canal].icon }) : app.openModal("pedidoDetail", { pedido: p });
  const importMkt = (p) => app.openModal("confirm", { title: "Importar pedido para o PCP?", icon: "download", message: <>O pedido <b>{p.os}</b> de <b>{CH_META[p.canal].label}</b> será criado como pedido interno.</>, confirmLabel: "Importar pedido", successMsg: "Pedido " + p.os + " importado", onConfirm: () => app.criarPedido({ os: (p._ch === "ml" ? "ML" : "SH") + p.os.slice(-5), cliente: p.cliente + " · " + CH_META[p.canal].label, produto: p.produto, qtd: p.qtd, valor: p.valor, prio: 5, entrega: "—", canal: p.canal }) });
  const cancelPedido = (p) => app.openModal("confirm", { title: "Cancelar OS " + p.os + "?", icon: "x", message: <>O pedido de <b>{p.cliente}</b> será movido para cancelados e as reservas de estoque serão liberadas.</>, confirmLabel: "Cancelar pedido", successMsg: "OS " + p.os + " cancelada", onConfirm: () => app.moverPedidoStatus(p._id, "cancelado") });
  const deletePedido = (p) => app.openModal("confirm", { title: "Excluir OS " + p.os + "?", message: <>O pedido de <b>{p.cliente}</b> será removido definitivamente.</>, successMsg: "OS " + p.os + " excluída", onConfirm: () => app.excluirPedido(p._id) });
  const pedidoMenu = (p) => [
    { icon: "eye", label: "Abrir pedido", onClick: () => app.openModal("pedidoDetail", { pedido: p }) },
    { icon: "edit", label: "Editar pedido", onClick: () => app.openModal("novoPedido", { edit: p }) },
    { icon: "factory", label: "Gerar OP", onClick: () => app.openModal("novaOP", { fromPedido: p }) },
    { icon: "printer", label: "Imprimir", onClick: () => PCPExport.printPedido(p, app) },
    { sep: true },
    p.status === "cancelado"
      ? { icon: "trash", label: "Excluir", danger: true, onClick: () => deletePedido(p) }
      : { icon: "x", label: "Cancelar pedido", danger: true, onClick: () => cancelPedido(p) },
  ];
  const menuFor = (p) => p._mkt ? [
    { icon: "eye", label: "Ver detalhe", onClick: () => openPedido(p) },
    { icon: "download", label: "Importar para o PCP", onClick: () => importMkt(p) },
    { icon: "link", label: "Abrir no " + CH_META[p.canal].label, onClick: () => window.open("https://www." + (p._ch === "ml" ? "mercadolivre.com.br/vendas" : "shopee.com.br/portal/sale") + "/" + p.os, "_blank") },
  ] : pedidoMenu(p);

  // drag-and-drop: mover pedido interno entre colunas de status
  const dropTo = (colId) => {
    const id = dragId; setOverCol(null); setDragId(null);
    if (!id) return;
    const p = app.pedidos.find((x) => x._id === id);
    if (!p || p.status === colId) return;
    app.moverPedidoStatus(id, colId);
    app.toast("OS " + p.os + " → " + KCOLS.find((c) => c.id === colId).label, "ok");
  };

  return (
    <div className="view-inner">
      <div className="page-head head-row">
        <div>
          <div className="crumb">Pedidos</div>
          <h1 className="page-title">Resumo dos pedidos</h1>
          <p className="page-sub">{all.length} pedido{all.length === 1 ? "" : "s"} · {atrasados} atrasado{atrasados === 1 ? "" : "s"}</p>
        </div>
        <div className="spacer" />
        <div className="row gap8">
          <Btn icon="upload" onClick={() => app.openModal("importar", { entity: "pedidos" })}>Importar</Btn>
          <Btn icon="download" onClick={() => { PCPExport.modelo("pedidos"); app.toast("Modelo de pedidos baixado", "ok"); }}>Modelo</Btn>
          <Btn icon="download" onClick={() => app.openModal("exportar", { entity: "pedidos" })}>Exportar</Btn>
          <Btn icon="plus" variant="primary" onClick={() => app.openModal("novoPedido")}>Novo pedido</Btn>
        </div>
      </div>

      <div className="metrics" style={{ gridTemplateColumns: "repeat(4, 1fr)", marginBottom: 18 }}>
        <MetricCard icon="fileText" label="Total" value={all.length} />
        <MetricCard icon="inbox" label="Em aberto" value={all.filter((p) => p.status === "aberto").length} />
        <MetricCard icon="play" label="Em andamento" value={all.filter((p) => p.status === "andamento").length} />
        <MetricCard icon="clock" label="Atrasados" value={atrasados} state="warn" />
      </div>

      <div className="toolbar" style={{ marginBottom: 14 }}>
        <div className="input" style={{ width: 280 }}>
          <Icon name="search" size={15} />
          <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Buscar por OS, cliente ou produto…" />
        </div>
        <div className="seg">
          <button className={view === "kanban" ? "on" : ""} onClick={() => setView("kanban")}><Icon name="grid" size={14} />Kanban</button>
          <button className={view === "lista" ? "on" : ""} onClick={() => setView("lista")}><Icon name="list" size={14} />Lista</button>
        </div>
        <div className="seg">
          {[["todos", "Todos os canais"], ["loja", "Loja"], ["mercado_livre", "Mercado Livre"], ["shopee", "Shopee"]].map(([k, l]) => (
            <button key={k} className={canal === k ? "on" : ""} onClick={() => setCanal(k)}>{l}</button>
          ))}
        </div>
        <span className="spacer" />
        <Btn icon="filter" size="sm" onClick={() => app.openModal("filtros", { kind: "pedidos" })}>Filtros</Btn>
      </div>

      {view === "kanban" ? (
        <div className="kanban">
          {KCOLS.map((col) => {
            const cards = peds.filter((p) => p.status === col.id);
            const isOver = overCol === col.id && dragId;
            return (
              <div key={col.id} className="kcol"
                style={isOver ? { outline: "2px dashed var(--accent)", outlineOffset: -2, background: "var(--accent-tint)" } : undefined}
                onDragOver={(e) => { if (dragId) { e.preventDefault(); e.dataTransfer.dropEffect = "move"; if (overCol !== col.id) setOverCol(col.id); } }}
                onDragLeave={(e) => { if (e.currentTarget === e.target) setOverCol((c) => c === col.id ? null : c); }}
                onDrop={(e) => { e.preventDefault(); dropTo(col.id); }}>
                <div className="kcol-head">
                  <span className="dot" style={{ background: col.color }} />
                  <span className="t">{col.label}</span>
                  <span className="n">{cards.length}</span>
                  <span className="spacer" />
                  <IconBtn icon="plus" size={14} onClick={() => app.openModal("novoPedido")} />
                </div>
                <div className="kcol-body">
                  {cards.map((p) => <PedidoCard key={p._id} p={p} app={app} menu={menuFor} onOpen={openPedido} chMeta={CH_META}
                    draggable={!p._mkt} dragging={dragId === p._id}
                    onDragStart={(e) => { setDragId(p._id); e.dataTransfer.effectAllowed = "move"; try { e.dataTransfer.setData("text/plain", p._id); } catch (_) {} }}
                    onDragEnd={() => { setDragId(null); setOverCol(null); }} />)}
                  {cards.length === 0 && <div className="small muted" style={{ padding: "16px 6px", textAlign: "center" }}>{dragId ? "Solte aqui" : "Nenhum pedido"}</div>}
                </div>
              </div>
            );
          })}
        </div>
      ) : (
        <div className="card tbl-wrap">
          <table className="tbl">
            <thead><tr><th>OS</th><th>Cliente</th><th>Canal</th><th>Produto</th><th className="num">Qtd</th><th className="num">Valor</th><th>Entrega</th><th>Status</th><th></th></tr></thead>
            <tbody>
              {peds.map((p) => (
                <tr key={p._id} className={(p.atrasado ? "row-warn " : "") + "clickable"} onClick={() => openPedido(p)}>
                  <td><span className="mono strong">{p.os}</span></td>
                  <td className="strong">{p.cliente}</td>
                  <td><span className="mkt-chip" style={{ margin: 0 }}><Icon name={CH_META[p.canal].icon} size={12} />{CH_META[p.canal].label}</span></td>
                  <td className="muted">{p.produto}</td>
                  <td className="num">{p.qtd}</td>
                  <td className="num strong">{DB.BRL(p.valor)}</td>
                  <td>{p.atrasado ? <Badge tone="warn" dotted>{p.entrega}</Badge> : p.entrega}</td>
                  <td><Badge tone={p.status === "concluido" ? "ok" : p.status === "cancelado" ? "crit" : p.status === "andamento" ? "accent" : undefined} dotted>{KCOLS.find((c) => c.id === p.status).label}</Badge></td>
                  <td onClick={(e) => e.stopPropagation()}>
                    <RowMenu items={menuFor(p)} />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

function PedidoCard({ p, app, menu, onOpen, chMeta, draggable, dragging, onDragStart, onDragEnd }) {
  const alerta = p.alerta === "ruptura" ? { t: "Ruptura de estoque", tone: "crit", icon: "alert" }
    : p.alerta === "atrasado" ? { t: "Entrega atrasada", tone: "warn", icon: "clock" }
    : p.alerta === "margem" ? { t: "Margem negativa", tone: "crit", icon: "trendDown" } : null;
  const ch = chMeta && p.canal && p.canal !== "loja" ? chMeta[p.canal] : null;
  return (
    <div className="kcard" draggable={draggable} onDragStart={onDragStart} onDragEnd={onDragEnd}
      style={{ opacity: dragging ? 0.4 : 1, cursor: draggable ? "grab" : "pointer" }}
      onClick={() => (onOpen ? onOpen(p) : app.openModal("pedidoDetail", { pedido: p }))}>
      <div className="kc-top">
        <span className="os">{ch ? p.os : "OS " + p.os}</span>
        <span className="spacer" style={{ flex: 1 }} />
        {menu && <span onClick={(e) => e.stopPropagation()} style={{ marginRight: 2 }}><RowMenu items={menu(p)} /></span>}
        <span className="prio" style={{ color: p.prio >= 7 ? "var(--crit)" : "var(--muted)", fontSize: 11 }}>
          <Icon name="zap" size={11} />P{p.prio}
        </span>
      </div>
      {(() => {
        const itens = app.normItens ? app.normItens(p) : (p.itens || []);
        const qtdTotal = itens.reduce((s, x) => s + (+x.qtd || 0), 0) || p.qtd;
        if (itens.length > 1) {
          return (
            <>
              <div className="kc-title">{itens[0].nome}</div>
              <div className="kc-cli">{p.cliente} · {itens.length} itens · {qtdTotal}un</div>
            </>
          );
        }
        return (
          <>
            <div className="kc-title">{(itens[0] && itens[0].nome) || p.produto}</div>
            <div className="kc-cli">{p.cliente} · {qtdTotal}un</div>
          </>
        );
      })()}
      {ch && <div style={{ marginTop: 8 }}><span className="mkt-chip" style={{ margin: 0 }}><Icon name={ch.icon} size={12} />{ch.label}</span></div>}
      {alerta && <div style={{ marginTop: 9 }}><Badge tone={alerta.tone} dotted>{alerta.t}</Badge></div>}
      <div className="kc-foot">
        <Icon name="calendar" size={13} />
        <span>{p.entrega}</span>
        <span className="spacer" />
        <span className="mono strong" style={{ color: "var(--ink)" }}>{DB.BRL(p.valor)}</span>
      </div>
    </div>
  );
}

Object.assign(window, { Dashboard, Estoque, Pedidos });
