<?php
declare(strict_types=1);

/**
 * Consulta publica da NFCe pelo QR Code.
 *
 * Reproduz a pagina que a SEFAZ abre quando o consumidor le o QR Code
 * do cupom. Nao exige certificado: e acesso publico.
 */

require dirname(__DIR__) . '/vendor/autoload.php';

use Sefaz\Chave;
use Sefaz\Db;
use Sefaz\QrCode;

header('Content-Type: text/html; charset=utf-8');

$p = $_GET['p'] ?? '';
$chaveManual = preg_replace('/\D/', '', (string) ($_GET['chNFe'] ?? '')) ?? '';

$erro = null;
$nfe = null;
$hashOk = null;

try {
    if ($p !== '') {
        $dados = QrCode::analisarParametro((string) $p);
        if ($dados === null) {
            throw new RuntimeException('Parametro do QR Code em formato invalido.');
        }
        $chave = Chave::analisar($dados['chave']);

        $nfe = buscarNfe($chave->valor);

        // Valida o hash contra o CSC do emitente.
        if ($nfe !== null) {
            $emit = Db::um(
                'SELECT csc_id, csc_token FROM emitente WHERE cnpj = ?',
                [$chave->cnpj]
            );
            if ($emit !== null && $emit['csc_token'] !== null) {
                $hashOk = QrCode::validarHash(
                    $dados['chave'],
                    $dados['versaoQR'],
                    $dados['tpAmb'],
                    $dados['cIdToken'],
                    (string) $emit['csc_token'],
                    $dados['hash'],
                    $dados['diaEmi'] ?? null,
                    $dados['vNF'] ?? null,
                    $dados['digVal'] ?? null
                );
            }
        }
    } elseif ($chaveManual !== '') {
        if (strlen($chaveManual) !== 44) {
            throw new RuntimeException('A chave de acesso deve ter 44 digitos.');
        }
        $chave = Chave::analisar($chaveManual);
        if (!$chave->dvValido()) {
            throw new RuntimeException('Chave de acesso com digito verificador invalido.');
        }
        $nfe = buscarNfe($chave->valor);
    }
} catch (Throwable $e) {
    $erro = $e->getMessage();
}

function buscarNfe(string $chave): ?array
{
    return Db::um(
        'SELECT n.*, e.razao_social, e.ie
           FROM nfe n
           LEFT JOIN emitente e ON e.id = n.emitente_id
          WHERE n.chave = ?',
        [$chave]
    );
}

function h(?string $v): string
{
    return htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8');
}

$temConsulta = ($p !== '' || $chaveManual !== '');
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Consulta NFC-e - Ambiente de Simulacao</title>
<style>
  :root { --azul:#1351b4; --cinza:#f5f6f7; --borda:#d4d8dd; }
  * { box-sizing: border-box; }
  body { margin:0; font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
         background:var(--cinza); color:#1a1a1a; }
  .aviso { background:#fff3cd; border-bottom:2px solid #ffc107; color:#664d03;
           padding:.7rem 1rem; text-align:center; font-size:.9rem; font-weight:600; }
  header { background:var(--azul); color:#fff; padding:1.1rem 1rem; }
  header h1 { margin:0; font-size:1.2rem; font-weight:600; }
  main { max-width:820px; margin:1.5rem auto; padding:0 1rem; }
  .card { background:#fff; border:1px solid var(--borda); border-radius:8px;
          padding:1.25rem; margin-bottom:1rem; }
  .chave { font-family: ui-monospace, monospace; font-size:.95rem; word-break:break-all;
           background:var(--cinza); padding:.6rem; border-radius:4px; }
  table { width:100%; border-collapse:collapse; margin-top:.5rem; }
  th, td { text-align:left; padding:.55rem .4rem; border-bottom:1px solid var(--borda);
           font-size:.93rem; vertical-align:top; }
  th { width:38%; color:#555; font-weight:600; }
  .selo { display:inline-block; padding:.3rem .75rem; border-radius:999px;
          font-size:.85rem; font-weight:700; }
  .ok   { background:#d1e7dd; color:#0a3622; }
  .ruim { background:#f8d7da; color:#58151c; }
  .neutro { background:#e2e3e5; color:#41464b; }
  form { display:flex; gap:.5rem; flex-wrap:wrap; }
  input[type=text] { flex:1; min-width:260px; padding:.6rem; font-size:1rem;
                     border:1px solid var(--borda); border-radius:4px;
                     font-family: ui-monospace, monospace; }
  button { padding:.6rem 1.4rem; background:var(--azul); color:#fff; border:0;
           border-radius:4px; font-size:1rem; cursor:pointer; }
  .erro { background:#f8d7da; color:#58151c; padding:.8rem; border-radius:4px; }
</style>
</head>
<body>

<div class="aviso">
  AMBIENTE DE SIMULACAO PARA TESTES &mdash; os documentos aqui consultados
  NAO possuem validade fiscal
</div>

<header><h1>Consulta NFC-e</h1></header>

<main>

  <div class="card">
    <form method="get">
      <input type="text" name="chNFe" maxlength="54" placeholder="Chave de acesso (44 digitos)"
             value="<?= h($chaveManual) ?>">
      <button type="submit">Consultar</button>
    </form>
  </div>

<?php if ($erro !== null): ?>
  <div class="card"><div class="erro"><?= h($erro) ?></div></div>

<?php elseif ($temConsulta && $nfe === null): ?>
  <div class="card">
    <span class="selo ruim">NAO ENCONTRADA</span>
    <p>Documento nao consta na base de dados deste ambiente.</p>
  </div>

<?php elseif ($nfe !== null): ?>
  <div class="card">
    <?php
      $situacao = (string) $nfe['situacao'];
      $classe = match ($situacao) {
          'autorizada' => 'ok',
          'cancelada', 'denegada' => 'ruim',
          default => 'neutro',
      };
    ?>
    <span class="selo <?= $classe ?>"><?= strtoupper(h($situacao)) ?></span>
    <?php if ($hashOk !== null): ?>
      <span class="selo <?= $hashOk ? 'ok' : 'ruim' ?>">
        QR Code: <?= $hashOk ? 'hash valido' : 'hash INVALIDO' ?>
      </span>
    <?php endif; ?>

    <p class="chave"><?= h((string) $nfe['chave']) ?></p>

    <table>
      <tr><th>Situacao</th><td><?= (int) $nfe['c_stat'] ?> &ndash; <?= h((string) $nfe['x_motivo']) ?></td></tr>
      <tr><th>Modelo</th><td><?= (int) $nfe['modelo'] === 65 ? '65 - NFC-e' : '55 - NF-e' ?></td></tr>
      <tr><th>Numero / Serie</th><td><?= (int) $nfe['numero'] ?> / <?= (int) $nfe['serie'] ?></td></tr>
      <tr><th>Emitente</th><td><?= h((string) ($nfe['razao_social'] ?? '-')) ?></td></tr>
      <tr><th>CNPJ</th><td><?= h((string) $nfe['cnpj_emit']) ?></td></tr>
      <tr><th>Destinatario</th><td><?= h((string) ($nfe['dest_nome'] ?? '-')) ?></td></tr>
      <tr><th>Valor total</th><td>R$ <?= number_format((float) $nfe['valor_total'], 2, ',', '.') ?></td></tr>
      <tr><th>Emissao</th><td><?= h((string) $nfe['dh_emi']) ?></td></tr>
      <tr><th>Protocolo</th><td><?= h((string) ($nfe['n_prot'] ?? '-')) ?></td></tr>
      <tr><th>Ambiente</th><td><?= (int) $nfe['tp_amb'] === 1 ? 'Producao' : 'Homologacao' ?></td></tr>
    </table>
  </div>
<?php endif; ?>

</main>
</body>
</html>
