// js/components/pages/NovaVendaPage.jsx
// [Wave 24 v224.5 NUCLEAR EXTRACT 2026-05-23] 833L → ~480L
// 3 arquivos novos extraídos (ZERO mudança lógica):
//   - js/lib/novavenda/calcs.js (constantes + 11 factories puras)
//   - widgets/novavenda/ItemsListPanel.jsx (search produto + tabela + desconto global + pricing)
//   - widgets/novavenda/PaymentFretePanel.jsx (frete + NF + pagamento)
//
// Este arquivo agora é ORQUESTRADOR: states + refs + useEffects + handleSave LITERAL + render
//   header, pagamento confirmação, cliente, ItemsListPanel, PaymentFretePanel, obs, button, exit modal.
//
// CRITICAL: handleSave (L121-247 do original) preservado LITERAL — toca createSaleAtomic +
//   setSales + setQuotes + setProducts + setReceivables. NÃO MUDAR atomicidade.
//
// Original: Extraído de index.html em Fase 6 (2026-04-29): L2041-L2649
// Deps runtime: fmt, today, itemNet, nid, genIdUUID, toast, createSaleAtomic, createDiscountRequestAtomic,
//   confirmForceCreateForOverdueClient, mapErrorToUX, znxGuard, znxCounter, refreshProducts,
//   getAvailableStockForSeller, getUserContext, getSellerAppUserId, searchProducts, _inFlight, Sentry
(function() {
  'use strict';
  const {useState, useEffect, useRef, useMemo} = React;

  // [Wave 24 v224.5 + v224.55 2026-05-28] vars+check MOVED to component body (preventivo)
  // regra_validacao_helpers_runtime_quando_ordem_scripts_uncertain

  // SecHead local (usada 3-4× inline aqui também) · não usa GOLD/NAVY → safe IIFE-level
  function SecHead({icon, title}){
    return (
      <div style={{padding:'13px 20px',borderBottom:'1px solid #F0F2F5',display:'flex',alignItems:'center',gap:8}}>
        <span style={{fontSize:14}}>{icon}</span>
        <span style={{fontSize:10,fontWeight:800,color:'#6B7280',letterSpacing:1.5,textTransform:'uppercase'}}>{title}</span>
      </div>
    );
  }

function NovaVendaPage({user,products,clients,quotes,setQuotes,vendedores,sales,setSales,setProducts,setReceivables,discountRequests,setDiscountRequests,onClose}){
  // [v224.55 FIX-PREV-5 2026-05-28] vars+check em render time
  // regra_estender_bloco_refs_fail_loud — 1 bloco agregado
  const calcs = window.ZNX && window.ZNX.novavenda && window.ZNX.novavenda.calcs;
  const ExitConfirmModal = window.ZNX && window.ZNX.widgets && window.ZNX.widgets.ExitConfirmModal;
  const nvW = (window.ZNX && window.ZNX.widgets && window.ZNX.widgets.novavenda) || {};
  const BlockedClientAlertW = window.ZNX && window.ZNX.widgets && window.ZNX.widgets.clientes && window.ZNX.widgets.clientes.BlockedClientAlert; // [v224.123]
  const _missing = [];
  if(!calcs) _missing.push('novavenda.calcs');
  if(!ExitConfirmModal) _missing.push('ExitConfirmModal');
  if(!nvW.ItemsListPanel) _missing.push('ItemsListPanel');
  if(!nvW.PaymentFretePanel) _missing.push('PaymentFretePanel');
  if(_missing.length){
    const _msg = '[NovaVendaPage v224.5] widgets faltando: ' + _missing.join(', ');
    console.error(_msg);
    if(window.Sentry && typeof window.Sentry.captureMessage === 'function'){
      window.Sentry.captureMessage(_msg, 'error');
    }
  }
  const GOLD = (calcs && calcs.GOLD) || '#B89840';
  const NAVY = (calcs && calcs.NAVY) || '#1B2A4A';
  const [search,setSearch] = useState('');
  const [form,setForm] = useState({clientId:'',clientName:'',items:[],date:today(),paymentStatus:'Pago',paymentMethod:'',sellerName:user.name,canal:'',obs:'',frete:'Retirada',embalagem:'',enderecoEntrega:{nome:'',cep:'',endereco:'',numero:'',complemento:'',bairro:'',cidade:'',estado:''},obsTransportadora:'',nfEnabled:false,notaFiscal:{numero:'',serie:'',chave:'',emissao:'',cnpj:'',obs:''},globalDiscountType:'',globalDiscountValue:0});
  const searchRef = useRef(null);
  const [clientSearch,setClientSearch] = useState('');
  const [showClientDrop,setShowClientDrop] = useState(false);
  const [productsLoading,setProductsLoading] = useState(true);
  const [pendingVndNum,setPendingVndNum] = useState(null);
  const [exitConfirmVnd,setExitConfirmVnd] = useState(false);
  const [blockedAlert,setBlockedAlert] = useState(null); // [v224.123 NUCLEAR] cliente bloqueado
  const [saving,setSaving] = useState(false);

  // Focus on mount
  useEffect(function(){setTimeout(function(){if(searchRef.current) searchRef.current.focus();},150);},[]);

  // BUG-S003 fix: hidrata products do relacional
  useEffect(function(){
    let cancelled = false;
    (async function(){
      await refreshProducts(setProducts);
      if(!cancelled) setProductsLoading(false);
    })();
    return function(){cancelled = true;};
  },[]);

  // [F5-02 v223.28] Reserva VND number on mount
  useEffect(function(){
    let cancelled = false;
    (async function(){
      try{
        if(!znxCounter || !znxCounter.reserveVNDAsync) return;
        const vnd = await znxCounter.reserveVNDAsync();
        if(!cancelled) setPendingVndNum(vnd);
      }catch(err){
        if(typeof Sentry !== 'undefined'){
          Sentry.captureMessage('[F5-02 v223.28] NovaVendaPage reserveVNDAsync fail',{level:'warning',extra:{err:String(err)}});
        }
      }
    })();
    return function(){cancelled = true;};
  },[]);

  function confirmExitVnd(){
    if(form.clientId || form.items.length > 0){setExitConfirmVnd(true);}
    else{onClose();}
  }

  // useMemo via calcs
  const filtered = useMemo(function(){return calcs.computeFiltered(products, search);},[products, search]);
  const visibleClients = useMemo(function(){return calcs.computeVisibleClients(user, clients, sales, quotes);},[clients, sales, quotes, user]);

  // isDecant + brandMeta via calcs (passar como prop pra ItemsListPanel)
  const isDecant = calcs && calcs.isDecant;
  const brandMeta = calcs && calcs.brandMeta;

  function addProduct(p){
    if(p.stock<=0 && !isDecant(p)){toast('"'+p.name+'" está zerado.'); return;}
    const existing = form.items.findIndex(function(i){return typeof nid==='function' ? nid(i.productId, p.id) : String(i.productId)===String(p.id);});
    if(existing >= 0){
      setForm(function(f){
        const items = f.items.map(function(it,idx){return idx===existing ? Object.assign({},it,{qty:it.qty+1}) : it;});
        return Object.assign({},f,{items:items});
      });
    } else {
      setForm(function(f){
        return Object.assign({},f,{items:[{productId:p.id, qty:1, price:p.salePrice||0, discountPct:0, name:p.name, brand:p.brand, volume:p.volume}].concat(f.items)});
      });
    }
    setTimeout(function(){const el=document.getElementById('znx-itens'); if(el) el.scrollIntoView({behavior:'smooth',block:'nearest'});},120);
  }

  async function removeItem(i){
    if(!await znxGuard(null)) return;
    setForm(function(f){return Object.assign({},f,{items:f.items.filter(function(_,idx){return idx!==i;})});});
  }
  function changeQty(i, delta){
    setForm(function(f){
      const items = f.items.map(function(it,idx){return idx===i ? Object.assign({},it,{qty:Math.max(1,it.qty+delta)}) : it;});
      return Object.assign({},f,{items:items});
    });
  }

  // Calcs inline via factories
  const subtotal = calcs.computeSubtotal(form.items);
  const totalDiscount = calcs.computeTotalDiscount(form.items);
  const afterItemDiscount = calcs.computeAfterItemDiscount(subtotal, totalDiscount);
  const globalDiscAmt = calcs.computeGlobalDiscAmt(afterItemDiscount, form.globalDiscountType, form.globalDiscountValue);
  const freteV = calcs.computeFreteValue(form.frete);
  const nfTax = calcs.computeNfTax(afterItemDiscount, globalDiscAmt, freteV, form.nfEnabled);
  const total = calcs.computeTotal(afterItemDiscount, globalDiscAmt, freteV, nfTax);
  const mistoOk = calcs.computeMistoOk(form, total);
  const canSubmit = calcs.computeCanSubmit(form, mistoOk);
  const totalQty = form.items.reduce(function(s,i){return s+i.qty;},0);
  const selectedClient = clients.find(function(c){return c.id===form.clientId;});

  // ──────────────────────────────────────────────────────────────────
  // handleSave LITERAL (L121-247 do original) — NÃO MUDAR atomicidade
  // ──────────────────────────────────────────────────────────────────
  async function handleSave(){
    if(_inFlight.has('sale-create')) return;
    _inFlight.add('sale-create');
    setSaving(true);
    try{
    if(productsLoading){toast('Aguarde — sincronizando estoque…'); return;}
    if(!form.clientId){toast('Selecione o cliente antes de criar a venda.'); return;}
    if(form.items.length===0){toast('Adicione pelo menos um produto.'); return;}
    if(!form.paymentMethod){toast('Selecione a forma de pagamento (Pix, Dinheiro ou Misto).'); return;}
    if(form.paymentMethod==='Misto'){
      const pix = Number(form.paymentPixValue||0);
      const cash = Number(form.paymentCashValue||0);
      if(pix<=0 || cash<=0){toast('Pagamento Misto exige valores Pix > 0 E Dinheiro > 0.'); return;}
      const sum = Number((pix+cash).toFixed(2));
      const tot = Number(total.toFixed(2));
      if(Math.abs(sum-tot)>=0.01){toast('Soma Pix('+fmt(pix)+') + Dinheiro('+fmt(cash)+') = '+fmt(sum)+' não bate com total '+fmt(tot)+'.'); return;}
    }
    if(form.frete==='Retirada' && !form.embalagem){toast('Selecione a embalagem (Sacola ou Caixa) para retirada presencial.'); return;}
    // [BUG-FRETE v212] Bloqueia salvar Sedex/PAC/Motoboy sem endereço de entrega
    if(['Sedex','PAC','Motoboy'].includes(form.frete)){
      const ee = form.enderecoEntrega || {};
      const cli = clients.find(function(c){return c.id===form.clientId;});
      const fallbackRua = ee.endereco || (cli && cli.address) || '';
      const fallbackCidade = ee.cidade || (cli && cli.city) || '';
      if(!fallbackRua || !fallbackCidade){
        toast('⚠️ Preencha endereço de entrega (rua + cidade) antes de salvar venda '+form.frete+'.','warning');
        if(typeof Sentry !== 'undefined') try{Sentry.captureMessage('[ZNX v212] save sale BLOCKED — frete='+form.frete+' sem endereço',{level:'warning',extra:{clientId:form.clientId, clientName: cli && cli.name, hasEE:!!ee.endereco, hasClientAddr: !!(cli && cli.address)}});}catch(_){}
        return;
      }
    }
    // [v224.42 ENTREGA TRANSPORTADORA] Bloqueia save sem data+hora entrega · spec Jamal obrigatório
    if(form.frete === 'Transportadora'){
      const ee = form.enderecoEntrega || {};
      if(!ee.delivery_date || !ee.delivery_time){
        toast('⚠️ Para Transportadora · preencha data E horário da entrega antes de salvar','error');
        if(typeof Sentry !== 'undefined') try{Sentry.captureMessage('[v224.42 ENTREGA] save sale BLOCKED — Transportadora sem data/hora',{level:'warning',extra:{clientId:form.clientId, hasDate:!!ee.delivery_date, hasTime:!!ee.delivery_time}});}catch(_){}
        return;
      }
    }
    const hasDiscount = form.items.some(function(it){return (it.discountPct||0)>0;}) || (form.globalDiscountValue||0)>0;
    const hasPriceBelow = form.items.some(function(it){
      const cat = products.find(function(p){return typeof nid==='function' ? nid(p.id, it.productId) : String(p.id)===String(it.productId);});
      return cat && Number(it.price)<Number(cat.salePrice);
    });
    if(user.role==='vendedor' && (hasDiscount || hasPriceBelow)){
      const client = clients.find(function(c){return c.id===form.clientId;});
      const totalDesc = totalDiscount + globalDiscAmt + (hasPriceBelow ? form.items.reduce(function(s,it){
        const cat = products.find(function(p){return typeof nid==='function' ? nid(p.id, it.productId) : String(p.id)===String(it.productId);});
        return s + (cat && Number(it.price)<Number(cat.salePrice) ? it.qty*(Number(cat.salePrice)-Number(it.price)) : 0);
      },0) : 0);
      const drIdNV = genIdUUID();
      const drResultNV = await createDiscountRequestAtomic({
        id: drIdNV,
        requested_by: user.name,
        client_id: form.clientId || null,
        client_name: (client && client.name) || '—',
        is_orcamento: false,
        is_edit: false,
        has_price_below: hasPriceBelow,
        total_liquido: total,
        total_desconto: totalDesc,
        global_discount_type: form.globalDiscountType || null,
        global_discount_value: Number(form.globalDiscountValue||0),
        form_data: Object.assign({},form,{clientId:form.clientId, globalDiscountType:form.globalDiscountType, globalDiscountValue:form.globalDiscountValue}),
        items: form.items
      });
      if(!drResultNV.success){
        toast('❌ Erro ao enviar pedido: '+(drResultNV.errorMessage||'tente novamente'));
        return;
      }
      onClose();
      toast(hasPriceBelow ? '⚠️ Preço abaixo do catálogo detectado. Enviado para aprovação do administrador.' : '✅ Venda enviada para aprovação do admin.');
      return;
    }
    // === PR-13: chamada atômica via create_sale_transaction ===
    let result = await createSaleAtomic({form, clients, paymentStatus:form.paymentStatus, freteV, pendingVndNum, forceCreate:false, znxCounter, sales, quotes, kind:'direct_sale'});
    if(!result.success && result.errorCode==='client_has_overdue_debt'){
      const forceConfirmed = await confirmForceCreateForOverdueClient(result.errorMessage);
      if(forceConfirmed){
        result = await createSaleAtomic({form, clients, paymentStatus:form.paymentStatus, freteV, pendingVndNum, forceCreate:true, znxCounter, sales, quotes, kind:'direct_sale'});
      } else {
        toast('Venda cancelada.');
        return;
      }
    }
    // [RG7 ONDA-N3 v218.17] Resultado QUEUED
    if(result.success && result.queued){
      console.log('[ZNX] handleSave QUEUED offline:', result.offlineQueueId);
      if(typeof Sentry !== 'undefined') Sentry.addBreadcrumb({category:'offline-queue', message:'sale queued offline', level:'info', data:{queueId:result.offlineQueueId, idemKey:result.idempotencyKey, clientId:form.clientId, items:(form.items||[]).length}});
      toast('💾 Venda salva offline — vai sincronizar quando voltar a internet','warning');
      onClose();
      return;
    }
    if(!result.success){
      console.error('[ZNX] handleSave createSaleAtomic failed:', result);
      if(result.errorCode==='insufficient_stock'){
        refreshProducts(setProducts);
        toast('⚠️ Estoque atualizado. Verifique as quantidades e tente novamente.');
      } else {
        toast('❌ '+mapErrorToUX(result.errorCode, result.errorMessage));
      }
      if(typeof window.znxCaptureRpcError === 'function'){
        window.znxCaptureRpcError('NovaVenda handleSave', result.errorCode||'failed', {errorCode:result.errorCode, clientId:form.clientId, items:(form.items||[]).length});
      } else if(typeof Sentry !== 'undefined'){
        Sentry.captureException(new Error(result.errorCode||'handleSave failed'), {extra:{errorCode:result.errorCode, clientId:form.clientId, items:(form.items||[]).length}});
      }
      return;
    }
    // [v224.116 2026-06-03] toast verde se replay confirmou venda mascarada por timeout edge
    if(result.replayConfirmed) toast('✅ Venda '+(result.saleNumber||'')+' salva · servidor demorou mas concluiu.','success');
    // Sync state local com banco
    const cliNV = clients.find(function(x){return x.id===form.clientId;});
    const ns = Object.assign({},form,{
      id: result.saleId, number: result.saleNumber,
      clientId: form.clientId, clientName: (cliNV && cliNV.name) || form.clientName || '',
      sellerName: form.sellerName || user.name,
      status: 'Aberto', paymentStatus: form.paymentStatus || 'Pendente',
      createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
      frete: form.frete, freteValor: freteV
    });
    setSales(function(prev){return prev.concat([ns]);});
    // DRIFT-Q2: hidratar ORC companion
    if(result.quoteId && result.quoteNumber && typeof setQuotes==='function'){
      const nq = {
        id: result.quoteId, number: result.quoteNumber,
        date: form.date, clientId: form.clientId,
        clientName: (cliNV && cliNV.name) || form.clientName || '',
        status: 'Convertido', items: form.items || [],
        total: result.saleTotal || 0,
        paymentMethod: form.paymentMethod || '',
        paymentStatus: form.paymentStatus || 'Pendente',
        sellerName: form.sellerName || user.name,
        canal: form.canal || '',
        saleId: result.saleId, saleNumber: result.saleNumber,
        createdAt: new Date().toISOString(), updatedAt: new Date().toISOString()
      };
      setQuotes(function(prev){return prev.concat([nq]);});
    }
    setProducts(function(prev){return prev.map(function(p){
      const it = result.items.find(function(i){return i.product_id===p.id;});
      return it ? Object.assign({},p,{stock:Math.max(0,(p.stock||0)-it.qty)}) : p;
    });});
    if(result.receivableStatus==='Pendente'){
      setReceivables(function(prev){return prev.concat([{
        id: result.recId,
        description: result.saleNumber+' — '+((cliNV && cliNV.name) || ''),
        clientId: form.clientId, value: total,
        due: result.receivableDue, status: 'Pendente',
        saleId: result.saleId
      }]);});
    }
    toast('✅ Venda criada com sucesso');
    onClose();
    } finally {
      _inFlight.delete('sale-create');
      setSaving(false);
    }
  }

  // ── RENDER ────────────────────────────────────────────────────
  return (
    <div style={{position:'fixed',inset:0,zIndex:2000,background:'#F0F2F5',overflowY:'auto',fontFamily:"'Plus Jakarta Sans',sans-serif"}}>
      <div style={{maxWidth:920,margin:'0 auto',padding:'28px 20px 48px'}}>

        {/* PAGE HEADER */}
        <div style={{display:'flex',justifyContent:'space-between',alignItems:'flex-start',marginBottom:24}}>
          <div>
            <div style={{display:'flex',alignItems:'baseline',gap:0,flexWrap:'wrap'}}>
              <span style={{fontSize:26,fontWeight:900,color:GOLD,letterSpacing:1,lineHeight:1.2}}>ZAYNEX</span>
              <span style={{fontSize:26,fontWeight:700,color:NAVY,lineHeight:1.2}}>&nbsp;• {pendingVndNum}</span>
            </div>
            <div style={{fontSize:12,color:'#9CA3AF',marginTop:4,letterSpacing:0.2}}>Plataforma de vendas B2B para revendedores</div>
            <button onClick={confirmExitVnd} style={{marginTop:10,background:'none',border:'1px solid #D1D5DB',borderRadius:7,padding:'4px 13px',fontSize:11,color:'#6B7280',cursor:'pointer',fontWeight:600,letterSpacing:0.3}}>← Voltar</button>
          </div>
          <div style={{textAlign:'right',flexShrink:0}}>
            <div style={{fontSize:11,color:'#9CA3AF',fontWeight:500,letterSpacing:0.3}}>Total do pedido</div>
            <div style={{fontSize:30,fontWeight:900,color:GOLD,lineHeight:1.1,marginTop:2}}>{fmt(total)}</div>
            <div style={{fontSize:11,color:'#9CA3AF',marginTop:3}}>{today()}</div>
          </div>
        </div>

        {/* PAGAMENTO CONFIRMAÇÃO */}
        <div style={{background:'#F0FDF4',borderRadius:10,border:'1.5px solid #16A34A',marginBottom:14,padding:'12px 20px',display:'flex',alignItems:'center',gap:10}}>
          <span style={{fontSize:18}}>✅</span>
          <div>
            <div style={{fontWeight:800,fontSize:13,color:'#15803D'}}>Pagamento confirmado</div>
            <div style={{fontSize:11,color:'#4ADE80',marginTop:1}}>Se o pagamento não foi confirmado, use Orçamentos</div>
          </div>
        </div>

        {/* CLIENTE */}
        <div style={{background:'#fff',borderRadius:10,border:'1px solid #E4E7EC',marginBottom:14,overflow:'visible'}}>
          <SecHead icon="🏢" title="Cliente"/>
          <div style={{padding:'16px 20px'}}>
            <div style={{position:'relative'}}>
              <input value={clientSearch}
                onChange={function(e){setClientSearch(e.target.value); setShowClientDrop(true); if(!e.target.value){setForm(function(f){return Object.assign({},f,{clientId:'', clientName:''});});}}}
                onFocus={function(){setShowClientDrop(true);}}
                onBlur={function(){setTimeout(function(){setShowClientDrop(false);},150);}}
                placeholder="Buscar cliente pelo nome..."
                style={{width:'100%',padding:'10px 14px',paddingLeft:36,borderRadius:8,border:'1.5px solid '+(form.clientId?NAVY:'#D1D5DB'),fontSize:13,color:NAVY,outline:'none',fontFamily:"'Plus Jakarta Sans',sans-serif",fontWeight:form.clientId?600:400,background:'#fff',boxSizing:'border-box'}}
                autoComplete="off"/>
              <span style={{position:'absolute',left:12,top:'50%',transform:'translateY(-50%)',fontSize:14,color:'#9CA3AF',pointerEvents:'none'}}>🔍</span>
              {form.clientId && <span style={{position:'absolute',right:12,top:'50%',transform:'translateY(-50%)',fontSize:11,color:'#16A34A',fontWeight:700,pointerEvents:'none'}}>✓</span>}
              {showClientDrop && (
                <div style={{position:'absolute',top:'calc(100% + 4px)',left:0,right:0,background:'#fff',border:'1.5px solid '+NAVY+'44',borderRadius:8,maxHeight:220,overflowY:'auto',zIndex:300,boxShadow:'0 8px 24px rgba(0,0,0,0.12)'}}>
                  {visibleClients.filter(function(c){return !clientSearch || c.name.toLowerCase().includes(clientSearch.toLowerCase());}).map(function(c){
                    return (
                      <div key={c.id}
                        onMouseDown={function(){
                          if(window.znxIsClientBlocked&&window.znxIsClientBlocked(c)){setShowClientDrop(false);setBlockedAlert(c);return;}
                          setClientSearch(c.name);
                          setForm(function(f){return Object.assign({},f,{clientId:c.id, clientName:c.name, enderecoEntrega:{nome:c.name||'', cep:c.cep||'', endereco:c.address||'', numero:'', complemento:'', bairro:c.neighborhood||'', cidade:c.city||'', estado:c.state||''}});});
                          setShowClientDrop(false);
                        }}
                        style={{padding:'10px 16px',cursor:'pointer',borderBottom:'1px solid #F3F4F6',display:'flex',justifyContent:'space-between',alignItems:'center'}}
                        onMouseEnter={function(e){e.currentTarget.style.background='#F8F9FB';}}
                        onMouseLeave={function(e){e.currentTarget.style.background='transparent';}}>
                        <div>
                          <div style={{fontSize:13,fontWeight:600,color:NAVY}}>{window.znxIsClientBlocked&&window.znxIsClientBlocked(c)&&<span title="Cliente bloqueado" style={{marginRight:5}}>🚫</span>}{c.name}</div>
                          {(c.phone || c.whatsapp || c.city) && <div style={{fontSize:11,color:'#9CA3AF',marginTop:1}}>{[c.phone||c.whatsapp, (c.city && c.state ? c.city+'/'+c.state : c.city||c.state)].filter(Boolean).join(' · ')}</div>}
                        </div>
                        <span style={{fontSize:10,padding:'2px 6px',borderRadius:4,background:c.type==='PJ'?'#DBEAFE':'#F3F4F6',color:c.type==='PJ'?'#1E40AF':'#6B7280',fontWeight:700}}>{c.type}</span>
                      </div>
                    );
                  })}
                  {visibleClients.filter(function(c){return !clientSearch || c.name.toLowerCase().includes(clientSearch.toLowerCase());}).length===0 && (
                    <div style={{padding:'14px',textAlign:'center',color:'#9CA3AF',fontSize:13}}>
                      Nenhum cliente {user && user.role==='vendedor' ? 'na sua carteira' : ''}.
                      {user && user.role==='vendedor' && <div style={{fontSize:11,marginTop:6,color:'#7C3AED'}}>Clique "+ Novo Cliente" pra cadastrar.</div>}
                    </div>
                  )}
                </div>
              )}
            </div>
            {selectedClient && Number(selectedClient.creditBalance || selectedClient.credit_balance || 0) > 0 && (function(){
              const credit = Number(selectedClient.creditBalance || selectedClient.credit_balance || 0);
              const baseTotal = (form.items||[]).reduce(function(s,it){return s + (Number(it.qty)*Number(it.price)*(1-(Number(it.discountPct)||0)/100));},0);
              const willApply = Math.min(credit, baseTotal);
              return (
                <div style={{marginTop:12,background:'#ECFDF5',border:'1px solid #10B98166',borderRadius:8,padding:'10px 14px',display:'flex',justifyContent:'space-between',alignItems:'center',fontSize:13}}>
                  <span style={{color:'#065F46'}}>💰 <strong>Cliente tem {fmt(credit)} de crédito.</strong> Será abatido ao gerar venda.</span>
                  {baseTotal>0 && <span style={{color:'#059669',fontWeight:700}}>Aplicará: {fmt(willApply)}</span>}
                </div>
              );
            })()}
            {selectedClient && (
              <div style={{marginTop:12,background:'#F8F9FB',borderRadius:8,padding:'12px 16px',display:'grid',gridTemplateColumns:'1fr 1fr',gap:10}}>
                {selectedClient.phone && <div><div style={{fontSize:10,color:'#9CA3AF',fontWeight:600,marginBottom:2}}>Telefone</div><div style={{fontSize:13,fontWeight:700,color:NAVY}}>{selectedClient.phone}</div></div>}
                {selectedClient.email && <div><div style={{fontSize:10,color:'#9CA3AF',fontWeight:600,marginBottom:2}}>Email</div><div style={{fontSize:13,fontWeight:600,color:'#374151'}}>{selectedClient.email}</div></div>}
                {selectedClient.city && <div><div style={{fontSize:10,color:'#9CA3AF',fontWeight:600,marginBottom:2}}>Cidade</div><div style={{fontSize:13,fontWeight:600,color:'#374151'}}>{selectedClient.city}</div></div>}
                {selectedClient.contact && <div><div style={{fontSize:10,color:'#9CA3AF',fontWeight:600,marginBottom:2}}>Contato</div><div style={{fontSize:13,fontWeight:600,color:'#374151'}}>{selectedClient.contact}</div></div>}
              </div>
            )}
          </div>
        </div>

        {/* ITEMS LIST PANEL (busca + tabela + desconto global + pricing) */}
        {nvW.ItemsListPanel && (
          <nvW.ItemsListPanel
            form={form} setForm={setForm}
            search={search} setSearch={setSearch}
            filtered={filtered} searchRef={searchRef}
            productsLoading={productsLoading}
            products={products} quotes={quotes} user={user}
            addProduct={addProduct} removeItem={removeItem}
            subtotal={subtotal} totalDiscount={totalDiscount}
            globalDiscAmt={globalDiscAmt} freteV={freteV} nfTax={nfTax} total={total}
            isDecant={isDecant} brandMeta={brandMeta}/>
        )}

        {/* PAYMENT FRETE PANEL (frete + NF + pagamento) */}
        {nvW.PaymentFretePanel && (
          <nvW.PaymentFretePanel
            form={form} setForm={setForm} total={total}
            FRETE_OPTS={calcs.FRETE_OPTS} nfTax={nfTax}/>
        )}

        {/* OBSERVAÇÕES */}
        <div style={{background:'#fff',borderRadius:10,border:'1px solid #E4E7EC',marginBottom:24,overflow:'hidden'}}>
          <SecHead icon="💬" title="Observações"/>
          <div style={{padding:'14px 20px'}}>
            <textarea value={form.obs||''} onChange={function(e){setForm(function(f){return Object.assign({},f,{obs:e.target.value});});}}
              placeholder="Digite observações do pedido..."
              rows={3}
              style={{width:'100%',padding:'10px 14px',borderRadius:8,border:'1.5px solid #D1D5DB',fontSize:13,color:'#374151',outline:'none',resize:'vertical',fontFamily:"'Plus Jakarta Sans',sans-serif",boxSizing:'border-box',lineHeight:1.5,background:'#FAFAFA'}}
              onFocus={function(e){e.target.style.borderColor=NAVY; e.target.style.background='#fff';}}
              onBlur={function(e){e.target.style.borderColor='#D1D5DB'; e.target.style.background='#FAFAFA';}}/>
          </div>
        </div>

        {/* CRIAR VENDA */}
        <button onClick={handleSave} disabled={!canSubmit || saving}
          style={{width:'100%',padding:'16px',background:(canSubmit && !saving)?NAVY:'#F3F4F6',border:'none',borderRadius:12,color:(canSubmit && !saving)?GOLD:'#9CA3AF',fontWeight:900,fontSize:15,cursor:(canSubmit && !saving)?'pointer':'not-allowed',letterSpacing:0.5,transition:'all .15s',boxShadow:(canSubmit && !saving)?'0 4px 20px rgba(27,42,74,.2)':'none'}}>
          {saving ? 'Salvando...' : !form.clientId ? 'Selecione o cliente primeiro' : form.items.length===0 ? 'Adicione produtos ao pedido' : '✓ CRIAR VENDA  —  '+fmt(total)}
        </button>
      </div>

      {/* [v224.123 NUCLEAR] popup cliente bloqueado */}
      {blockedAlert && BlockedClientAlertW && (
        <BlockedClientAlertW client={blockedAlert} onClose={function(){setBlockedAlert(null);}}/>
      )}
      {/* EXIT MODAL */}
      {ExitConfirmModal && (
        <ExitConfirmModal
          open={exitConfirmVnd}
          title="Sair da venda?"
          message={<>Dados não salvos. O número <strong>{pendingVndNum}</strong> será perdido.</>}
          onCancel={function(){setExitConfirmVnd(false);}}
          onConfirm={onClose}/>
      )}
    </div>
  );
}

  window.ZNX = window.ZNX || {};
  window.ZNX.components = window.ZNX.components || {};
  window.ZNX.components.NovaVendaPage = NovaVendaPage;
  window.NovaVendaPage = NovaVendaPage;
  window.ZNX.refactor_phase_6_loaded = window.ZNX.refactor_phase_6_loaded || {};
  window.ZNX.refactor_phase_6_loaded.NovaVendaPage = true;
  // [Wave 24 marker v224.5] confirma extract executado
  window.NovaVendaPage_v224_5_wave24 = true;
})();
