<section class="panel" id="integration-camera" style="max-width:820px;margin-inline:auto">
  <div class="panel-header"><div><h3>📷 Ler QR Code de integração</h3><p>Leia convites de integração, empresa ou prestador diretamente pela Central de Integrações.</p></div></div>
  <div data-int-qr-camera-box style="position:relative;overflow:hidden;border:1px solid var(--border);border-radius:20px;background:#070812;min-height:270px;display:grid;place-items:center">
    <video data-int-qr-video playsinline muted style="width:100%;max-height:55vh;object-fit:cover;display:none"></video>
    <div data-int-qr-placeholder style="text-align:center;padding:38px 20px;color:var(--muted)"><div style="font-size:3.6rem;margin-bottom:10px">📷</div><strong style="display:block;color:var(--text);margin-bottom:7px">Câmera desligada</strong><span>Toque em “Acessar câmera” e aponte para o QR Code.</span></div>
    <div data-int-qr-guide hidden style="position:absolute;inset:16% 13%;border:3px solid var(--accent);border-radius:24px;box-shadow:0 0 0 9999px rgba(0,0,0,.2);pointer-events:none"></div>
  </div>
  <div class="actions" style="margin-top:15px"><button class="btn btn-primary" type="button" data-int-qr-start>📷 Acessar câmera</button><button class="btn btn-secondary" type="button" data-int-qr-stop disabled>■ Fechar câmera</button><label class="btn btn-secondary" style="cursor:pointer">📸 Ler de uma foto<input data-int-qr-file type="file" accept="image/*" capture="environment" hidden></label></div>
  <div class="notice" data-int-qr-status style="margin-top:15px"><strong>Status:</strong> câmera aguardando.</div>
  <div class="inline-filter" style="margin-top:15px"><input class="input" data-int-qr-manual placeholder="Cole aqui o link do convite"><button class="btn btn-secondary" type="button" data-int-qr-open-link>Abrir convite</button></div>
</section>
<script>
(function(){
 const video=document.querySelector('[data-int-qr-video]'),placeholder=document.querySelector('[data-int-qr-placeholder]'),guide=document.querySelector('[data-int-qr-guide]'),startBtn=document.querySelector('[data-int-qr-start]'),stopBtn=document.querySelector('[data-int-qr-stop]'),statusBox=document.querySelector('[data-int-qr-status]'),fileInput=document.querySelector('[data-int-qr-file]'),manual=document.querySelector('[data-int-qr-manual]'),openManual=document.querySelector('[data-int-qr-open-link]');
 let stream=null,detector=null,running=false,raf=0,lastInvalid='';
 function status(message,type){const icons={ok:'✅',error:'⚠️',scan:'🔎',info:'ℹ️'};statusBox.innerHTML='<strong>'+(icons[type]||'ℹ️')+' Status:</strong> '+message;}
 function validInvite(raw){raw=String(raw||'').trim();if(!raw)return null;let u;try{u=new URL(raw,window.location.href)}catch(e){return null;}if(u.origin!==window.location.origin)return null;const path=u.pathname.replace(/\/+$/,'');const allowed=['/integration_join.php','/company_join.php','/provider_join.php'];if(!allowed.some(p=>path.endsWith(p)))return null;if(!(u.searchParams.get('token')||'').trim())return null;if(path.endsWith('/integration_join.php')&&!/^\d+$/.test(u.searchParams.get('link_id')||''))return null;if(path.endsWith('/company_join.php')&&!/^\d+$/.test(u.searchParams.get('company_id')||''))return null;if(path.endsWith('/provider_join.php')&&!/^\d+$/.test(u.searchParams.get('provider_id')||''))return null;return u.href;}
 function go(raw){const url=validInvite(raw);if(!url){lastInvalid=String(raw||'');status('QR lido, mas ele não é um convite válido desta plataforma.','error');return false;}stop();status('Convite reconhecido. Liberando o acesso…','ok');setTimeout(()=>location.href=url,180);return true;}
 async function ensureDetector(){if(detector)return detector;if(!('BarcodeDetector' in window))throw new Error('Este navegador não possui leitor de QR integrado. Use um navegador atualizado ou a opção de foto.');detector=new BarcodeDetector({formats:['qr_code']});return detector;}
 async function scan(){if(!running)return;try{if(video.readyState>=2){const codes=await detector.detect(video);if(codes&&codes.length){const raw=(codes[0].rawValue||'').trim();if(raw&&raw!==lastInvalid&&go(raw))return;}}}catch(e){}if(running)raf=requestAnimationFrame(scan);}
 async function start(){if(running)return;if(!window.isSecureContext){status('A câmera exige HTTPS. Abra a plataforma com https://','error');return;}if(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia){status('Este navegador não disponibilizou acesso à câmera.','error');return;}try{status('solicitando permissão da câmera…','info');await ensureDetector();stream=await navigator.mediaDevices.getUserMedia({audio:false,video:{facingMode:{ideal:'environment'},width:{ideal:1280},height:{ideal:720}}});video.srcObject=stream;await video.play();running=true;video.style.display='block';placeholder.style.display='none';guide.hidden=false;startBtn.disabled=true;stopBtn.disabled=false;status('aponte para o QR Code.','scan');scan();}catch(e){status(e&&e.name==='NotAllowedError'?'Permissão da câmera negada.':(e.message||'Não foi possível acessar a câmera.'),'error');stop();}}
 function stop(){running=false;if(raf)cancelAnimationFrame(raf);raf=0;if(stream){stream.getTracks().forEach(t=>t.stop());stream=null;}video.pause();video.srcObject=null;video.style.display='none';placeholder.style.display='block';guide.hidden=true;startBtn.disabled=false;stopBtn.disabled=true;}
 async function scanFile(file){if(!file)return;try{status('analisando a foto…','scan');const d=await ensureDetector(),bitmap=await createImageBitmap(file),codes=await d.detect(bitmap);if(bitmap.close)bitmap.close();if(codes&&codes.length)go(codes[0].rawValue||'');else status('Nenhum QR Code foi encontrado nessa imagem.','error');}catch(e){status(e.message||'Não foi possível ler a imagem.','error');}finally{fileInput.value='';}}
 startBtn&&startBtn.addEventListener('click',start);stopBtn&&stopBtn.addEventListener('click',()=>{stop();status('câmera fechada.','info')});fileInput&&fileInput.addEventListener('change',()=>scanFile(fileInput.files&&fileInput.files[0]));openManual&&openManual.addEventListener('click',()=>{if(!go(manual.value))manual.focus()});manual&&manual.addEventListener('keydown',e=>{if(e.key==='Enter'){e.preventDefault();openManual.click();}});window.addEventListener('pagehide',stop);
})();
</script>
