/* PDV — Distribuidores (venda direta por caixa) */

function PdvDistribuidores({ ctx }) {
  const [sub, setSub] = useState("nova");
  const pendingCount = ctx.state.sales.filter(s => s.paid < s.total).length;
  return (
    <>
      <div className="page-head">
        <div>
          <h1>PDV Distribuidores</h1>
          <p>Venda direta por caixa para lojas, mercados e sorveterias parceiras</p>
        </div>
      </div>

      <Tabs
        items={[
          { value:"nova",       label:"Nova venda" },
          { value:"historico",  label:"Histórico" },
          { value:"pendencias", label:`Pendências${pendingCount ? " · "+pendingCount : ""}` },
        ]}
        value={sub}
        onChange={setSub}
      />

      {sub === "nova" && <NovaVendaDistrib ctx={ctx} />}
      {sub === "historico" && <HistDistribuidores ctx={ctx} />}
      {sub === "pendencias" && <PendenciasDistribuidores ctx={ctx} />}
    </>
  );
}

function NovaVendaDistrib({ ctx }) {
  const [client, setClient] = useState(null);
  const [search, setSearch] = useState("");
  const [showClients, setShowClients] = useState(false);
  const [showNewClient, setShowNewClient] = useState(false);
  const [items, setItems] = useState([]); // {productId, boxes, loose}
  const [payment, setPayment] = useState(ctx.state.settings.methods[0] || "PIX");
  const [discount, setDiscount] = useState(0);
  const [showFormat, setShowFormat] = useState(null); // null | 'preview' | 'final'
  const [lastSale, setLastSale] = useState(null);
  const [showHistory, setShowHistory] = useState(false);
  const [showPresets, setShowPresets] = useState(false);
  const [showSavePreset, setShowSavePreset] = useState(false);

  const getBox = (productId) => {
    const p = ctx.state.products.find(x => x.id === productId);
    return p?.boxSize || 60;
  };

  /* histórico do cliente atual (para CTA "repetir última compra") */
  const clientHistory = client
    ? ctx.state.sales.filter(s => s.clientId === client.id).sort((a,b)=>(b.date+""+b.time).localeCompare(a.date+""+a.time))
    : [];
  const lastClientSale = clientHistory[0];

  const addItem = (productId, n) => {
    const inc = n || 1;
    setItems(prev => {
      const ex = prev.find(p => p.productId === productId);
      if (ex) return prev.map(p => p.productId === productId ? { ...p, boxes: (p.boxes || 0) + inc } : p);
      return [...prev, { productId, boxes: inc, loose: 0 }];
    });
  };
  const addLoose = (productId, n) => {
    const inc = n || 1;
    setItems(prev => {
      const ex = prev.find(p => p.productId === productId);
      if (ex) return prev.map(p => p.productId === productId ? { ...p, loose: (p.loose || 0) + inc } : p);
      return [...prev, { productId, boxes: 0, loose: inc }];
    });
  };
  const updateBoxes = (productId, boxes) => {
    setItems(prev => {
      const updated = prev.map(p => p.productId === productId ? { ...p, boxes: Math.max(0, boxes) } : p);
      return updated.filter(p => (p.boxes || 0) > 0 || (p.loose || 0) > 0);
    });
  };
  const updateLoose = (productId, loose) => {
    setItems(prev => {
      const updated = prev.map(p => p.productId === productId ? { ...p, loose: Math.max(0, loose) } : p);
      return updated.filter(p => (p.boxes || 0) > 0 || (p.loose || 0) > 0);
    });
  };

  /* aplica um "lote" (kit pré-montado) ao carrinho atual, somando às quantidades existentes */
  const applyPreset = (preset) => {
    setItems(prev => {
      const next = [...prev];
      preset.items.forEach(({ productId, boxes }) => {
        const i = next.findIndex(p => p.productId === productId);
        if (i >= 0) next[i] = { ...next[i], boxes: (next[i].boxes || 0) + boxes };
        else next.push({ productId, boxes, loose: 0 });
      });
      return next;
    });
    ctx.pushToast(`Lote "${preset.name}" adicionado ao pedido·${preset.items.reduce((s,i)=>s+i.boxes,0)} cx`);
  };

  /* repete a última compra deste cliente */
  const repeatLast = () => {
    if (!lastClientSale) return;
    const reusedItems = lastClientSale.items.map(it => ({
      productId: it.productId,
      boxes: it.boxes || 0,
      loose: it.loose || 0,
    }));
    setItems(reusedItems);
    setPayment(lastClientSale.payment || payment);
    ctx.pushToast(`Última compra carregada · ${reusedItems.length} sabor(es)`);
  };

  const totalUnits = items.reduce((s, i) => s + (i.boxes || 0) * getBox(i.productId) + (i.loose || 0), 0);
  const subtotal = items.reduce((s, i) => {
    const p = ctx.state.products.find(x => x.id === i.productId);
    const units = (i.boxes || 0) * getBox(i.productId) + (i.loose || 0);
    return s + units * (p?.price || 0) * 0.55;
  }, 0);
  const total = Math.max(0, subtotal - discount);

  const filteredClients = ctx.state.distributors.filter(d => d.name.toLowerCase().includes(search.toLowerCase()));

  const finish = () => {
    if (!client || items.length === 0) return;
    // Check stock
    const insufficient = items.find(it => {
      const stockObj = ctx.state.stock.find(x => x.productId === it.productId && x.warehouseId === WH_DISTRIB_ID);
      const needed = (it.boxes || 0) * getBox(it.productId) + (it.loose || 0);
      return !stockObj || stockObj.units < needed;
    });
    if (insufficient) {
      ctx.pushToast("Estoque insuficiente para um dos sabores");
      return;
    }
    const saleId = "VND-" + Date.now().toString(36).toUpperCase();
    const saleSnapshot = {
      id: saleId,
      date: new Date().toISOString().slice(0,10),
      client: { ...client },
      payment, subtotal, discount, total,
      items: items.map(i => ({
        productId: i.productId,
        boxes: i.boxes || 0,
        loose: i.loose || 0,
        boxSize: getBox(i.productId),
      })),
    };
    ctx.actions.finalizeDistribSale({ clientId: client.id, items, payment, total, subtotal, discount });
    setLastSale(saleSnapshot);
    setShowFormat("final");
    setItems([]); setDiscount(0);
  };

  const previewReceipt = (fmt) => {
    if (!client || items.length === 0) { ctx.pushToast("Adicione um cliente e produtos antes"); return; }
    printSaleReceipt({
      company: ctx.state.company,
      sale: {
        id: "PREVIEW-" + Date.now().toString(36).toUpperCase(),
        date: new Date().toISOString().slice(0,10),
        client, payment, subtotal, discount, total,
      },
      items: items.map(i => ({
        productId: i.productId,
        boxes: i.boxes || 0,
        loose: i.loose || 0,
        boxSize: getBox(i.productId),
      })),
      products: ctx.state.products, fmt,
    });
  };

  const printFinal = (fmt, vias) => {
    if (!lastSale) return;
    printSaleReceipt({
      company: ctx.state.company,
      sale: lastSale,
      items: lastSale.items,
      products: ctx.state.products,
      fmt,
      vias: vias || "both",
    });
  };

  return (
    <div style={{ display:"grid", gridTemplateColumns:"1.5fr 1fr", gap:14 }}>
      <div style={{ display:"flex", flexDirection:"column", gap: 14 }}>
        <Card title="Distribuidor" subtitle="Busque por nome, CNPJ ou cidade">
          {!client ? (
            <div style={{ position:"relative" }}>
              <div style={{ display:"flex", alignItems:"center", gap:8, padding:"10px 14px", background:"var(--ink-50)", borderRadius:8, border:"1px solid var(--line)" }}>
                <Icons.Search size={16} color="var(--ink-400)" />
                <input
                  style={{ flex:1, background:"transparent", border:"none", outline:"none", fontSize:14 }}
                  placeholder="Comece a digitar o nome do distribuidor…"
                  value={search}
                  onChange={(e) => { setSearch(e.target.value); setShowClients(true); }}
                  onFocus={() => setShowClients(true)}
                />
                <Button variant="ghost" size="sm" icon={<Icons.Plus size={12}/>} onClick={() => setShowNewClient(true)}>Novo cliente</Button>
              </div>
              {showClients && filteredClients.length > 0 && (
                <div style={{ position:"absolute", left:0, right:0, top:"calc(100% + 4px)", background:"white", border:"1px solid var(--line)", borderRadius:10, boxShadow:"var(--sh-2)", zIndex:5, maxHeight:280, overflow:"auto" }}>
                  {filteredClients.map(d => (
                    <button key={d.id} onClick={() => { setClient(d); setShowClients(false); setPayment(d.payment || ctx.state.settings.methods[0]); }}
                      style={{ width:"100%", padding:"10px 14px", border:"none", background:"transparent", textAlign:"left", borderBottom:"1px solid var(--line)", cursor:"pointer", display:"flex", justifyContent:"space-between", alignItems:"center" }}
                    >
                      <div>
                        <div style={{ fontWeight:600, color:"var(--ink-900)", fontSize:13 }}>{d.name}</div>
                        <div className="subtle">{d.doc} · {d.city}</div>
                      </div>
                      <Chip>{d.payment}</Chip>
                    </button>
                  ))}
                </div>
              )}
              {showClients && search && filteredClients.length === 0 && (
                <div style={{ position:"absolute", left:0, right:0, top:"calc(100% + 4px)", background:"white", border:"1px solid var(--line)", borderRadius:10, padding:14, zIndex:5 }}>
                  <p className="subtle" style={{ margin:0 }}>Nenhum distribuidor encontrado. <a onClick={() => setShowNewClient(true)} style={{ color:"var(--brand-600)", cursor:"pointer", fontWeight:600 }}>Cadastrar novo</a></p>
                </div>
              )}
            </div>
          ) : (
            <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", padding:"12px 14px", background:"linear-gradient(180deg, #FFF1EA 0%, #FDE6DC 100%)", border:"1px solid var(--brand-100)", borderRadius:10, boxShadow:"0 1px 0 rgba(255,255,255,.8) inset, 0 2px 6px -2px rgba(212,49,11,.15)" }}>
              <div style={{ display:"flex", gap:12, alignItems:"center" }}>
                <div className="avatar" style={{ width:42, height:42, fontSize:13, background:"var(--brand-600)" }}>{client.name.split(" ").map(w => w[0]).slice(0,2).join("")}</div>
                <div>
                  <div style={{ fontWeight:700, color:"var(--ink-900)", fontSize:14 }}>{client.name}</div>
                  <div className="subtle">{client.doc} · {client.city} · {client.phone}</div>
                  <div style={{ display:"flex", gap:10, marginTop:4, fontSize:11.5 }}>
                    <span style={{ color:"var(--ink-700)", fontWeight:600 }}>{client.totals?.compras || 0} compras anteriores</span>
                    {client.totals?.valor > 0 && <span className="muted">· {fmtBRL(client.totals.valor)} acumulado</span>}
                  </div>
                </div>
              </div>
              <div style={{ display:"flex", gap:6 }}>
                {lastClientSale && (
                  <Button variant="secondary" size="sm" icon={<Icons.History size={12}/>} onClick={repeatLast} title={`Carrega a compra de ${fmtDate(lastClientSale.date)}`}>Repetir última</Button>
                )}
                <Button variant="secondary" size="sm" icon={<Icons.Eye size={12}/>} onClick={() => setShowHistory(true)}>Histórico</Button>
                <Button variant="ghost" size="sm" onClick={() => { setClient(null); setItems([]); }}>Trocar</Button>
              </div>
            </div>
          )}
        </Card>

        <Card title="Produtos" subtitle="Vendas por caixa fechada (60 unidades) · use os botões +1 / +5 / +10" flush
          action={
            <Button variant="secondary" size="sm" icon={<Icons.Box size={12}/>} onClick={() => setShowPresets(true)}>Lotes prontos</Button>
          }
        >
          {ctx.state.products.length === 0 ? (
            <div className="empty">
              <Icons.Box size={26} color="var(--ink-300)"/>
              <h4>Nenhum produto cadastrado</h4>
              <p>Cadastre produtos para começar a vender.</p>
            </div>
          ) : (
          <div style={{ display:"grid", gridTemplateColumns:"repeat(4, 1fr)", gap: 1, background:"var(--line)" }}>
            {ctx.state.products.map(p => {
              const stock = ctx.state.stock.find(s => s.productId === p.id && s.warehouseId === WH_DISTRIB_ID);
              const availUnits = stock?.units || 0;
              const productBox = p.boxSize || 60;
              const availBoxes = Math.floor(availUnits / productBox);
              const cart = items.find(it => it.productId === p.id);
              const inCartBoxes = cart?.boxes || 0;
              const inCartLoose = cart?.loose || 0;
              const inCartUnits = inCartBoxes * productBox + inCartLoose;
              const lowStock = availBoxes < 3;
              const empty = availUnits === 0;
              return (
                <div key={p.id}
                  style={{ background: inCartUnits > 0 ? "linear-gradient(180deg, #FFF7F4 0%, #FFFFFF 100%)" : "white", padding:"12px 12px 10px", display:"flex", flexDirection:"column", gap:8, opacity: empty ? .55 : 1, position:"relative" }}>
                  {inCartUnits > 0 && (
                    <span style={{ position:"absolute", top:8, right:8, background:"var(--brand-600)", color:"white", borderRadius:100, fontSize:10, fontWeight:700, padding:"2px 7px", letterSpacing:0, lineHeight:1.5, boxShadow:"0 2px 6px -1px rgba(212,49,11,.4)" }}>
                      {inCartBoxes > 0 && `${inCartBoxes} cx`}
                      {inCartBoxes > 0 && inCartLoose > 0 && " + "}
                      {inCartLoose > 0 && `${inCartLoose} un`}
                    </span>
                  )}
                  <div style={{ display:"flex", alignItems:"center", gap:8, justifyContent:"space-between" }}>
                    <div style={{ display:"flex", alignItems:"center", gap:8, minWidth:0 }}>
                      <span style={{ width:14, height:14, borderRadius:4, background:p.color, flexShrink:0 }} />
                      <span style={{ fontSize:11, color:"var(--ink-400)", fontWeight:500, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{p.line}</span>
                    </div>
                    {empty && <Chip tone="danger">esgotado</Chip>}
                  </div>
                  <div style={{ fontSize:13, fontWeight:600, color:"var(--ink-900)", lineHeight:1.25 }}>{p.flavor}</div>
                  <div style={{ display:"flex", flexDirection:"column", gap:1, minHeight: 32 }}>
                    <div className="subtle" style={{ fontSize:11, lineHeight:1.2 }}>
                      <span style={{ color: lowStock && !empty ? "var(--warning)" : "var(--ink-500)", fontWeight:600 }}>{availBoxes}</span> cx · <span className="muted">{availUnits} un</span>
                    </div>
                    <strong className="numeric" style={{ color:"var(--brand-600)", fontSize:11, fontWeight:700 }}>{fmtBRL(p.price * 0.55 * productBox)}/cx <span style={{ color:"var(--ink-400)", fontWeight:500 }}>({productBox}un)</span></strong>
                  </div>
                  <div style={{ display:"flex", gap:4, marginTop:2 }}>
                    {[1, 5, 10].map(n => {
                      const dis = empty || (inCartBoxes + n) > availBoxes;
                      return (
                        <button key={n}
                          onClick={() => addItem(p.id, n)}
                          disabled={dis}
                          style={{
                            flex:1, padding:"5px 0", borderRadius:6,
                            border:"1px solid " + (dis ? "var(--line)" : (n === 1 ? "var(--line-strong)" : "var(--brand-600)")),
                            background: dis ? "var(--ink-50)" : (n === 1 ? "white" : "linear-gradient(180deg, #FFF1EA 0%, #FDE6DC 100%)"),
                            color: dis ? "var(--ink-300)" : (n === 1 ? "var(--ink-800)" : "var(--brand-700)"),
                            fontWeight:700, fontSize:11, cursor: dis?"not-allowed":"pointer",
                            boxShadow: dis ? "none" : "0 1px 0 rgba(255,255,255,.7) inset",
                          }}>+{n}cx</button>
                      );
                    })}
                    {(() => {
                      const looseDis = empty || (inCartUnits + 1) > availUnits;
                      return (
                        <button onClick={() => addLoose(p.id, 1)} disabled={looseDis} title="Adicionar 1 unidade avulsa"
                          style={{
                            padding:"5px 8px", borderRadius:6,
                            border:"1px dashed " + (looseDis ? "var(--line)" : "var(--ink-300)"),
                            background: looseDis ? "var(--ink-50)" : "white",
                            color: looseDis ? "var(--ink-300)" : "var(--ink-700)",
                            fontWeight:700, fontSize:11, cursor: looseDis?"not-allowed":"pointer",
                          }}>+un</button>
                      );
                    })()}
                  </div>
                </div>
              );
            })}
          </div>
          )}
        </Card>
      </div>

      <div style={{ position:"sticky", top: 80, alignSelf:"flex-start" }}>
        <Card title="Pedido" subtitle={`${items.length} sabore${items.length===1?"":"s"} · ${totalUnits} unidades`} flush>
          {items.length === 0 ? (
            <div className="empty">
              <Icons.Box size={26} color="var(--ink-300)" />
              <h4>Carrinho vazio</h4>
              <p>Clique nos produtos ao lado para adicionar caixas ao pedido</p>
            </div>
          ) : (
            <>
              <div style={{ maxHeight: 280, overflow:"auto" }}>
                {items.map(it => {
                  const p = ctx.state.products.find(x => x.id === it.productId);
                  const productBox = p?.boxSize || 60;
                  const boxesUnits = (it.boxes || 0) * productBox;
                  const looseUnits = it.loose || 0;
                  const totalIt = boxesUnits + looseUnits;
                  const valIt = totalIt * (p?.price || 0) * 0.55;
                  return (
                    <div key={it.productId} style={{ padding:"10px 16px", borderBottom:"1px solid var(--line)", display:"flex", flexDirection:"column", gap:6 }}>
                      <div style={{ display:"flex", alignItems:"center", gap:10 }}>
                        <span style={{ width:10, height:10, borderRadius:3, background:p.color, flexShrink:0 }} />
                        <div style={{ flex:1, minWidth:0 }}>
                          <div style={{ fontSize:12.5, fontWeight:600, color:"var(--ink-900)" }}>{p.flavor}</div>
                          <div className="subtle" style={{ fontSize:10.5 }}>{totalIt} un · {fmtBRL(valIt)}</div>
                        </div>
                        <button className="icon-btn" onClick={() => updateBoxes(it.productId, 0) || updateLoose(it.productId, 0)} title="Remover"><Icons.Trash size={13}/></button>
                      </div>
                      <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:8 }}>
                        <div style={{ display:"flex", alignItems:"center", gap:6, justifyContent:"space-between" }}>
                          <span style={{ fontSize:11, color:"var(--ink-500)", fontWeight:600 }}>Caixas ({productBox}un)</span>
                          <Stepper value={it.boxes || 0} onChange={(v) => updateBoxes(it.productId, v)} />
                        </div>
                        <div style={{ display:"flex", alignItems:"center", gap:6, justifyContent:"space-between" }}>
                          <span style={{ fontSize:11, color:"var(--ink-500)", fontWeight:600 }}>Avulsas</span>
                          <Stepper value={it.loose || 0} onChange={(v) => updateLoose(it.productId, v)} />
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
              <div style={{ padding: 16, borderTop:"1px solid var(--line)", background:"var(--canvas)" }}>
                <Field label="Forma de pagamento">
                  <div style={{ display:"grid", gridTemplateColumns:"repeat(3, 1fr)", gap: 6 }}>
                    {ctx.state.settings.methods.map(m => (
                      <button key={m} onClick={() => setPayment(m)}
                        style={{
                          padding:"7px 8px", borderRadius:7, fontSize:12, fontWeight:600,
                          border: "1px solid " + (payment === m ? "var(--brand-600)" : "var(--line)"),
                          background: payment === m ? "var(--brand-50)" : "white",
                          color: payment === m ? "var(--brand-700)" : "var(--ink-700)",
                          cursor:"pointer"
                        }}
                      >{m}</button>
                    ))}
                  </div>
                </Field>
                <div style={{ display:"flex", flexDirection:"column", gap:8, marginTop:14, paddingTop:14, borderTop:"1px dashed var(--line)" }}>
                  <Row label="Subtotal" value={fmtBRL(subtotal)} />
                  <Row label="Desconto" value={
                    <input className="input" value={discount} onChange={e => setDiscount(parseFloat(e.target.value) || 0)}
                      style={{ width:110, textAlign:"right", padding:"4px 8px" }}
                    />
                  } />
                  <Row label={<strong style={{ fontSize:14 }}>Total</strong>} value={<strong style={{ fontSize:18, color:"var(--brand-600)", fontFamily:"var(--font-display)" }}>{fmtBRL(total)}</strong>} />
                </div>
                <div style={{ display:"flex", gap:8, marginTop:14 }}>
                  <Button variant="secondary" icon={<Icons.Print size={14}/>} onClick={() => setShowFormat("preview")} disabled={!client || items.length===0}>Imprimir</Button>
                  <Button variant="primary" style={{ flex:1, justifyContent:"center" }} onClick={finish} disabled={!client}>
                    Finalizar · {fmtBRL(total)}
                  </Button>
                </div>
              </div>
            </>
          )}
        </Card>
      </div>

      {showNewClient && (
        <DistribuidorModal
          initial={null}
          onClose={() => setShowNewClient(false)}
          onSave={(v) => {
            ctx.actions.addDistributor(v);
            // auto-select newly added; need to fetch by name (just use last)
            setShowNewClient(false);
            // Pull the last (newest) distributor — addTo prepends
            setTimeout(() => {
              const newD = ctx.state.distributors.find(d => d.name === v.name && d.doc === v.doc);
              if (newD) setClient(newD);
            }, 0);
          }}
        />
      )}

      {showFormat === "preview" && (
        <ReceiptFormatModal
          title="Pré-visualizar comprovante"
          subtitle="Imprima uma cópia provisória antes de finalizar"
          onClose={() => setShowFormat(null)}
          onPrint={(fmt) => { previewReceipt(fmt); setShowFormat(null); }}
        />
      )}

      {showHistory && client && (
        <ClientHistoryModal
          ctx={ctx}
          kind="distributor"
          client={client}
          onClose={() => setShowHistory(false)}
        />
      )}

      {showPresets && (
        <PresetsModal
          ctx={ctx}
          currentItems={items}
          onApply={(preset) => { applyPreset(preset); setShowPresets(false); }}
          onClose={() => setShowPresets(false)}
          onSaveCurrent={() => { setShowPresets(false); setShowSavePreset(true); }}
          canSaveCurrent={items.length > 0}
        />
      )}

      {showSavePreset && (
        <SavePresetModal
          items={items}
          products={ctx.state.products}
          onClose={() => setShowSavePreset(false)}
          onSave={(payload) => {
            ctx.actions.addSalePreset({ ...payload, items: items.map(({productId, boxes}) => ({ productId, boxes })) });
            setShowSavePreset(false);
          }}
        />
      )}

      {showFormat === "final" && lastSale && (
        <Modal title="✅ Venda finalizada" subtitle={`${lastSale.client.name} · ${fmtBRL(lastSale.total)} · ${lastSale.payment}`}
          onClose={() => { setShowFormat(null); setLastSale(null); setClient(null); setSearch(""); }}
          size="lg"
          footer={
            <Button variant="ghost" onClick={() => { setShowFormat(null); setLastSale(null); setClient(null); setSearch(""); }}>Concluir sem imprimir</Button>
          }
        >
          <SaleReceiptChooser
            note="Estoque e financeiro foram atualizados. Selecione a via e o formato:"
            onPrint={(fmt, vias) => printFinal(fmt, vias)}
          />
        </Modal>
      )}
    </div>
  );
}

function Row({ label, value }) {
  return (
    <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", fontSize:13 }}>
      <span className="muted">{label}</span>
      <span className="numeric">{value}</span>
    </div>
  );
}

function HistDistribuidores({ ctx }) {
  const [reprintSale, setReprintSale] = useState(null);
  const sales = ctx.state.finance.filter(f => f.cat === "Venda Distribuidor").sort((a, b) => b.date.localeCompare(a.date));
  const totalSales = sales.reduce((s, x) => s + x.value, 0);
  const aReceber = sales.filter(s => s.status === "a_receber").reduce((s, x) => s + x.value, 0);

  const onDelete = (s) => ctx.askConfirm({
    title: "Excluir venda?",
    message: "Esta ação remove o lançamento financeiro. O estoque NÃO é restaurado.",
    danger: true,
    onConfirm: () => ctx.actions.deleteFinance(s.id),
  });

  const reprint = (sale, fmt) => {
    // Reconstrói um comprovante "resumo" a partir do lançamento financeiro (não temos itens originais)
    const client = ctx.state.distributors.find(d => d.name === sale.ref) || { name: sale.ref };
    printSaleReceipt({
      company: ctx.state.company,
      sale: { id: sale.id, date: sale.date, client, payment:"—", subtotal: sale.value, discount:0, total: sale.value, perBox:60 },
      items: [], products: ctx.state.products, fmt,
    });
  };

  return (
    <>
      <div className="grid-4" style={{ marginBottom: 14 }}>
        <KPI tone="info" medal={<Icons.Receipt size={18} strokeWidth={2}/>} label="Vendas registradas" value={fmtInt(sales.length)} sub="Histórico completo" />
        <KPI tone="success" medal={<Icons.ArrowDown size={18} strokeWidth={2}/>} label="Faturado total" value={fmtBRL(totalSales)} sub="Soma de todas as vendas" />
        <KPI tone="warning" medal={<Icons.Wallet size={18} strokeWidth={2}/>} label="A receber" value={fmtBRL(aReceber)} sub={`${sales.filter(s => s.status === "a_receber").length} vendas a prazo`} />
        <KPI tone="brand" medal={<Icons.PieChart size={18} strokeWidth={2}/>} label="Ticket médio" value={fmtBRL(sales.length ? totalSales / sales.length : 0)} sub="Por venda" />
      </div>

      <Card title="Histórico de vendas" flush
        action={<Button variant="secondary" size="sm" icon={<Icons.Download size={12}/>} onClick={() => exportSalesCsv(sales)}>Exportar CSV</Button>}
      >
        {sales.length === 0 ? (
          <div className="empty">
            <Icons.Receipt size={26} color="var(--ink-300)"/>
            <h4>Nenhuma venda registrada</h4>
            <p>Use a aba "Nova venda" para registrar a primeira.</p>
          </div>
        ) : (
        <table className="tbl">
          <thead>
            <tr>
              <th>Nº</th>
              <th>Data</th>
              <th>Distribuidor</th>
              <th className="num">Valor</th>
              <th>Status</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {sales.map(s => (
              <tr key={s.id}>
                <td className="mono muted">{s.id}</td>
                <td>{fmtDate(s.date)}</td>
                <td className="strong">{s.ref}</td>
                <td className="num strong numeric">{fmtBRL(s.value)}</td>
                <td>
                  {s.status === "confirmado" ? <Chip tone="success" dot>pago</Chip> : <Chip tone="warning" dot>a receber</Chip>}
                </td>
                <td>
                  <div style={{ display:"flex", gap:2 }}>
                    <button className="icon-btn" title="Reimprimir comprovante" onClick={() => setReprintSale(s)}><Icons.Print /></button>
                    <button className="icon-btn" title="Excluir" onClick={() => onDelete(s)}><Icons.Trash /></button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        )}
      </Card>
      {reprintSale && (
        <ReceiptFormatModal
          title="Reimprimir comprovante"
          subtitle={reprintSale.ref + " · " + fmtBRL(reprintSale.value)}
          onClose={() => setReprintSale(null)}
          onPrint={(fmt) => { reprint(reprintSale, fmt); setReprintSale(null); }}
        />
      )}
    </>
  );
}

window.PdvDistribuidores = PdvDistribuidores;

/* ============ Seletor de formato + vias para comprovante de venda ============ */
function SaleReceiptChooser({ note, onPrint }) {
  const [fmt, setFmt] = useState("a4");
  const [vias, setVias] = useState("both");
  const formats = [
    { value:"a4",   label:"Papel A4",     hint:"Impressora comum",       icon:"📄" },
    { value:"mm80", label:"Térmica 80mm", hint:"Cupom largo",            icon:"🧾" },
    { value:"mm58", label:"Térmica 58mm", hint:"Mini-impressora",        icon:"🎫" },
  ];
  const viasOptions = [
    { value:"both",         label:"Ambas as vias", hint:"Empresa + Distribuidor (recomendado)", icon:"📋📋" },
    { value:"empresa",      label:"Só via empresa",       hint:"Cópia interna",          icon:"🏭" },
    { value:"distribuidor", label:"Só via distribuidor",  hint:"Para o cliente",         icon:"🏪" },
  ];
  return (
    <>
      {note && <p className="muted" style={{ marginTop:0, fontSize:13 }}>{note}</p>}
      <div style={{ marginBottom: 14 }}>
        <div style={{ fontSize:11.5, fontWeight:700, color:"var(--ink-700)", textTransform:"uppercase", letterSpacing:".08em", marginBottom:8 }}>Formato</div>
        <div className="grid-3" style={{ gap:8 }}>
          {formats.map(o => (
            <button key={o.value} onClick={() => setFmt(o.value)}
              style={{
                padding:"12px 14px", borderRadius:10, textAlign:"left", cursor:"pointer",
                display:"flex", alignItems:"center", gap:10,
                border:"1px solid " + (fmt===o.value ? "var(--brand-600)" : "var(--line)"),
                background: fmt===o.value ? "var(--brand-50)" : "white",
                boxShadow: fmt===o.value ? "0 0 0 3px var(--brand-100)" : "none",
                transition:"all .12s",
              }}>
              <div style={{ fontSize:22 }}>{o.icon}</div>
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ fontWeight:700, color:"var(--ink-900)", fontSize:13 }}>{o.label}</div>
                <div className="subtle" style={{ fontSize:11 }}>{o.hint}</div>
              </div>
            </button>
          ))}
        </div>
      </div>
      <div style={{ marginBottom: 14 }}>
        <div style={{ fontSize:11.5, fontWeight:700, color:"var(--ink-700)", textTransform:"uppercase", letterSpacing:".08em", marginBottom:8 }}>Via(s) a imprimir</div>
        <div style={{ display:"flex", flexDirection:"column", gap:6 }}>
          {viasOptions.map(o => (
            <button key={o.value} onClick={() => setVias(o.value)}
              style={{
                padding:"10px 14px", borderRadius:8, textAlign:"left", cursor:"pointer",
                display:"flex", alignItems:"center", gap:12,
                border:"1px solid " + (vias===o.value ? "var(--brand-600)" : "var(--line)"),
                background: vias===o.value ? "var(--brand-50)" : "white",
                transition:"all .12s",
              }}>
              <div style={{ fontSize:18 }}>{o.icon}</div>
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ fontWeight:700, color:"var(--ink-900)", fontSize:13 }}>{o.label}</div>
                <div className="subtle" style={{ fontSize:11 }}>{o.hint}</div>
              </div>
              {vias === o.value && <Icons.Check size={16} color="var(--brand-600)" strokeWidth={2.4}/>}
            </button>
          ))}
        </div>
      </div>
      <Button variant="primary" icon={<Icons.Print size={14}/>} onClick={() => onPrint(fmt, vias)} style={{ width:"100%", justifyContent:"center" }}>Gerar comprovante</Button>
    </>
  );
}

/* ============ Aba Pendências ============ */
function PendenciasDistribuidores({ ctx }) {
  const [payTarget, setPayTarget] = useState(null);
  const [reprintSale, setReprintSale] = useState(null);
  const pending = ctx.state.sales
    .filter(s => s.paid < s.total)
    .sort((a, b) => a.date.localeCompare(b.date));

  const totalPending = pending.reduce((s, x) => s + (x.total - x.paid), 0);
  const totalReceived = pending.reduce((s, x) => s + x.paid, 0);
  const totalSold = pending.reduce((s, x) => s + x.total, 0);

  /* Reimpressão a partir do registro de venda detalhado */
  const reprintFromSale = (sale, fmt, vias) => {
    const client = ctx.state.distributors.find(d => d.id === sale.clientId) || { name: "—" };
    printSaleReceipt({
      company: ctx.state.company,
      sale: { ...sale, client },
      items: sale.items.map(it => ({ productId: it.productId, boxes: it.boxes, unitPrice: it.unitPrice, subtotal: it.subtotal })),
      products: ctx.state.products,
      fmt, vias: vias || "both",
    });
  };

  return (
    <>
      <div className="grid-3" style={{ marginBottom: 14 }}>
        <KPI tone="warning" medal={<Icons.Wallet size={18} strokeWidth={2}/>} label="A receber (total)" value={fmtBRL(totalPending)} sub={`${pending.length} venda(s) pendente(s)`} />
        <KPI tone="info" medal={<Icons.ArrowDown size={18} strokeWidth={2}/>} label="Já recebido (parciais)" value={fmtBRL(totalReceived)} sub="De vendas ainda em aberto" />
        <KPI tone="success" medal={<Icons.Receipt size={18} strokeWidth={2}/>} label="Volume com pendência" value={fmtBRL(totalSold)} sub="Valor original das vendas" />
      </div>

      <Card title="Vendas pendentes" subtitle="Aguardando pagamento integral ou parcelado" flush>
        {pending.length === 0 ? (
          <div className="empty">
            <Icons.Check size={26} color="var(--ink-300)"/>
            <h4>Nenhuma pendência</h4>
            <p>Todas as vendas estão quitadas. 🎉</p>
          </div>
        ) : (
        <table className="tbl">
          <thead>
            <tr>
              <th>Cliente</th>
              <th>Data</th>
              <th>Pagamento</th>
              <th className="num">Total</th>
              <th className="num">Pago</th>
              <th className="num">Pendente</th>
              <th>Progresso</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {pending.map(s => {
              const c = ctx.state.distributors.find(d => d.id === s.clientId);
              const pending = s.total - s.paid;
              const pct = (s.paid / s.total) * 100;
              const isParcial = s.paid > 0;
              return (
                <tr key={s.id}>
                  <td>
                    <div style={{ display:"flex", alignItems:"center", gap:10 }}>
                      <div className="avatar" style={{ width:28, height:28, fontSize:10, background:"linear-gradient(135deg, var(--brand-500), var(--brand-700))" }}>{(c?.name||"?").split(" ").map(w => w[0]).slice(0,2).join("")}</div>
                      <div>
                        <div style={{ fontWeight:600, color:"var(--ink-900)" }}>{c?.name || s.clientId}</div>
                        <div className="subtle">{c?.city || ""}</div>
                      </div>
                    </div>
                  </td>
                  <td>{fmtDate(s.date)}{s.time && s.time !== "—" ? <div className="subtle">{s.time}</div> : null}</td>
                  <td><Chip>{s.payment}</Chip></td>
                  <td className="num strong numeric">{fmtBRL(s.total)}</td>
                  <td className="num numeric" style={{ color: isParcial ? "var(--success)" : "var(--ink-400)" }}>{isParcial ? "+ " + fmtBRL(s.paid) : "—"}</td>
                  <td className="num strong numeric" style={{ color:"var(--warning)" }}>{fmtBRL(pending)}</td>
                  <td style={{ width:140 }}>
                    <div style={{ display:"flex", alignItems:"center", gap:6 }}>
                      <ProgressBar value={s.paid} max={s.total} tone={pct >= 100 ? "ok" : pct >= 50 ? "warn" : "danger"} />
                      <span className="subtle numeric" style={{ minWidth:32, textAlign:"right" }}>{Math.round(pct)}%</span>
                    </div>
                  </td>
                  <td>
                    <div style={{ display:"flex", gap:2 }}>
                      <Button variant="primary" size="sm" icon={<Icons.Wallet size={12}/>} onClick={() => setPayTarget(s)}>Receber</Button>
                      <button className="icon-btn" title="Reimprimir comprovante" onClick={() => setReprintSale(s)}><Icons.Print/></button>
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
        )}
      </Card>

      {payTarget && (
        <ReceiveSalePaymentModal
          sale={payTarget}
          client={ctx.state.distributors.find(d => d.id === payTarget.clientId)}
          methods={ctx.state.settings.methods}
          onClose={() => setPayTarget(null)}
          onConfirm={(payload) => {
            ctx.actions.receiveSalePayment({ saleId: payTarget.id, ...payload });
            setPayTarget(null);
          }}
        />
      )}

      {reprintSale && (
        <Modal title="Reimprimir comprovante" subtitle={`${(ctx.state.distributors.find(d => d.id === reprintSale.clientId) || {}).name || ""} · ${fmtBRL(reprintSale.total)}`}
          size="lg" onClose={() => setReprintSale(null)}
          footer={<Button variant="ghost" onClick={() => setReprintSale(null)}>Fechar</Button>}
        >
          <SaleReceiptChooser
            onPrint={(fmt, vias) => { reprintFromSale(reprintSale, fmt, vias); setReprintSale(null); }}
          />
        </Modal>
      )}
    </>
  );
}

function ReceiveSalePaymentModal({ sale, client, methods, onClose, onConfirm }) {
  const pending = sale.total - sale.paid;
  const [amount, setAmount] = useState(pending);
  const [method, setMethod] = useState(methods?.[0] || "PIX");
  const [date, setDate] = useState(new Date().toISOString().slice(0,10));
  const [err, setErr] = useState("");

  const submit = () => {
    const v = parseFloat(String(amount).replace(",", "."));
    if (!v || v <= 0) { setErr("Valor inválido"); return; }
    if (v > pending + 0.001) { setErr(`Valor maior que o saldo pendente (${fmtBRL(pending)})`); return; }
    onConfirm({ amount: v, method, date });
  };

  const quickFills = [
    { label: "100% (quitar)",  value: pending },
    { label: "50%",            value: Math.round(pending * 0.5 * 100) / 100 },
    { label: "25%",            value: Math.round(pending * 0.25 * 100) / 100 },
  ];

  return (
    <Modal title="Receber pagamento" subtitle={`${client?.name || ""} · saldo de ${fmtBRL(pending)}`} onClose={onClose}
      footer={<><Button variant="ghost" onClick={onClose}>Cancelar</Button><Button variant="primary" icon={<Icons.Check size={14} strokeWidth={2.2}/>} onClick={submit}>Registrar recebimento</Button></>}
    >
      <div style={{ padding:"14px 16px", background:"linear-gradient(180deg, var(--brand-50) 0%, #FFFFFF 100%)", border:"1px solid var(--brand-100)", borderRadius:12, marginBottom:14, display:"flex", gap:14, alignItems:"center", flexWrap:"wrap" }}>
        <div>
          <div className="subtle" style={{ textTransform:"uppercase", letterSpacing:".08em", fontWeight:700, fontSize:10 }}>Total da venda</div>
          <strong className="numeric" style={{ fontSize:18, fontFamily:"var(--font-display)", color:"var(--ink-900)" }}>{fmtBRL(sale.total)}</strong>
        </div>
        <div>
          <div className="subtle" style={{ textTransform:"uppercase", letterSpacing:".08em", fontWeight:700, fontSize:10 }}>Já pago</div>
          <strong className="numeric" style={{ fontSize:18, fontFamily:"var(--font-display)", color:"var(--success)" }}>{fmtBRL(sale.paid)}</strong>
        </div>
        <div>
          <div className="subtle" style={{ textTransform:"uppercase", letterSpacing:".08em", fontWeight:700, fontSize:10 }}>Saldo pendente</div>
          <strong className="numeric" style={{ fontSize:18, fontFamily:"var(--font-display)", color:"var(--warning)" }}>{fmtBRL(pending)}</strong>
        </div>
      </div>

      <Field label="Valor recebido (R$)" required error={err}>
        <input className="input numeric" value={amount} onChange={e => { setErr(""); setAmount(e.target.value.replace(/[^\d.,]/g,"").replace(",", ".")); }} autoFocus style={{ fontSize:20, fontWeight:700, padding:"10px 14px" }} />
      </Field>
      <div style={{ display:"flex", gap:6, marginTop:8 }}>
        {quickFills.map(q => (
          <button key={q.label} onClick={() => { setErr(""); setAmount(q.value); }}
            style={{ padding:"5px 12px", borderRadius:100, fontSize:11.5, fontWeight:600, border:"1px solid var(--line-strong)", background:"white", color:"var(--ink-700)", cursor:"pointer" }}>{q.label}</button>
        ))}
      </div>

      <div className="grid-2" style={{ gap:14, marginTop:14 }}>
        <Field label="Forma de pagamento" required>
          <select className="select" value={method} onChange={e => setMethod(e.target.value)}>
            {(methods || ["PIX","Dinheiro","Cartão","Transferência"]).map(m => <option key={m}>{m}</option>)}
          </select>
        </Field>
        <Field label="Data do recebimento">
          <input className="input" type="date" value={date} onChange={e => setDate(e.target.value)} />
        </Field>
      </div>

      <div style={{ marginTop:14, padding:"10px 14px", background:"var(--info-bg)", color:"var(--info)", borderRadius:8, fontSize:12, display:"flex", gap:8, alignItems:"flex-start" }}>
        <Icons.AlertTriangle size={13} style={{ marginTop:2, flexShrink:0 }}/>
        <span>Este valor entra como <strong>entrada confirmada</strong> em Movimentações. O saldo pendente ({fmtBRL(pending - (parseFloat(String(amount).replace(",", ".")) || 0))} restante) permanece em Pendências até quitação.</span>
      </div>
    </Modal>
  );
}

/* ============ Lotes pré-montados ============ */
function PresetsModal({ ctx, currentItems, onApply, onClose, onSaveCurrent, canSaveCurrent }) {
  const presets = ctx.state.salePresets || [];
  const products = ctx.state.products;

  const getBox = (productId) => {
    const p = products.find(x => x.id === productId);
    return p?.boxSize || 60;
  };

  const calcPresetTotal = (preset) => {
    return preset.items.reduce((sum, it) => {
      const p = products.find(x => x.id === it.productId);
      return sum + (p ? it.boxes * getBox(it.productId) * p.price * 0.55 : 0);
    }, 0);
  };
  const calcPresetUnits = (preset) => preset.items.reduce((s, it) => s + it.boxes * getBox(it.productId), 0);

  return (
    <Modal title="Lotes pré-montados" subtitle="Adicione kits inteiros ao pedido com 1 clique" size="lg" onClose={onClose}
      footer={
        <>
          <Button variant="ghost" onClick={onClose}>Fechar</Button>
          <Button variant="primary" icon={<Icons.Plus size={14}/>} onClick={onSaveCurrent} disabled={!canSaveCurrent}>Salvar pedido atual como lote</Button>
        </>
      }
    >
      {presets.length === 0 ? (
        <div className="empty">
          <Icons.Box size={26} color="var(--ink-300)"/>
          <h4>Nenhum lote cadastrado</h4>
          <p>Crie pedidos rapidamente: monte o carrinho desejado e salve como "lote pré-montado".</p>
        </div>
      ) : (
        <div className="grid-2" style={{ gap:12 }}>
          {presets.map(preset => {
            const total = calcPresetTotal(preset);
            const units = calcPresetUnits(preset);
            // verificação de estoque
            const stockOk = preset.items.every(it => {
              const st = ctx.state.stock.find(s => s.productId === it.productId && s.warehouseId === WH_DISTRIB_ID);
              return st && st.units >= it.boxes * getBox(it.productId);
            });
            return (
              <div key={preset.id}
                style={{
                  padding:"14px 16px", borderRadius:12,
                  border:"1px solid " + (stockOk ? "var(--line)" : "var(--warning)"),
                  background: "linear-gradient(180deg, #FFFFFF 0%, #FAFAFB 100%)",
                  boxShadow: "var(--sh-2)",
                  display:"flex", flexDirection:"column", gap:10,
                }}>
                <div style={{ display:"flex", justifyContent:"space-between", alignItems:"flex-start", gap:8 }}>
                  <div style={{ minWidth:0 }}>
                    <div style={{ fontFamily:"var(--font-display)", fontSize:15, fontWeight:700, color:"var(--ink-900)", letterSpacing:"-.01em" }}>{preset.name}</div>
                    <div className="subtle">{preset.description}</div>
                  </div>
                  {!stockOk && <Chip tone="warning" dot>estoque parcial</Chip>}
                </div>
                <div style={{ display:"flex", flexWrap:"wrap", gap:4 }}>
                  {preset.items.slice(0, 6).map(it => {
                    const p = products.find(x => x.id === it.productId);
                    if (!p) return null;
                    return (
                      <span key={it.productId} className="tag-flavor" style={{ fontSize:10.5 }}>
                        <span className="sw" style={{ background: p.color }} />
                        {p.flavor.length > 14 ? p.flavor.slice(0,14)+"…" : p.flavor} <span style={{ color:"var(--brand-700)", fontWeight:700 }}>×{it.boxes}</span>
                      </span>
                    );
                  })}
                  {preset.items.length > 6 && <span className="chip">+{preset.items.length - 6} sabor(es)</span>}
                </div>
                <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", paddingTop:8, borderTop:"1px dashed var(--line)" }}>
                  <div className="subtle" style={{ fontSize:11 }}>
                    <strong style={{ color:"var(--ink-800)" }}>{preset.items.reduce((s,i)=>s+i.boxes,0)} cx</strong> · {units} un · <strong className="numeric" style={{ color:"var(--brand-600)" }}>{fmtBRL(total)}</strong>
                  </div>
                  <div style={{ display:"flex", gap:4 }}>
                    {!preset.id.startsWith("preset-mix-verao") && !preset.id.startsWith("preset-linha") && !preset.id.startsWith("preset-combo") && !preset.id.startsWith("preset-gold") && (
                      <button className="icon-btn" title="Excluir lote" onClick={() => ctx.askConfirm({ title:"Excluir lote?", message:`Excluir "${preset.name}"?`, danger:true, onConfirm: () => ctx.actions.deleteSalePreset(preset.id) })}>
                        <Icons.Trash size={13}/>
                      </button>
                    )}
                    <Button variant="primary" size="sm" icon={<Icons.Plus size={12}/>} onClick={() => onApply(preset)}>Adicionar</Button>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </Modal>
  );
}

function SavePresetModal({ items, products, onClose, onSave }) {
  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const totalBoxes = items.reduce((s, i) => s + i.boxes, 0);
  const submit = () => {
    if (!name.trim()) return;
    onSave({ name: name.trim(), description: description.trim() || `${items.length} sabores · ${totalBoxes} cx` });
  };
  return (
    <Modal title="Salvar lote pré-montado" subtitle={`${items.length} sabor(es) · ${totalBoxes} cx no carrinho atual`} onClose={onClose}
      footer={<><Button variant="ghost" onClick={onClose}>Cancelar</Button><Button variant="primary" onClick={submit} disabled={!name.trim()}>Salvar lote</Button></>}
    >
      <div style={{ display:"flex", flexDirection:"column", gap:14 }}>
        <Field label="Nome do lote" required>
          <input className="input" value={name} onChange={e => setName(e.target.value)} placeholder="Ex.: Mix do quiosque" autoFocus />
        </Field>
        <Field label="Descrição (opcional)">
          <input className="input" value={description} onChange={e => setDescription(e.target.value)} placeholder="Resumo curto para identificar o lote" />
        </Field>
        <div style={{ padding:12, background:"var(--canvas)", border:"1px solid var(--line)", borderRadius:8 }}>
          <div style={{ fontSize:11, color:"var(--ink-500)", textTransform:"uppercase", letterSpacing:".06em", fontWeight:700, marginBottom:6 }}>Conteúdo</div>
          <div style={{ display:"flex", flexWrap:"wrap", gap:5 }}>
            {items.map(it => {
              const p = products.find(x => x.id === it.productId);
              return (
                <span key={it.productId} className="tag-flavor" style={{ fontSize:11 }}>
                  <span className="sw" style={{ background:p?.color }} />
                  {p?.flavor} <strong style={{ color:"var(--brand-700)" }}>×{it.boxes}</strong>
                </span>
              );
            })}
          </div>
        </div>
      </div>
    </Modal>
  );
}
