<?php

declare(strict_types=1);

// ============================================================
// config.php — API RRB — PHP 8.2+
// Requiere PHP 8.2 o superior.
// ============================================================

define('DB_HOST',    'localhost');
define('DB_NAME',    'wwsist_rrb0426');
define('DB_USER',    'wwsist_mikes');
define('DB_PASS',    'Mikel123*');
define('JWT_SECRET', 'RRB_SECRET_KEY_2026_CAMBIAR');
define('JWT_EXPIRE', 604800);

// --- Funciones de base de datos ---

function getDB(): PDO {
    static $pdo = null;
    if ($pdo === null) {
        try {
            $pdo = new PDO(
                'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8mb4',
                DB_USER,
                DB_PASS,
                [
                    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                    PDO::ATTR_EMULATE_PREPARES   => false,
                ]
            );
        } catch (PDOException $e) {
            http_response_code(500);
            echo json_encode(['success' => false, 'message' => 'Error de conexion a la base de datos.']);
            exit;
        }
    }
    return $pdo;
}

// --- Funciones de respuesta ---

function jsonOk(array $data, int $code = 200): never {
    http_response_code($code);
    echo json_encode(['success' => true, 'data' => $data], JSON_UNESCAPED_UNICODE);
    exit;
}

function jsonErr(int $code, string $msg): never {
    http_response_code($code);
    echo json_encode(['success' => false, 'message' => $msg], JSON_UNESCAPED_UNICODE);
    exit;
}

// --- Funciones JWT ---

function b64url(string $data): string {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function makeJWT(array $payload): string {
    $h          = b64url(json_encode(['alg' => 'HS256', 'typ' => 'JWT']));
    $payload['iat'] = time();
    $payload['exp'] = time() + JWT_EXPIRE;
    $p          = b64url(json_encode($payload));
    $sig        = b64url(hash_hmac('sha256', $h . '.' . $p, JWT_SECRET, true));
    return $h . '.' . $p . '.' . $sig;
}

function checkJWT(string $token): ?array {
    $parts = explode('.', $token);
    if (count($parts) !== 3) {
        return null;
    }
    $expected = b64url(hash_hmac('sha256', $parts[0] . '.' . $parts[1], JWT_SECRET, true));
    if (!hash_equals($expected, $parts[2])) {
        return null;
    }
    $data = json_decode(base64_decode(strtr($parts[1], '-_', '+/')), true);
    if (!is_array($data) || ($data['exp'] ?? 0) < time()) {
        return null;
    }
    return $data;
}

// --- Middleware de autenticacion ---

function auth(): array {
    $h = '';

    // Metodo 1: HTTP_AUTHORIZATION directo (Apache mod_php)
    if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
        $h = $_SERVER['HTTP_AUTHORIZATION'];
    }
    // Metodo 2: REDIRECT_HTTP_AUTHORIZATION (cPanel PHP-FPM / FastCGI con RewriteRule)
    elseif (!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
        $h = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
    }
    // Metodo 3: apache_request_headers() (disponible en algunos entornos cPanel)
    elseif (function_exists('apache_request_headers')) {
        $hdrs = apache_request_headers();
        if (!empty($hdrs['Authorization'])) {
            $h = $hdrs['Authorization'];
        } elseif (!empty($hdrs['authorization'])) {
            $h = $hdrs['authorization'];
        }
    }
    // Metodo 4: getallheaders() como alternativa
    if (!$h && function_exists('getallheaders')) {
        $hdrs = getallheaders();
        if (!empty($hdrs['Authorization'])) {
            $h = $hdrs['Authorization'];
        } elseif (!empty($hdrs['authorization'])) {
            $h = $hdrs['authorization'];
        }
    }
    // Metodo 5: leer directamente del header HTTP_AUTHORIZATION via SetEnvIf
    if (!$h && !empty($_SERVER['Authorization'])) {
        $h = $_SERVER['Authorization'];
    }
    // Metodo 6: Leer del stream de entrada (para PHP-FPM en cPanel)
    if (!$h) {
        $headers = getallheaders();
        if ($headers && is_array($headers)) {
            foreach ($headers as $key => $value) {
                if (strtolower($key) === 'authorization') {
                    $h = $value;
                    break;
                }
            }
        }
    }

    // Metodo 6: token por parametro GET (solo para diagnostico)
    $rawToken = '';
    if (!$h && !empty($_GET['token'])) {
        $rawToken = $_GET['token'];
    } elseif ($h && str_starts_with($h, 'Bearer ')) {
        $rawToken = substr($h, 7);
    }

    if (!$rawToken) {
        jsonErr(401, 'Token requerido.');
    }
    $payload = checkJWT($rawToken);
    if (!$payload) {
        jsonErr(401, 'Token invalido o expirado.');
    }
    return $payload;
}

// --- Leer body JSON ---

function body(): array {
    $raw = file_get_contents('php://input');
    $d   = json_decode($raw, true);
    return is_array($d) ? $d : [];
}

// --- Calculo de referencia (digito verificador) ---

function calcRef(int $id): string {
    $temp   = $id;
    $digits = str_split((string)$temp);
    $len    = count($digits);
    $start2 = ($len % 2 === 0);
    $sum    = 0;
    foreach ($digits as $i => $d) {
        $useTwo = $start2 ? ($i % 2 === 0) : ($i % 2 !== 0);
        $mult   = $useTwo ? 2 : 1;
        $val    = (int)$d * $mult;
        if ($val > 9) {
            $s   = str_split((string)$val);
            $val = (int)$s[0] + (int)$s[1];
        }
        $sum += $val;
    }
    $r = $sum % 10;
    $v = ($r === 0) ? 0 : (10 - $r);
    return (string)$temp . (string)$v;
}

// ============================================================
// CORS y headers — se ejecutan al incluir este archivo
// ============================================================
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Content-Type: application/json; charset=utf-8');

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