<?php
require_once __DIR__ . '/config.php';

$method = $_SERVER['REQUEST_METHOD'];
$action = strParam('action');

// ─── LOGIN ────────────────────────────────────────────────────────────────────
if ($action === 'login' && $method === 'POST') {
    $b = body();
    $username = trim($b['username'] ?? '');
    $password = $b['password'] ?? '';
    if (!$username || !$password) jsonError('Usuario y contraseña requeridos');

    try {
        $db = getDB();
        $st = $db->prepare("SELECT * FROM users WHERE username=? AND active=1 LIMIT 1");
        $st->execute([$username]);
        $user = $st->fetch();

        if (!$user) jsonError('Credenciales incorrectas', 401);

        // Soporte para contraseñas en texto plano (legacy) y hashes bcrypt
        $ok = false;
        if (strpos($user['password_hash'], '$2y$') === 0) {
            $ok = password_verify($password, $user['password_hash']);
        } else {
            // Texto plano: migrar a hash
            $ok = ($user['password_hash'] === $password);
            if ($ok) {
                $hash = password_hash($password, PASSWORD_BCRYPT);
                $db->prepare("UPDATE users SET password_hash=? WHERE id=?")->execute([$hash, $user['id']]);
            }
        }
        if (!$ok) jsonError('Credenciales incorrectas', 401);

        // Crear sesión (token 64 hex chars, expira en 8 horas)
        $token = bin2hex(random_bytes(32));
        $exp   = date('Y-m-d H:i:s', time() + 8 * 3600);
        // Limpiar sesiones viejas del usuario
        $db->prepare("DELETE FROM sessions WHERE user_id=?")->execute([$user['id']]);
        $db->prepare("INSERT INTO sessions (user_id,token,expires_at) VALUES (?,?,?)")
           ->execute([$user['id'], $token, $exp]);

        $user['podoFunctions'] = json_decode($user['podo_functions'] ?? '[]', true) ?? [];
        unset($user['password_hash'], $user['podo_functions']);

        jsonOk(['ok' => true, 'token' => $token, 'user' => $user]);
    } catch (Throwable $e) {
        jsonError('Error en login: ' . $e->getMessage(), 500);
    }
}

// ─── LOGOUT ───────────────────────────────────────────────────────────────────
if ($action === 'logout' && $method === 'POST') {
    $token = $_SERVER['HTTP_X_AUTH_TOKEN'] ?? '';
    if ($token) {
        try {
            $db = getDB();
            $db->prepare("DELETE FROM sessions WHERE token=?")->execute([$token]);
        } catch (Throwable $e) {}
    }
    jsonOk(['ok' => true]);
}

// ─── VERIFICAR SESIÓN ─────────────────────────────────────────────────────────
if ($action === 'me' && $method === 'GET') {
    $user = requireAuth();
    unset($user['password_hash'], $user['podo_functions']);
    jsonOk(['ok' => true, 'user' => $user]);
}

// ─── LICENCIA: VERIFICAR ─────────────────────────────────────────────────────
if ($action === 'license_verify' && $method === 'GET') {
    try {
        $db = getDB();
        $st = $db->prepare("SELECT val FROM config WHERE `key`='license' LIMIT 1");
        $st->execute();
        $row = $st->fetch();
        $key = $row['val'] ?? '';
        $valid = verifyLicense($key);
        jsonOk(['valid' => $valid, 'key' => $valid ? $key : null]);
    } catch (Throwable $e) {
        jsonOk(['valid' => false, 'key' => null]);
    }
}

// ─── LICENCIA: ACTIVAR ───────────────────────────────────────────────────────
if ($action === 'license_activate' && $method === 'POST') {
    $b = body();
    $key = strtoupper(trim($b['key'] ?? ''));
    if (!$key) jsonError('Clave requerida');
    if (!verifyLicense($key)) jsonError('Clave de licencia inválida');

    try {
        $db = getDB();
        $st = $db->prepare("INSERT INTO config (`key`,val) VALUES ('license',?) ON DUPLICATE KEY UPDATE val=?");
        $st->execute([$key, $key]);
        jsonOk(['ok' => true, 'message' => 'Licencia activada correctamente']);
    } catch (Throwable $e) {
        jsonError('Error al guardar licencia: ' . $e->getMessage(), 500);
    }
}


// ─── CHECK_USER: verificar si usuario existe y si tiene contraseña ────────────
if ($action === 'check_user' && $method === 'POST') {
    $b = body();
    $username = trim($b['username'] ?? '');
    if (!$username) jsonError('Usuario requerido');

    try {
        $db = getDB();
        $st = $db->prepare("SELECT id, name, role, password_hash FROM users WHERE username=? AND active=1 LIMIT 1");
        $st->execute([$username]);
        $user = $st->fetch();

        if (!$user) {
            jsonOk(['exists' => false]);
        }

        $noPassword = empty($user['password_hash']) || trim($user['password_hash']) === '';
        jsonOk([
            'exists'      => true,
            'no_password' => $noPassword,
            'id'          => $user['id'],
            'name'        => $user['name'],
            'role'        => $user['role'],
        ]);
    } catch (Throwable $e) {
        jsonError('Error: ' . $e->getMessage(), 500);
    }
}

// ─── SET_PASSWORD: establecer contraseña por primera vez (usuario sin pass) ──
if ($action === 'set_password' && $method === 'POST') {
    $b        = body();
    $username = trim($b['username'] ?? '');
    $password = $b['password'] ?? '';

    if (!$username || !$password) jsonError('Usuario y contraseña requeridos');
    if (strlen($password) < 6) jsonError('La contraseña debe tener al menos 6 caracteres');

    try {
        $db = getDB();
        $st = $db->prepare("SELECT * FROM users WHERE username=? AND active=1 LIMIT 1");
        $st->execute([$username]);
        $user = $st->fetch();

        if (!$user) jsonError('Usuario no encontrado', 404);

        // Solo permitir si NO tiene contraseña aún
        if (!empty($user['password_hash']) && trim($user['password_hash']) !== '') {
            jsonError('Este usuario ya tiene contraseña. Use el login normal.', 403);
        }

        $hash = password_hash($password, PASSWORD_BCRYPT);
        $db->prepare("UPDATE users SET password_hash=? WHERE id=?")->execute([$hash, $user['id']]);

        // Crear sesión directamente
        $token = bin2hex(random_bytes(32));
        $exp   = date('Y-m-d H:i:s', time() + 8 * 3600);
        $db->prepare("DELETE FROM sessions WHERE user_id=?")->execute([$user['id']]);
        $db->prepare("INSERT INTO sessions (user_id,token,expires_at) VALUES (?,?,?)")
           ->execute([$user['id'], $token, $exp]);

        $user['podoFunctions'] = json_decode($user['podo_functions'] ?? '[]', true) ?? [];
        unset($user['password_hash'], $user['podo_functions']);

        jsonOk(['ok' => true, 'token' => $token, 'user' => $user]);
    } catch (Throwable $e) {
        jsonError('Error: ' . $e->getMessage(), 500);
    }
}

// ─── CHANGE_PASSWORD: Super Admin cambia contraseña de cualquier usuario ──────
if ($action === 'change_password' && $method === 'POST') {
    $caller = requireAuth();
    if ($caller['role'] !== 'Super Admin') jsonError('Solo el Super Admin puede cambiar contraseñas', 403);

    $b      = body();
    $userId = (int)($b['user_id'] ?? 0);
    $newPwd = $b['password'] ?? '';
    $newUser = trim($b['username'] ?? '');
    $newName = trim($b['name'] ?? '');

    if (!$userId) jsonError('user_id requerido');
    if ($newPwd && strlen($newPwd) < 6) jsonError('La contraseña debe tener al menos 6 caracteres');

    try {
        $db = getDB();
        $updates = [];
        $vals    = [];

        if ($newPwd) {
            $updates[] = 'password_hash=?';
            $vals[]    = password_hash($newPwd, PASSWORD_BCRYPT);
        }
        if ($newUser) {
            // Check unique
            $chk = $db->prepare("SELECT id FROM users WHERE username=? AND id!=? LIMIT 1");
            $chk->execute([$newUser, $userId]);
            if ($chk->fetch()) jsonError('El nombre de usuario ya está en uso');
            $updates[] = 'username=?';
            $vals[]    = $newUser;
        }
        if ($newName) {
            $updates[] = 'name=?';
            $vals[]    = $newName;
        }

        if (empty($updates)) jsonError('Sin datos para actualizar');

        $vals[] = $userId;
        $db->prepare("UPDATE users SET " . implode(',', $updates) . " WHERE id=?")->execute($vals);

        $st = $db->prepare("SELECT id,username,name,role,active FROM users WHERE id=? LIMIT 1");
        $st->execute([$userId]);
        jsonOk(['ok' => true, 'user' => $st->fetch()]);
    } catch (Throwable $e) {
        jsonError('Error: ' . $e->getMessage(), 500);
    }
}

// ─── LISTA PÚBLICA DE USUARIOS ACTIVOS (para dropdown login) ─────────────────
// No requiere autenticación — solo devuelve username, name y role (sin datos sensibles)
if ($action === 'user_list' && $method === 'GET') {
    try {
        $db = getDB();
        $st = $db->query(
            "SELECT username, name, role FROM users WHERE active=1 ORDER BY role DESC, name ASC"
        );
        jsonOk(['users' => $st->fetchAll()]);
    } catch (Throwable $e) {
        jsonOk(['users' => []]); // Silencioso si BD no está lista
    }
}

// ─── RESET PASSWORD (por username — solo desde gestor externo con token) ──────
// action=reset_password  POST {username, new_password, master_token}
if ($action === 'reset_password' && $method === 'POST') {
    $b = body();
    $masterToken = $b['master_token'] ?? '';
    // Verificar token maestro (mismo secret que licencia)
    $expectedToken = hash_hmac('sha256', 'reset_password', 'PODOCLINIC2024BELA');
    if (!hash_equals($expectedToken, $masterToken)) {
        jsonError('Token maestro inválido', 403);
    }
    $username = trim($b['username'] ?? '');
    $newPwd   = $b['new_password'] ?? '';
    if (!$username) jsonError('Usuario requerido');
    if (strlen($newPwd) < 4) jsonError('La contraseña debe tener al menos 4 caracteres');
    try {
        $db = getDB();
        $st = $db->prepare("SELECT id, name FROM users WHERE username=? LIMIT 1");
        $st->execute([$username]);
        $u = $st->fetch();
        if (!$u) jsonError('Usuario no encontrado', 404);
        $hash = password_hash($newPwd, PASSWORD_BCRYPT);
        $db->prepare("UPDATE users SET password_hash=? WHERE username=?")->execute([$hash, $username]);
        // Invalidar todas las sesiones activas del usuario
        $db->prepare("DELETE FROM sessions WHERE user_id=?")->execute([$u['id']]);
        jsonOk(['ok' => true, 'message' => 'Contraseña actualizada para ' . $u['name']]);
    } catch (Throwable $e) {
        jsonError('Error: ' . $e->getMessage(), 500);
    }
}

jsonError('Acción no encontrada: ' . $action, 404);
