<?php
// ─── SUPRIMIR ERRORES PHP QUE ROMPEN EL JSON ──────────────────────────────────
ini_set('display_errors', '0');
ini_set('display_startup_errors', '0');
error_reporting(0);
ob_start(); // Captura cualquier output no-JSON antes de responder

// ─── CONFIGURACIÓN BD ─────────────────────────────────────────────────────────
// EDITAR ESTOS VALORES EN CPANEL → MySQL Databases
define('DB_HOST', 'localhost');
define('DB_NAME', 'soportej_podoclinic'); // ej: johndoe_podoclinic
define('DB_USER', 'soportej_podo');          // ej: johndoe_podo
define('DB_PASS', '#Alivale2002');
define('DB_CHARSET', 'utf8mb4');

// ─── LICENCIA ─────────────────────────────────────────────────────────────────
define('LICENSE_SECRET', 'PODOCLINIC2024BELA');

// ─── CORS & JSON HEADERS ──────────────────────────────────────────────────────
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-Requested-With, X-Auth-Token');
// Prevenir cache del navegador en todas las respuestas API
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Expires: 0');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }

// ─── CONEXIÓN PDO (singleton) ────────────────────────────────────────────────
function getDB() {
    static $pdo = null;
    if ($pdo === null) {
        $dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET;
        $pdo = new PDO($dsn, DB_USER, DB_PASS, [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,
        ]);
    }
    return $pdo;
}

// ─── HELPERS ──────────────────────────────────────────────────────────────────
function jsonOk($data) {
    while (ob_get_level() > 0) { ob_end_clean(); } // Descartar cualquier output previo (errores PHP, etc.)
    header('Content-Type: application/json; charset=utf-8');
    // No usar JSON_NUMERIC_CHECK: convierte DNI como "06016895" en 6016895 y pierde el cero inicial.
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}
function jsonError($msg, $code = 400) {
    while (ob_get_level() > 0) { ob_end_clean(); } // Descartar cualquier output previo
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(['error' => $msg], JSON_UNESCAPED_UNICODE);
    exit;
}
function body() {
    $raw = file_get_contents('php://input');
    if ($raw === false || trim($raw) === '') return [];
    $data = json_decode($raw, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        jsonError('JSON inválido recibido por el servidor: ' . json_last_error_msg(), 400);
    }
    return is_array($data) ? $data : [];
}
function intParam($key, $default = 0) {
    return isset($_GET[$key]) ? (int)$_GET[$key] : $default;
}
function strParam($key, $default = '') {
    return $_GET[$key] ?? $default;
}

// ─── VERIFICAR LICENCIA (HMAC-SHA256) ────────────────────────────────────────
function verifyLicense($key) {
    if (!$key) return false;
    $parts = explode('-', strtoupper(trim($key)));
    if (count($parts) !== 5) return false;
    $data  = implode('', array_slice($parts, 0, 4));
    $check = $parts[4];
    $hash  = strtoupper(substr(hash_hmac('sha256', $data, LICENSE_SECRET), 0, 4));
    return $hash === $check;
}

// ─── AUTENTICACIÓN POR TOKEN ─────────────────────────────────────────────────
function requireAuth() {
    $token = $_SERVER['HTTP_X_AUTH_TOKEN'] ?? '';
    if (!$token) jsonError('No autenticado', 401);
    try {
        $db = getDB();
        $st = $db->prepare(
            "SELECT s.user_id FROM sessions s
             WHERE s.token=? AND s.expires_at > NOW() LIMIT 1"
        );
        $st->execute([$token]);
        $sess = $st->fetch();
        if (!$sess) jsonError('Sesión inválida o expirada', 401);
        // Renovar la sesión mientras el usuario sigue trabajando.
        $db->prepare("UPDATE sessions SET expires_at=DATE_ADD(NOW(), INTERVAL 8 HOUR) WHERE token=?")->execute([$token]);

        $us = $db->prepare("SELECT * FROM users WHERE id=? AND active=1 LIMIT 1");
        $us->execute([$sess['user_id']]);
        $user = $us->fetch();
        if (!$user) jsonError('Usuario no encontrado', 401);

        // Decodificar campos JSON
        $user['podoFunctions'] = json_decode($user['podo_functions'] ?? '[]', true) ?? [];
        return $user;
    } catch (Throwable $e) {
        jsonError('Error de autenticación: ' . $e->getMessage(), 500);
    }
}

// ─── VERIFICAR LICENCIA ACTIVA ────────────────────────────────────────────────
function requireLicense() {
    try {
        $db = getDB();
        $st = $db->prepare("SELECT val FROM config WHERE `key`='license' LIMIT 1");
        $st->execute();
        $row = $st->fetch();
        if (!$row || !verifyLicense($row['val'])) {
            jsonError('Licencia inválida o no activada', 403);
        }
    } catch (Throwable $e) {
        jsonError('Error al verificar licencia', 500);
    }
}

// ─── PERMISOS POR ROL ─────────────────────────────────────────────────────────
const ROLE_PERMS = [
    'Super Admin'   => ['dashboard','patients','appointments','reports','config','admin',
                        'payments','cashbox','inventory','commissions','corte','reminders',
                        'portal','laboratory','photos','documents','library','ventas','suppliers'],
    'Administrador' => ['dashboard','patients','appointments','reports','config','admin',
                        'payments','cashbox','inventory','commissions','corte','reminders',
                        'portal','laboratory','photos','documents','library','ventas','suppliers'],
    'Podólogo'      => ['dashboard','patients','appointments','reports','payments',
                        'laboratory','photos'],
    'Recepcionista' => ['dashboard','patients','appointments','cashbox','reminders','portal'],
];

function can(array $user, $perm) {
    if ($user['role'] === 'Super Admin') return true;

    // Verificar primero si Super Admin desactivó este módulo para el rol en BD
    try {
        $db = getDB();
        // Checar permisos dinámicos guardados por Super Admin
        $st = $db->prepare("SELECT perms FROM module_perms WHERE role=? LIMIT 1");
        $st->execute([$user['role']]);
        $row = $st->fetch();
        if ($row) {
            $dynPerms = json_decode($row['perms'], true) ?? [];
            // Si hay permisos dinámicos guardados, usarlos (Super Admin los controló)
            return in_array($perm, $dynPerms);
        }
    } catch (Throwable $e) {
        // Si BD no disponible, usar permisos estáticos
    }

    $perms = ROLE_PERMS[$user['role']] ?? [];
    return in_array($perm, $perms, true);
}
function requirePerm(array $user, $perm) {
    if (!can($user, $perm)) jsonError('Sin permisos para esta acción', 403);
}
function requireSA(array $user) {
    if ($user['role'] !== 'Super Admin') jsonError('Acceso restringido al Super Administrador', 403);
}
function isSA(array $user) {
    return $user['role'] === 'Super Admin';
}
