#!/usr/bin/env php
<?php

declare(strict_types=1);

/**
 * Script de réinitialisation du mot de passe d'un utilisateur
 * Génère un nouveau mot de passe sécurisé et l'enregistre
 * Usage: ./reset-password <environment> <user_id>
 */

require_once __DIR__ . '/../lib/CryptoService.php';
require_once __DIR__ . '/../lib/DatabaseConnection.php';
require_once __DIR__ . '/../lib/helpers.php';

// Vérifier les arguments
if ($argc < 3) {
    error("Usage: " . basename($argv[0]) . " <environment> <user_id>");
    error("Exemple: " . basename($argv[0]) . " dva 123");
    exit(1);
}

$environment = strtoupper($argv[1]);
$userId = (int)$argv[2];

/**
 * Génère un mot de passe sécurisé selon les règles de l'API
 * Règles conformes à PasswordSecurityService de l'API
 *
 * @param int $length Longueur du mot de passe (12-20)
 * @return string Mot de passe généré
 */
function generateSecurePassword(int $length = 14): string {
    // Limiter la longueur entre 12 et 20 (règles API)
    $length = max(12, min(20, $length));

    // Caractères autorisés (sans ambiguïté visuelle - règles API)
    $lowercase = 'abcdefghijkmnopqrstuvwxyz'; // sans l
    $uppercase = 'ABCDEFGHJKLMNPQRSTUVWXYZ'; // sans I, O
    $numbers = '23456789'; // sans 0, 1
    $special = '!@#$%^&*()_+-=[]{}|;:,.<>?';

    $password = '';

    // Garantir au moins un caractère de chaque type (règle API)
    $password .= $lowercase[random_int(0, strlen($lowercase) - 1)];
    $password .= $uppercase[random_int(0, strlen($uppercase) - 1)];
    $password .= $numbers[random_int(0, strlen($numbers) - 1)];
    $password .= $special[random_int(0, strlen($special) - 1)];

    // Compléter avec des caractères aléatoires
    $allChars = $lowercase . $uppercase . $numbers . $special;
    for ($i = strlen($password); $i < $length; $i++) {
        $password .= $allChars[random_int(0, strlen($allChars) - 1)];
    }

    // Mélanger les caractères (règle API)
    $passwordArray = str_split($password);
    shuffle($passwordArray);

    return implode('', $passwordArray);
}

try {
    // Ouvrir le tunnel SSH si nécessaire
    $tunnelScript = __DIR__ . '/_ssh-tunnel.sh';
    exec("$tunnelScript open $environment 2>&1", $output, $exitCode);

    if ($exitCode !== 0) {
        error("Impossible d'ouvrir le tunnel SSH");
        exit(1);
    }

    // Connexion à la base de données
    $db = new DatabaseConnection($environment);
    $pdo = $db->connect();

    info("Environnement: $environment");
    info("Recherche de l'utilisateur #$userId...\n");

    // Vérifier que l'utilisateur existe
    $stmt = $pdo->prepare("
        SELECT
            u.id,
            u.encrypted_user_name,
            u.encrypted_email,
            u.encrypted_name,
            u.first_name
        FROM users u
        WHERE u.id = :user_id
    ");

    $stmt->execute(['user_id' => $userId]);
    $user = $stmt->fetch();

    if (!$user) {
        error("Utilisateur #$userId introuvable");
        exit(1);
    }

    // Déchiffrer les données pour affichage
    $config = DatabaseConfig::getInstance();
    $crypto = new CryptoService($config->getEncryptionKey());

    $userName = $crypto->decryptSearchable($user['encrypted_user_name']);
    $email = $crypto->decryptSearchable($user['encrypted_email']);
    $name = $crypto->decryptWithIV($user['encrypted_name']);
    $firstName = $user['first_name'];

    // Afficher les infos utilisateur
    title("RÉINITIALISATION DU MOT DE PASSE");

    echo color("Utilisateur\n", 'bold');
    display("ID", (string)$user['id']);
    display("Username", $userName);
    display("Prénom", $firstName);
    display("Nom", $name);
    display("Email", $email);

    echo "\n";

    // Demander confirmation
    if (!confirm("Confirmer la réinitialisation du mot de passe ?")) {
        warning("Opération annulée");
        exit(0);
    }

    // Générer un nouveau mot de passe
    $newPassword = generateSecurePassword(14);
    $passwordHash = password_hash($newPassword, PASSWORD_BCRYPT);

    info("\nGénération du nouveau mot de passe...");

    // Mettre à jour la base de données
    $updateStmt = $pdo->prepare("
        UPDATE users
        SET user_pass_hash = :password_hash,
            updated_at = CURRENT_TIMESTAMP
        WHERE id = :user_id
    ");

    $updateStmt->execute([
        'password_hash' => $passwordHash,
        'user_id' => $userId
    ]);

    if ($updateStmt->rowCount() === 0) {
        error("Erreur lors de la mise à jour du mot de passe");
        exit(1);
    }

    // Afficher le résultat
    echo "\n";
    success("Mot de passe réinitialisé avec succès !");

    echo "\n";
    echo color("═══════════════════════════════════════════\n", 'cyan');
    echo color("  NOUVEAU MOT DE PASSE\n", 'bold');
    echo color("═══════════════════════════════════════════\n", 'cyan');
    echo "\n";
    echo color("  ", 'green') . color($newPassword, 'yellow') . "\n";
    echo "\n";
    echo color("═══════════════════════════════════════════\n", 'cyan');
    echo "\n";

    warning("⚠ Conservez ce mot de passe en lieu sûr !");
    warning("  Il ne sera pas possible de le récupérer.");

    echo "\n";

} catch (Exception $e) {
    error("Erreur: " . $e->getMessage());
    exit(1);
}
