<?php
/**
 * realtime_check.php
 * Endpoint de polling inteligente para os apps verificarem INSTANTANEAMENTE:
 *  - Bloqueio de dispositivo (allow_tv / allow_mobile)
 *  - Mudanças nas regras de acesso (allow_live, allow_movies, allow_series)
 *  - Status da conta (ativo/inativo)
 *  - Vencimento (conta vencida = bloquear)
 *  - updated_at para saber se precisam re-fetch completo
 *
 * Resposta minimalista para ser rápida (<1 KB, <50ms).
 * Apps devem chamar isso a cada 8-10 segundos enquanto ativos.
 *
 * MELHORIAS v2:
 *  - Retorna status da conta (inativo = bloquear imediatamente)
 *  - Retorna vencimento para o app detectar expiração
 *  - Retorna mensagem de bloqueio para exibir ao usuário
 *  - Cache SQLite WAL para resposta mais rápida
 */

declare(strict_types=1);

require_once dirname(__DIR__) . '/_app_guard.php';
app_guard_validate();
require_once dirname(__DIR__) . '/_device_access.php';
require_once dirname(__DIR__) . '/_auth_common.php';

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-App-Token');

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'OPTIONS') {
    http_response_code(204);
    exit;
}

function rt_out(array $payload): void {
    echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

$mac        = trim((string)($_POST['mac'] ?? $_GET['mac'] ?? ''));
$deviceType = da_normalize_device_type((string)($_POST['device_type'] ?? $_GET['device_type'] ?? 'tv'));
$clientTs   = (int)($_POST['last_ts'] ?? $_GET['last_ts'] ?? 0); // timestamp da última resposta conhecida pelo app

try {
    $db = new PDO('sqlite:' . dirname(__DIR__) . '/db.db');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    $db->exec('PRAGMA journal_mode=WAL');
    $db->exec('PRAGMA busy_timeout=1000');
    $db->exec('PRAGMA synchronous=NORMAL');
    da_ensure_schema($db);
    auth_ensure_schema($db);
} catch (Throwable $e) {
    rt_out(['status' => 'erro']);
}

$macNorm = da_normalize_mac($mac);
if ($macNorm === '') {
    rt_out(['status' => 'erro', 'message' => 'invalid_mac']);
}

$userRow = da_find_user_by_mac($db, $macNorm);
$serverTs = time();

if (!$userRow) {
    rt_out([
        'status'           => 'ok',
        'blocked'          => false,
        'rules_updated_at' => 0,
        'server_ts'        => $serverTs,
        'changed'          => false,
    ]);
}

$userStatus = strtolower(trim((string)($userRow['status'] ?? '')));
$vencimento = (int)($userRow['vencimento'] ?? 0);
$now        = time();

// --- Conta inativa ou vencida ---
if ($userStatus !== '' && $userStatus !== 'ativo') {
    rt_out([
        'status'           => 'ok',
        'blocked'          => true,
        'block_reason'     => 'account_inactive',
        'message'          => 'Conta desativada. Entre em contato com o suporte.',
        'allow_tv'         => false,
        'allow_mobile'     => false,
        'allow_movies'     => false,
        'allow_series'     => false,
        'allow_live'       => false,
        'rules_updated_at' => $serverTs,
        'server_ts'        => $serverTs,
        'changed'          => true,
    ]);
}

if ($vencimento > 0 && $vencimento < $now) {
    rt_out([
        'status'           => 'ok',
        'blocked'          => true,
        'block_reason'     => 'expired',
        'message'          => 'Sua conta venceu. Renove para continuar assistindo.',
        'allow_tv'         => false,
        'allow_mobile'     => false,
        'allow_movies'     => false,
        'allow_series'     => false,
        'allow_live'       => false,
        'rules_updated_at' => $serverTs,
        'server_ts'        => $serverTs,
        'changed'          => true,
        'vencimento'       => $vencimento,
    ]);
}

$userKey = da_user_key($userRow['username'] ?? '', $userRow['password'] ?? '');
$profile = da_get_profile_by_key($db, $userKey);

// Verifica bloqueio por tipo de dispositivo
$deviceBlocked = false;
$blockReason   = '';
if ($deviceType === 'mobile' && empty($profile['allow_mobile'])) {
    $deviceBlocked = true;
    $blockReason   = 'device_type_blocked';
} elseif ($deviceType === 'tv' && empty($profile['allow_tv'])) {
    $deviceBlocked = true;
    $blockReason   = 'device_type_blocked';
}

// Pega updated_at das regras e do perfil
$rulesUpdatedAt = (int)($profile['updated_at'] ?? 0);

$stRule = $db->prepare('SELECT updated_at FROM access_rules WHERE mac=? ORDER BY updated_at DESC LIMIT 1');
$stRule->execute([$macNorm]);
$ruleRow = $stRule->fetch();
if ($ruleRow && (int)$ruleRow['updated_at'] > $rulesUpdatedAt) {
    $rulesUpdatedAt = (int)$ruleRow['updated_at'];
}

// Verifica se houve mudança desde a última resposta conhecida pelo app
$changed = ($rulesUpdatedAt > $clientTs);

// Permissões de conteúdo
$allowTv     = !empty($profile['allow_tv']);
$allowMobile = !empty($profile['allow_mobile']);
$allowMovies = !empty($profile['allow_movies']);
$allowSeries = !empty($profile['allow_series']);
$allowLive   = !empty($profile['allow_live']);

$response = [
    'status'           => 'ok',
    'blocked'          => $deviceBlocked,
    'allow_tv'         => $allowTv,
    'allow_mobile'     => $allowMobile,
    'allow_movies'     => $allowMovies,
    'allow_series'     => $allowSeries,
    'allow_live'       => $allowLive,
    'rules_updated_at' => $rulesUpdatedAt,
    'server_ts'        => $serverTs,
    'changed'          => $changed,
    'vencimento'       => $vencimento,
];

if ($deviceBlocked) {
    $response['block_reason'] = $blockReason;
    $response['message']      = 'Este tipo de dispositivo está bloqueado.';
}

rt_out($response);
