<?php
/**
 * mac_status.php
 * Endpoint ultra-rápido de polling para o app verificar status do MAC a cada 5s.
 *
 * Retorna em <100ms o estado atual do MAC:
 *  - se está registrado, bloqueado, com credenciais prontas
 *  - activation_code gerado (se modo activation_code)
 *  - updated_at para detectar mudanças do painel instantaneamente
 *
 * Usado nas telas de "Aguardando liberação" (modo MAC) e
 * "Aguardando código de ativação" (modo activation_code).
 */
declare(strict_types=1);

require_once dirname(__DIR__) . '/_app_guard.php';
app_guard_validate();
require_once dirname(__DIR__) . '/_auth_common.php';
require_once dirname(__DIR__) . '/_trial_service.php';
require_once dirname(__DIR__) . '/_device_access.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 ms_out(array $payload): void {
    echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}


function ms_insert_pending_mac(PDO $db, string $mac): void {
    try {
        $cols = [];
        $q = $db->query('PRAGMA table_info(usuarios)');
        while ($r = $q->fetch(PDO::FETCH_ASSOC)) $cols[] = (string)$r['name'];
        if (!in_array('mac', $cols, true)) return;
        $fields = ['mac'];
        $values = [$mac];
        $add = function(string $col, $val) use (&$fields, &$values, $cols): void {
            if (in_array($col, $cols, true)) { $fields[] = $col; $values[] = $val; }
        };
        $deviceType = da_normalize_device_type((string)($_POST['device_type'] ?? $_GET['device_type'] ?? 'tv'));
        $add('dns', '');
        $add('username', '');
        $add('password', '');
        $add('vencimento', time() + 86400);
        $add('status', 'aguardando');
        $add('nome_cliente', 'Cliente ' . strtoupper(substr(str_replace(':', '', $mac), -4)));
        $add('whatsapp', '');
        $add('teste', 1);
        $add('teste_criado_at', time());
        $add('login_mode', 'mac');
        $add('device_type', $deviceType);
        $add('last_device_type', $deviceType);
        $sql = 'INSERT OR IGNORE INTO usuarios (' . implode(',', $fields) . ') VALUES (' . implode(',', array_fill(0, count($fields), '?')) . ')';
        $db->prepare($sql)->execute($values);
    } catch (Throwable $e) {}
}

function ms_normalize_mac(string $mac): string {
    $clean = strtoupper(substr(preg_replace('/[^A-Fa-f0-9]/', '', trim($mac)), 0, 12));
    if (strlen($clean) !== 12) return '';
    return implode(':', str_split($clean, 2));
}

$mac  = ms_normalize_mac((string)($_POST['mac'] ?? $_GET['mac'] ?? ''));
$mode = strtolower(trim((string)($_POST['mode'] ?? $_GET['mode'] ?? 'mac')));

if ($mac === '') {
    ms_out(['status' => 'error', 'message' => 'mac_required']);
}

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=2000');
    auth_ensure_schema($db);
    da_ensure_schema($db);
} catch (Throwable $e) {
    ms_out(['status' => 'error', 'message' => 'db_error']);
}

$activeMode = auth_get_active_login_mode($db);
$testCfg    = auth_get_test_config($db);
$dnsList    = auth_get_dns_list($db);

// Busca usuário pelo MAC
$st = $db->prepare('SELECT mac, username, password, dns, status, vencimento, nome_cliente, whatsapp, teste, login_mode, activation_code, usuario_id FROM usuarios WHERE mac = ? LIMIT 1');
$st->execute([$mac]);
$userRow = $st->fetch() ?: null;

$serverTs = time();

// --- MODO MAC: verifica se MAC já está liberado com credenciais válidas ---
if ($mode === 'mac') {
    if (!$userRow) {
        $autoMac  = (int)($testCfg['auto_mac_enabled'] ?? 0) === 1;
        $testOn   = (int)($testCfg['enabled']          ?? 0) === 1;
        if ($autoMac && $testOn) {
            try {
                $trial = gerar_teste_service($db, $mac, $testCfg, [
                    'nome' => 'Cliente ' . strtoupper(substr(str_replace(':', '', $mac), -4)),
                    'whatsapp' => '',
                ]);
                if (($trial['status'] ?? '') === 'success') {
                    $st = $db->prepare('SELECT mac, username, password, dns, status, vencimento, nome_cliente, whatsapp, teste, login_mode, activation_code, usuario_id FROM usuarios WHERE mac = ? LIMIT 1');
                    $st->execute([$mac]);
                    $userRow = $st->fetch() ?: null;
                }
            } catch (Throwable $e) {}
        }
        if (!$userRow) {
            ms_insert_pending_mac($db, $mac);
            ms_out([
                'status'           => 'waiting',
                'mac_registered'   => true,
                'active'           => false,
                'can_auto_trial'   => $autoMac && $testOn,
                'message'          => 'MAC cadastrado. Aguardando DNS, usuário e senha no painel.',
                'active_login_mode'=> $activeMode,
                'server_ts'        => $serverTs,
            ]);
        }
    }

    $userStatus  = strtolower(trim((string)($userRow['status'] ?? '')));
    $hasCreds    = trim((string)($userRow['dns'] ?? '')) !== ''
                && trim((string)($userRow['username'] ?? '')) !== ''
                && trim((string)($userRow['password'] ?? '')) !== '';
    $isActive    = ($userStatus === '' || $userStatus === 'ativo') && $hasCreds;

    if (!$isActive && !$hasCreds) {
        $autoMac  = (int)($testCfg['auto_mac_enabled'] ?? 0) === 1;
        $testOn   = (int)($testCfg['enabled']          ?? 0) === 1;
        if ($autoMac && $testOn) {
            try {
                $trial = gerar_teste_service($db, $mac, $testCfg, [
                    'nome' => 'Cliente ' . strtoupper(substr(str_replace(':', '', $mac), -4)),
                    'whatsapp' => '',
                ]);
                if (($trial['status'] ?? '') === 'success') {
                    $st = $db->prepare('SELECT mac, username, password, dns, status, vencimento, nome_cliente, whatsapp, teste, login_mode, activation_code, usuario_id FROM usuarios WHERE mac = ? LIMIT 1');
                    $st->execute([$mac]);
                    $userRow = $st->fetch() ?: $userRow;
                    $userStatus  = strtolower(trim((string)($userRow['status'] ?? '')));
                    $hasCreds    = trim((string)($userRow['dns'] ?? '')) !== ''
                                && trim((string)($userRow['username'] ?? '')) !== ''
                                && trim((string)($userRow['password'] ?? '')) !== '';
                    $isActive    = ($userStatus === '' || $userStatus === 'ativo') && $hasCreds;
                }
            } catch (Throwable $e) {}
        }
    }

    if (!$isActive) {
        ms_out([
            'status'           => 'waiting',
            'mac_registered'   => true,
            'active'           => false,
            'can_auto_trial'   => ((int)($testCfg['auto_mac_enabled'] ?? 0) === 1 && (int)($testCfg['enabled'] ?? 0) === 1),
            'message'          => $userStatus === 'inativo' ? 'Conta inativa. Aguardando liberação.' : 'Aguardando liberação.',
            'active_login_mode'=> $activeMode,
            'server_ts'        => $serverTs,
        ]);
    }

    // MAC ativo e com credenciais — retorna tudo para o app fazer login automático
    $dns      = trim((string)($userRow['dns'] ?? ''));
    $username = trim((string)($userRow['username'] ?? ''));
    $password = trim((string)($userRow['password'] ?? ''));
    $venc     = (string)($userRow['vencimento'] ?? '');
    $nome     = trim((string)($userRow['nome_cliente'] ?? ''));
    $whatsapp = trim((string)($userRow['whatsapp'] ?? ''));

    // Monta dns list com o DNS do usuário na frente
    $dnsListFinal = $dnsList;
    if ($dns !== '' && !in_array($dns, $dnsListFinal, true)) {
        array_unshift($dnsListFinal, $dns);
    }

    // Verifica bloqueio por dispositivo
    $userKey = da_user_key($username, $password);
    $profile = da_get_profile_by_key($db, $userKey);
    $blockedTv = empty($profile['allow_tv']);

    ms_out([
        'status'           => 'active',
        'mac_registered'   => true,
        'active'           => true,
        'blocked'          => $blockedTv,
        'username'         => $username,
        'password'         => $password,
        'dns'              => $dns,
        'dns_list'         => array_values($dnsListFinal),
        'vencimento'       => $venc,
        'nome_cliente'     => $nome,
        'whatsapp'         => $whatsapp,
        'active_login_mode'=> $activeMode,
        'server_ts'        => $serverTs,
    ]);
}

// --- MODO ACTIVATION_CODE: verifica/gera código de ativação ---
if ($mode === 'activation_code') {
    if (!$userRow) {
        // MAC não cadastrado — tenta gerar teste automático SE habilitado, gera código
        $autoMac = (int)($testCfg['auto_mac_enabled'] ?? 0) === 1;
        $testOn  = (int)($testCfg['enabled']          ?? 0) === 1;

        if ($autoMac && $testOn) {
            // Gera teste automático e retorna código de ativação
            $trial = gerar_teste_service($db, $mac, $testCfg, [
                'nome' => 'Cliente ' . strtoupper(substr(str_replace(':', '', $mac), -4)),
            ]);

            if (($trial['status'] ?? '') === 'success') {
                // Gera e salva código de ativação
                $code = auth_generate_activation_code($db);
                $db->prepare("UPDATE usuarios SET activation_code = ?, login_mode = 'activation_code' WHERE mac = ?")->execute([$code, $mac]);

                ms_out([
                    'status'            => 'code_generated',
                    'activation_code'   => $code,
                    'mac_registered'    => true,
                    'active_login_mode' => $activeMode,
                    'server_ts'         => $serverTs,
                ]);
            }

            ms_out([
                'status'           => 'waiting',
                'mac_registered'   => false,
                'active'           => false,
                'can_auto_trial'   => true,
                'active_login_mode'=> $activeMode,
                'message'          => 'Gerando acesso automático...',
                'server_ts'        => $serverTs,
            ]);
        }

        // Sem auto-trial: aguarda cadastro manual no painel
        ms_out([
            'status'           => 'waiting',
            'mac_registered'   => false,
            'active'           => false,
            'can_auto_trial'   => false,
            'active_login_mode'=> $activeMode,
            'message'          => 'MAC não cadastrado. Aguardando liberação.',
            'server_ts'        => $serverTs,
        ]);
    }

    // MAC já cadastrado — verifica se tem ou precisa gerar código de ativação
    $loginMode      = trim((string)($userRow['login_mode']      ?? 'normal'));
    $activationCode = trim((string)($userRow['activation_code'] ?? ''));

    // Se o modo do usuário é activation_code mas não tem código, gera agora
    if ($activationCode === '' && $loginMode === 'activation_code') {
        $activationCode = auth_generate_activation_code($db);
        $db->prepare("UPDATE usuarios SET activation_code = ? WHERE mac = ?")->execute([$activationCode, $mac]);
    }

    if ($activationCode !== '') {
        ms_out([
            'status'           => 'code_ready',
            'activation_code'  => $activationCode,
            'mac_registered'   => true,
            'active_login_mode'=> $activeMode,
            'server_ts'        => $serverTs,
        ]);
    }

    // MAC cadastrado mas sem código: aguardando admin gerar
    $userStatus = strtolower(trim((string)($userRow['status'] ?? '')));
    ms_out([
        'status'           => 'waiting',
        'mac_registered'   => true,
        'active'           => $userStatus === 'ativo',
        'active_login_mode'=> $activeMode,
        'message'          => 'Aguardando código de ativação.',
        'server_ts'        => $serverTs,
    ]);
}

// Modo desconhecido
ms_out(['status' => 'error', 'message' => 'invalid_mode']);
