let CSRF='', currentView='dashboard', REPORT_OPTIONS={columns:{}}, PRESET_CACHE=[], ACTIVE_SMART='', ORDERS_PAGE=1;
const $=s=>document.querySelector(s); const $$=s=>[...document.querySelectorAll(s)];
const fmt=v=>'R$ '+Number(v||0).toLocaleString('pt-BR',{minimumFractionDigits:2});
const esc=v=>String(v??'').replace(/[&<>'"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;',"'":'&#39;','"':'&quot;'}[c]));
const api=async(action, opts={})=>{const r=await fetch('api.php?action='+action,opts); const j=await r.json(); if(!j.ok) throw new Error(j.message||'Erro'); return j;};
function params(extra={}){const p=new URLSearchParams(); ['from','to','status','product','q'].forEach(id=>{const v=$('#'+id)?.value?.trim(); if(v)p.set(id,v)}); if(ACTIVE_SMART)p.set('smart',ACTIVE_SMART); Object.entries(extra).forEach(([k,v])=>{if(v!==undefined&&v!==null&&v!=='')p.set(k,v)}); return p.toString();}
async function boot(){try{const s=await api('session'); CSRF=s.csrf; if(s.user) showPanel(s); else showLogin();}catch(e){showLogin();}}
function showLogin(){$('#login').classList.remove('hidden');$('#panel').classList.add('hidden')}
async function showPanel(s){$('#login').classList.add('hidden');$('#panel').classList.remove('hidden');$('#storeName').textContent=s.config?.store||'Cartório'; await loadOptions(); initTouchSuggest(); loadDashboard();}
async function loadOptions(){try{const j=await api('report_options'); REPORT_OPTIONS=j.data||{}; fillList('statusList',REPORT_OPTIONS.statuses); fillList('productList',REPORT_OPTIONS.products); fillList('shippingList',REPORT_OPTIONS.shipping); fillList('cityList',REPORT_OPTIONS.cities); fillList('stateList',REPORT_OPTIONS.states); fillList('certTypeList',REPORT_OPTIONS.cert_types); fillList('modeList',REPORT_OPTIONS.modes); fillList('metaKeyList',REPORT_OPTIONS.meta_keys);}catch(e){}}
function fillList(id,rows){const el=$('#'+id); if(!el)return; el.innerHTML=(rows||[]).map(r=>`<option value="${esc(r.value)}"></option>`).join('');}
$('#loginForm').addEventListener('submit',async e=>{e.preventDefault();try{const data=Object.fromEntries(new FormData(e.target));const j=await api('login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(data)});CSRF=j.csrf;showPanel({user:j.user,config:{}})}catch(err){alert(err.message)}});
$('#logoutBtn').onclick=async()=>{await api('logout');location.reload()}; $$('[data-view]').forEach(b=>b.onclick=()=>setView(b.dataset.view)); $('#applyFilters').onclick=()=>{ORDERS_PAGE=1;loadCurrent()}; $('#menuBtn').onclick=()=>$('.sidebar').classList.toggle('open');
function setView(v){currentView=v; $$('[data-view]').forEach(b=>b.classList.toggle('active',b.dataset.view===v)); $$('.view').forEach(el=>el.classList.add('hidden')); $('#view-'+v).classList.remove('hidden'); $('#pageTitle').textContent={dashboard:'Dashboard',cartorio:'Cartório inteligente',orders:'Pedidos',reports:'Relatórios',import:'Importar XML'}[v]; $('#pageSub').textContent={dashboard:'Resumo geral financeiro e operacional',cartorio:'Inteligência pré-processada, cards sob demanda e conferência operacional paginada',orders:'Consulta paginada dos pedidos importados',reports:'Construtor e exportações personalizadas',import:'Importação de XML WooCommerce'}[v]; loadCurrent(); if(innerWidth<980)$('.sidebar').classList.remove('open')}
function loadCurrent(){ if(currentView==='dashboard')loadDashboard(); if(currentView==='cartorio')loadCartorio(); if(currentView==='orders')loadOrders(); if(currentView==='reports')loadReports(); if(currentView==='import')loadImport(); }
async function loadDashboard(){const j=await api('dashboard&'+params()); const d=j.data,k=d.kpi; $('#view-dashboard').innerHTML=`<div class="kpis"><div class="card kpi"><span>Pedidos</span><strong>${k.orders_count}</strong></div><div class="card kpi"><span>Total</span><strong>${fmt(k.total)}</strong></div><div class="card kpi"><span>Frete</span><strong>${fmt(k.shipping)}</strong></div><div class="card kpi"><span>Ticket médio</span><strong>${fmt(k.avg_ticket)}</strong></div></div><div class="grid"><div class="card"><h3>Por status</h3>${simpleTable(d.by_status)}</div><div class="card"><h3>Produtos</h3>${simpleTable(d.by_product)}</div><div class="card"><h3>Entrega</h3>${simpleTable(d.by_shipping)}</div><div class="card"><h3>Últimos dias</h3>${simpleTable(d.daily)}</div></div>`;}
function smartCards(rows,clickable=true){return `<div class="smart-cards">${(rows||[]).map(r=>`<button class="smart-card ${ACTIVE_SMART===r.key?'active':''}" ${clickable?`onclick="setSmart('${esc(r.key)}')"`:''}><span>${esc(r.label)}</span><strong>${r.qty}</strong><small>${fmt(r.total)}</small><em>${esc(r.hint)}</em></button>`).join('')}</div>`}
function setSmart(key){ACTIVE_SMART = ACTIVE_SMART===key ? '' : key; ORDERS_PAGE=1; loadCurrent();}
function simpleTable(rows){return `<div class="table-wrap"><table class="table"><tr><th>Item</th><th>Qtd.</th><th>Total</th></tr>${(rows||[]).map(r=>`<tr><td>${esc(r.label)}</td><td>${r.qty}</td><td>${fmt(r.total)}</td></tr>`).join('')}</table></div>`}
async function loadCartorio(){const status=(await api('intelligence_status')).data; $('#view-cartorio').innerHTML=`<div class="section-title"><div><h2>Relatórios cartorários inteligentes</h2><p>A inteligência é pré-processada para manter o sistema estável mesmo com base grande.</p></div>${ACTIVE_SMART?`<button class="ghost" onclick="setSmart('${ACTIVE_SMART}')">Limpar card</button>`:''}</div><div class="card progress-card"><div><b>Inteligência processada</b><p class="muted">${status.ready} de ${status.total} pedidos prontos • ${status.pending} pendente(s)</p></div><div class="actions"><button onclick="loadSmartArea()">Carregar cards inteligentes</button><button class="ghost" onclick="reprocessIntelligence()">Reprocessar inteligência</button></div></div><div id="smartArea"></div><div id="opsArea"></div>`;}
async function loadSmartArea(extra={}){const q=params(extra); const cards=(await api('smart_cards&'+q)).data||[]; const rows=(await api('operational_rows&'+q+'&limit=80')).data||[]; $('#smartArea').innerHTML=`${smartCards(cards,true)}<div class="ops-grid"><div class="card"><h3>Filtros rápidos</h3><div class="builder-grid mini"><label>Entrega<input id="quickShipping" class="smart-input" list="shippingList" data-options="shipping" placeholder="Sedex, Retirar..."></label><label>Cidade<input id="quickCity" class="smart-input" list="cityList" data-options="cities" placeholder="Rio de Janeiro..."></label><label>UF<input id="quickState" class="smart-input" list="stateList" data-options="states" placeholder="RJ, SP..."></label></div><div class="actions"><button onclick="applyQuickFilters()">Aplicar filtros rápidos</button><button class="ghost" onclick="clearQuickFilters()">Limpar</button></div></div><div class="card"><h3>Exportação operacional</h3><p class="muted">Exporta a visão filtrada com os totais destacados.</p><div class="actions"><button onclick="window.open('api.php?action=export_html&${params({columns:'pedido,data,status,cliente,produto,tipo_certidao,modalidade,entrega,frete,total,pendencias'})}')">PDF / impressão</button><button onclick="location.href='api.php?action=export_csv&${params({columns:'pedido,data,status,cliente,produto,tipo_certidao,modalidade,entrega,frete,total,pendencias'})}'">CSV</button></div></div></div>`; $('#opsArea').innerHTML=`<div class="card"><h3>Conferência operacional</h3><p class="muted">Pendências pré-processadas, sem varrer metadados em tempo real.</p>${operationalTable(rows)}</div>`; initTouchSuggest();}
async function reprocessIntelligence(){try{const j=await api('intelligence_reprocess&limit=250',{method:'POST',headers:{'X-CSRF-Token':CSRF}}); alert(`Processados: ${j.data.processed}. Restantes: ${j.data.remaining}.`); loadCartorio();}catch(e){alert(e.message)}}
function applyQuickFilters(){loadSmartArea({shipping:$('#quickShipping')?.value||'',city:$('#quickCity')?.value||'',state:$('#quickState')?.value||''})}
function clearQuickFilters(){['quickShipping','quickCity','quickState'].forEach(id=>{const el=$('#'+id); if(el)el.value=''}); loadSmartArea()}
function operationalTable(rows){return `<div class="table-wrap"><table class="table table-hover"><tr><th>Pedido</th><th>Data</th><th>Cliente</th><th>Produto</th><th>Tipo</th><th>Entrega</th><th>Pendências</th></tr>${(rows||[]).map(r=>`<tr onclick="openOrder(${r.id})"><td>${esc(r.pedido)}</td><td>${esc(r.data)}</td><td>${esc(r.cliente)}</td><td>${esc(r.produto)}</td><td>${esc(r.tipo_certidao)}</td><td>${esc(r.entrega)}</td><td><span class="warn-text">${esc(r.pendencias)}</span></td></tr>`).join('')||'<tr><td colspan="7">Nenhuma pendência encontrada nos filtros atuais.</td></tr>'}</table></div>`;}
async function loadOrders(){const j=await api('orders&'+params({page:ORDERS_PAGE,limit:50})); const pack=j.data, rows=pack.rows||[]; const pages=Math.max(1,Math.ceil(pack.total/pack.limit)); $('#view-orders').innerHTML=`<div class="actions card"><button onclick="window.open('api.php?action=export_html&${params()}')">PDF / impressão</button><button onclick="location.href='api.php?action=export_csv&${params()}'">CSV</button><button onclick="setView('reports')">Construtor</button>${ACTIVE_SMART?`<button class="ghost" onclick="setSmart('${ACTIVE_SMART}')">Limpar card inteligente</button>`:''}<span class="muted">Página ${pack.page} de ${pages} • ${pack.total} pedido(s)</span><button class="ghost" onclick="ordersPage(-1)" ${pack.page<=1?'disabled':''}>Anterior</button><button class="ghost" onclick="ordersPage(1)" ${pack.page>=pages?'disabled':''}>Próxima</button></div><br><div class="card table-wrap"><table class="table table-hover"><tr><th>Pedido</th><th>Data</th><th>Status</th><th>Cliente</th><th>Cidade/UF</th><th>Entrega</th><th>Total</th></tr>${rows.map(r=>`<tr onclick="openOrder(${r.id})"><td>${esc(r.order_number_formatted||r.woo_order_id)}</td><td>${esc(r.order_date)}</td><td><span class="pill ${esc(r.status)}">${esc(r.status)}</span></td><td>${esc(r.billing_name)}</td><td>${esc((r.billing_city||'')+'/'+(r.billing_state||''))}</td><td>${esc(r.shipping_method)}</td><td>${fmt(r.order_total)}</td></tr>`).join('')}</table></div>`;}
function ordersPage(step){ORDERS_PAGE=Math.max(1,ORDERS_PAGE+step); loadOrders();}
async function openOrder(id){const j=await api('order&id='+id); const d=j.data,o=d.order; const html=`<div class="drawer" onclick="this.remove()"><div class="drawer-card" onclick="event.stopPropagation()"><button class="ghost right" onclick="document.querySelector('.drawer').remove()">Fechar</button><h2>Pedido ${esc(o.order_number_formatted||o.woo_order_id)}</h2><p><b>${esc(o.billing_name)}</b> • ${esc(o.billing_email)} • ${esc(o.billing_phone)}</p><p>Status: <span class="pill ${esc(o.status)}">${esc(o.status)}</span> • Total: <b>${fmt(o.order_total)}</b> • Frete: ${fmt(o.shipping_total)}</p><p class="muted">Inteligência: ${esc(o.certificate_category||'')} ${o.pending_flags?`• Pendências: ${esc(o.pending_flags)}`:''}</p><h3>Itens</h3>${d.items.map(it=>`<div class="card soft"><b>${esc(it.name)}</b> — ${fmt(it.total)}<div class="meta-grid">${(it.meta||[]).map(m=>`<b>${esc(m.meta_key)}</b><span>${linkify(esc(m.meta_value))}</span>`).join('')}</div></div><br>`).join('')}<h3>Notas</h3>${(d.notes||[]).map(n=>`<p><b>${esc(n.note_date)}</b> ${esc(n.content)}</p>`).join('')||'<p class="muted">Sem notas.</p>'}</div></div>`; document.body.insertAdjacentHTML('beforeend',html);}
function loadReports(){ $('#view-reports').innerHTML=`<div class="reports-layout"><div class="card report-builder"><div class="section-title"><div><h2>Construtor de relatório</h2><p>Monte colunas, filtros operacionais e exporte com totais destacados.</p></div><button class="ghost" onclick="loadPresets()">Atualizar modelos</button></div><div class="builder-grid"><label>Título do relatório<input id="reportTitle" value="Relatório de Pedidos"></label><label>Tipo certidão<input id="certType" class="smart-input" list="certTypeList" data-options="cert_types" placeholder="Nascimento, Casamento, Óbito..."></label><label>Modalidade<input id="mode" class="smart-input" list="modeList" data-options="modes" placeholder="Breve Relato, Inteiro Teor..."></label><label><span>Anexos</span><select id="hasAttachment"><option value="">Todos</option><option value="1">Somente com anexos</option><option value="0">Somente sem anexos</option></select></label><label>Meta chave<input id="metaKey" class="smart-input" list="metaKeyList" data-options="meta_keys" placeholder="Livro, Folha, Termo..."></label><label>Meta valor<input id="metaValue" placeholder="Valor do campo"></label></div><h3>Colunas</h3><div class="columns-box">${columnsCheckboxes()}</div><div class="actions"><button onclick="previewReport()">Visualizar</button><button onclick="exportReport('html')">PDF / impressão</button><button onclick="exportReport('docx')">DOCX</button><button onclick="exportReport('xls')">Excel</button><button onclick="exportReport('csv')">CSV</button><button class="ghost" onclick="savePreset()">Salvar modelo</button></div></div><div class="card presets"><h3>Modelos salvos</h3><div id="presetList" class="muted">Carregando...</div></div></div><div id="reportPreview" class="card hidden"></div>`; loadPresets(); initTouchSuggest(); }
function columnsCheckboxes(){const defaults=['pedido','data','status','cliente','produto','tipo_certidao','modalidade','entrega','frete','total','pendencias']; const cols=REPORT_OPTIONS.columns||{}; return Object.entries(cols).map(([k,v])=>`<label class="check"><input type="checkbox" value="${esc(k)}" ${defaults.includes(k)?'checked':''}>${esc(v)}</label>`).join('');}
function reportExtra(){return {title:$('#reportTitle')?.value||'Relatório de Pedidos',cert_type:$('#certType')?.value||'',mode:$('#mode')?.value||'',has_attachment:$('#hasAttachment')?.value||'',meta_key:$('#metaKey')?.value||'',meta_value:$('#metaValue')?.value||'',columns:selectedColumns(),limit:5000};}
function selectedColumns(){return [...document.querySelectorAll('.columns-box input:checked')].map(i=>i.value).join(',');}
async function previewReport(){const q=params(reportExtra()); const [rowsJ, totalsJ]=await Promise.all([api('report_rows&'+q+'&limit=80'),api('report_totals&'+q)]); const rows=rowsJ.data||[], totals=totalsJ.data||{}; const cols=selectedColumns().split(',').filter(Boolean); const labels=REPORT_OPTIONS.columns||{}; $('#reportPreview').classList.remove('hidden'); $('#reportPreview').innerHTML=`<div class="section-title"><div><h3>Prévia</h3><p>${rows.length} registro(s) exibidos na prévia.</p></div></div><div class="total-strip"><div><span>Pedidos / entrega</span><strong>${totals.pedidos||0}</strong></div><div><span>Total de frete</span><strong>${fmt(totals.frete)}</strong></div><div><span>Total geral</span><strong>${fmt(totals.total_geral)}</strong></div></div><div class="table-wrap"><table class="table"><tr>${cols.map(c=>`<th>${esc(labels[c]||c)}</th>`).join('')}</tr>${rows.map(r=>`<tr>${cols.map(c=>`<td>${esc(r[c]??'')}</td>`).join('')}</tr>`).join('')}</table></div>`;}
function exportReport(type){const q=params(reportExtra()); const map={html:'export_html',docx:'export_docx',xls:'export_xls',csv:'export_csv'}; const url='api.php?action='+map[type]+'&'+q; if(type==='html') window.open(url); else location.href=url;}
async function savePreset(){const name=prompt('Nome do modelo de relatório:'); if(!name)return; const payload={name,description:'Modelo criado no construtor',config:{filters:Object.fromEntries(new URLSearchParams(params(reportExtra()))),columns:selectedColumns()}}; try{await api('preset_save',{method:'POST',headers:{'Content-Type':'application/json','X-CSRF-Token':CSRF},body:JSON.stringify(payload)}); loadPresets();}catch(e){alert(e.message)}}
async function loadPresets(){try{const j=await api('presets'); PRESET_CACHE=j.data||[]; $('#presetList').innerHTML=PRESET_CACHE.length?PRESET_CACHE.map((p,idx)=>`<div class="preset-item"><b>${esc(p.name)}</b><small>${esc(p.description||'')}</small><button class="ghost" onclick="applyPreset(${idx})">Aplicar</button></div>`).join(''):'Nenhum modelo salvo ainda.';}catch(e){$('#presetList').textContent=e.message}}
function applyPreset(idx){try{const raw=PRESET_CACHE[idx]?.config_json||{}; const cfg=typeof raw==='string'?JSON.parse(raw):raw; const f=cfg.filters||{}; ['from','to','status','product','q'].forEach(k=>{if($('#'+k) && f[k]!==undefined) $('#'+k).value=f[k]}); if($('#certType')) $('#certType').value=f.cert_type||''; if($('#mode')) $('#mode').value=f.mode||''; if($('#hasAttachment')) $('#hasAttachment').value=f.has_attachment||''; if($('#metaKey')) $('#metaKey').value=f.meta_key||''; if($('#metaValue')) $('#metaValue').value=f.meta_value||''; document.querySelectorAll('.columns-box input').forEach(i=>i.checked=(cfg.columns||'').split(',').includes(i.value)); previewReport();}catch(e){alert('Não foi possível aplicar o modelo.')}}
async function loadImport(){const j=await api('imports'); $('#view-import').innerHTML=`<div class="card"><h2>Importar XML WooCommerce</h2><form id="importForm"><input type="file" name="xml" accept=".xml" required><button>Importar</button></form><p class="muted">Novas importações já atualizam a inteligência de cada pedido automaticamente.</p></div><br><div class="card"><h3>Últimas importações</h3>${simpleImport(j.data)}</div>`; $('#importForm').onsubmit=async e=>{e.preventDefault(); const fd=new FormData(e.target); try{const r=await fetch('api.php?action=import',{method:'POST',headers:{'X-CSRF-Token':CSRF},body:fd}); const data=await r.json(); if(!data.ok)throw new Error(data.message); alert('Importação concluída.'); loadImport(); loadDashboard();}catch(err){alert(err.message)}}}
function simpleImport(rows){return `<div class="table-wrap"><table class="table"><tr><th>Arquivo</th><th>Status</th><th>Início</th><th>Fim</th></tr>${(rows||[]).map(r=>`<tr><td>${esc(r.filename)}</td><td><span class="pill ${esc(r.status)}">${esc(r.status)}</span></td><td>${esc(r.started_at)}</td><td>${esc(r.finished_at||'')}</td></tr>`).join('')}</table></div>`}
function linkify(t){return t.replace(/(https?:\/\/[^\s<]+)/g,'<a href="$1" target="_blank" rel="noopener">arquivo</a>')}
function initTouchSuggest(){document.querySelectorAll('.smart-input').forEach(input=>{input.onfocus=()=>showSuggestions(input); input.onclick=()=>showSuggestions(input); input.ontouchstart=()=>showSuggestions(input); input.oninput=()=>showSuggestions(input);}); document.addEventListener('click',e=>{if(!e.target.closest('.touch-suggest')&&!e.target.classList.contains('smart-input')) $('#touchSuggest')?.classList.add('hidden')},{once:true});}
function optionRows(key){return (REPORT_OPTIONS[key]||[]).map(r=>r.value).filter(Boolean).slice(0,80)}
function showSuggestions(input){const box=$('#touchSuggest'); if(!box||innerWidth>980)return; const key=input.dataset.options; const term=(input.value||'').toLowerCase(); const rows=optionRows(key).filter(v=>!term||String(v).toLowerCase().includes(term)).slice(0,18); if(!rows.length){box.classList.add('hidden');return;} const rect=input.getBoundingClientRect(); box.style.top=(rect.bottom+scrollY+6)+'px'; box.style.left=(rect.left+scrollX)+'px'; box.style.width=rect.width+'px'; box.innerHTML=rows.map(v=>`<button type="button" data-v="${esc(v)}">${esc(v)}</button>`).join(''); box.classList.remove('hidden'); box.querySelectorAll('button').forEach(btn=>btn.onclick=()=>{input.value=btn.dataset.v; box.classList.add('hidden'); input.dispatchEvent(new Event('change'));});}
boot();
