<?php
declare(strict_types=1);

/**
 * Endpoint leve para o pareamento por código do revendedor.
 *
 * Não carrega telas do painel, não inicia sessão administrativa e devolve
 * somente JSON. A autenticação do aplicativo já é validada por api/app.php.
 */

require_once dirname(__DIR__) . '/_auth_common.php';
require_once dirname(__DIR__) . '/_multiserver.php';
require_once dirname(__DIR__, 2) . '/includes/profile_pairing.php';

header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');

function pairing_api_reply(array $payload, int $httpStatus = 200): void
{
    http_response_code($httpStatus);
    echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

$dbPath = dirname(__DIR__) . '/db.db';
try {
    $db = new PDO('sqlite:' . $dbPath, null, null, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false,
    ]);
    $db->exec('PRAGMA busy_timeout = 30000');
    $db->exec('PRAGMA journal_mode = WAL');
    $db->exec('PRAGMA synchronous = NORMAL');
    pp_ensure_schema($db);
    ms_ensure_schema($db);
    auth_ensure_schema($db);
} catch (Throwable $e) {
    pairing_api_reply([
        'status' => 'error',
        'message' => 'Não foi possível acessar o banco do painel.',
        'error_code' => 'database_unavailable',
    ], 500);
}

$apiAction = strtolower(trim((string)($_REQUEST['api_action'] ?? $_REQUEST['pairing_action'] ?? '')));
$mac = pp_normalize_mac((string)($_REQUEST['mac'] ?? ''));
$deviceType = strtolower(trim((string)($_REQUEST['device_type'] ?? 'tv'))) === 'mobile' ? 'mobile' : 'tv';
$code = preg_replace('/\D+/', '', (string)($_REQUEST['code'] ?? '')) ?: '';

if ($mac === '') {
    pairing_api_reply([
        'status' => 'error',
        'message' => 'MAC inválido.',
        'error_code' => 'mac_required',
    ], 422);
}

try {
    if ($apiAction === 'pairing_create') {
        $pair = pp_create_pairing_code($db, $mac, $deviceType);
        pairing_api_reply([
            'status' => 'ok',
            'code' => (string)($pair['code'] ?? ''),
            'mac' => (string)($pair['mac'] ?? $mac),
            'device_type' => (string)($pair['device_type'] ?? $deviceType),
            'expires_at' => (int)($pair['expires_at'] ?? 0),
            'expires_in' => max(0, (int)($pair['expires_at'] ?? 0) - time()),
        ]);
    }

    if ($apiAction === 'pairing_status' || $apiAction === 'pairing_access') {
        if (strlen($code) !== 4) {
            pairing_api_reply([
                'status' => 'not_found',
                'claimed' => false,
                'access_ready' => false,
                'message' => 'Código inválido.',
            ]);
        }

        $pair = pp_pairing_status($db, $mac, $code);
        $pairStatus = (string)($pair['status'] ?? 'not_found');
        $payload = [
            'status' => $pairStatus,
            'claimed' => $pairStatus === 'claimed',
            'access_ready' => false,
            'revendedor_id' => (int)($pair['revendedor_id'] ?? 0),
            'expires_at' => (int)($pair['expires_at'] ?? 0),
            'expires_in' => max(0, (int)($pair['expires_at'] ?? 0) - time()),
            'mac' => $mac,
        ];

        if ($pairStatus === 'claimed') {
            $st = $db->prepare('SELECT * FROM usuarios WHERE mac=? ORDER BY rowid DESC LIMIT 1');
            $st->execute([$mac]);
            $user = $st->fetch(PDO::FETCH_ASSOC) ?: null;

            $servers = $user ? ms_get_servers($db, $mac, $user) : [];
            $primary = $servers[0] ?? null;
            $dns = $primary ? ms_normalize_dns((string)($primary['dns'] ?? '')) : auth_normalize_dns((string)($user['dns'] ?? ''));
            $username = trim((string)($primary['username'] ?? $user['username'] ?? ''));
            $password = (string)($primary['password'] ?? $user['password'] ?? '');
            $accessReady = $user !== null && $dns !== '' && $username !== '' && trim($password) !== '';
            $ownerId = (int)($user['usuario_id'] ?? $pair['revendedor_id'] ?? 0);
            $branding = $user && function_exists('auth_branding_payload')
                ? auth_branding_payload($db, $user)
                : auth_branding_payload($db, ['usuario_id' => $ownerId]);

            $dnsList = [];
            foreach ($servers as $server) {
                $serverDns = ms_normalize_dns((string)($server['dns'] ?? ''));
                if ($serverDns !== '' && !in_array($serverDns, $dnsList, true)) {
                    $dnsList[] = $serverDns;
                }
            }
            if ($dns !== '' && !in_array($dns, $dnsList, true)) {
                array_unshift($dnsList, $dns);
            }

            $payload = array_merge($payload, $branding, [
                'pairing_status' => $pairStatus,
                'login_status' => $accessReady ? 'ok' : 'waiting',
                'access_ready' => $accessReady,
                'mac_registered' => $user !== null,
                'mac_pending' => !$accessReady,
                'mac_has_credentials' => $accessReady,
                'dns' => $dns,
                'dns_list' => array_values($dnsList),
                'username' => $username,
                'password' => $password,
                'nome_cliente' => (string)($user['nome_cliente'] ?? ''),
                'whatsapp' => (string)($user['whatsapp'] ?? ''),
                'vencimento' => (string)($user['vencimento'] ?? ''),
                'revendedor_id' => $ownerId,
                'owner_id' => $ownerId,
                'usuario_id' => $ownerId,
                'servers' => $servers,
                'server_count' => count($servers),
                'multi_server_enabled' => count($servers) > 1,
                'message' => $accessReady
                    ? ($ownerId > 0 ? 'Acesso liberado pela revenda.' : 'Acesso liberado pelo administrador.')
                    : 'Código confirmado. Aguardando DNS, usuário e senha.',
            ]);
        }

        pairing_api_reply($payload);
    }

    if ($apiAction === 'pairing_cancel') {
        $cancelled = strlen($code) === 4 && pp_cancel_pairing($db, $mac, $code);
        pairing_api_reply([
            'status' => $cancelled ? 'cancelled' : 'not_found',
            'cancelled' => $cancelled,
        ]);
    }

    if ($apiAction === 'pairing_complete') {
        $completed = strlen($code) === 4 && pp_complete_pairing($db, $mac, $code);
        pairing_api_reply([
            'status' => $completed ? 'completed' : 'not_found',
            'completed' => $completed,
        ]);
    }

    pairing_api_reply([
        'status' => 'error',
        'message' => 'Ação de pareamento inválida.',
        'error_code' => 'unknown_pairing_action',
    ], 400);
} catch (Throwable $e) {
    pairing_api_reply([
        'status' => 'error',
        'message' => trim($e->getMessage()) !== '' ? $e->getMessage() : 'Não foi possível concluir o pareamento.',
        'error_code' => 'pairing_failed',
    ], 500);
}
