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

declare(strict_types=1);

/**
 * Script de recherche d'utilisateurs par chaîne
 * Recherche dans : username, nom, prénom, secteur
 * Usage: ./search-user <environment> <search_string>
 */

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> <search_string>");
    error("Exemple: " . basename($argv[0]) . " dva dupont");
    error("         " . basename($argv[0]) . " dva secteur_a");
    error("         " . basename($argv[0]) . " dva j.dupont");
    exit(1);
}

$environment = strtoupper($argv[1]);
$searchString = strtolower(trim($argv[2]));

if (strlen($searchString) < 2) {
    error("La recherche doit contenir au moins 2 caractères");
    exit(1);
}

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: '$searchString'");
    info("Champs: username, nom, prénom, secteur\n");

    // Récupérer les utilisateurs avec sect_name (en clair) et first_name (en clair)
    // On peut filtrer directement sur ces deux champs
    $stmt = $pdo->prepare("
        SELECT
            u.id,
            u.encrypted_user_name,
            u.encrypted_email,
            u.encrypted_name,
            u.first_name,
            u.sect_name,
            u.fk_role,
            u.fk_entite,
            r.libelle as role_name,
            e.encrypted_name as entite_encrypted_name
        FROM users u
        LEFT JOIN x_users_roles r ON u.fk_role = r.id
        LEFT JOIN entites e ON u.fk_entite = e.id
        WHERE LOWER(u.first_name) LIKE :search1
           OR LOWER(u.sect_name) LIKE :search2
        ORDER BY u.id
    ");

    $searchPattern = '%' . $searchString . '%';
    $stmt->execute([
        'search1' => $searchPattern,
        'search2' => $searchPattern
    ]);

    $preFilteredUsers = $stmt->fetchAll();

    // Récupérer TOUS les utilisateurs pour chercher dans les champs chiffrés
    $stmtAll = $pdo->query("
        SELECT
            u.id,
            u.encrypted_user_name,
            u.encrypted_email,
            u.encrypted_name,
            u.first_name,
            u.sect_name,
            u.fk_role,
            u.fk_entite,
            r.libelle as role_name,
            e.encrypted_name as entite_encrypted_name
        FROM users u
        LEFT JOIN x_users_roles r ON u.fk_role = r.id
        LEFT JOIN entites e ON u.fk_entite = e.id
        ORDER BY u.id
    ");

    $allUsers = $stmtAll->fetchAll();

    info("Analyse de " . count($allUsers) . " utilisateurs...\n");

    // Déchiffrer et filtrer
    $config = DatabaseConfig::getInstance();
    $crypto = new CryptoService($config->getEncryptionKey());

    $matchedUsers = [];
    $seenIds = [];

    // Ajouter d'abord les résultats pré-filtrés (sect_name, first_name)
    foreach ($preFilteredUsers as $user) {
        $username = $crypto->decryptSearchable($user['encrypted_user_name']);
        $name = $crypto->decryptWithIV($user['encrypted_name']);

        // Vérifier aussi dans les champs chiffrés
        $matches = false;
        $matchedFields = [];

        if (stripos($user['first_name'], $searchString) !== false) {
            $matches = true;
            $matchedFields[] = 'prénom';
        }
        if (stripos($user['sect_name'], $searchString) !== false) {
            $matches = true;
            $matchedFields[] = 'secteur';
        }
        if ($username && stripos($username, $searchString) !== false) {
            $matches = true;
            $matchedFields[] = 'username';
        }
        if ($name && stripos($name, $searchString) !== false) {
            $matches = true;
            $matchedFields[] = 'nom';
        }

        if ($matches) {
            $matchedUsers[] = [
                'id' => $user['id'],
                'username' => $username ?? '-',
                'prenom' => $user['first_name'] ?? '-',
                'nom' => $name ?? '-',
                'secteur' => $user['sect_name'] ?? '-',
                'role' => $user['role_name'] ?? '-',
                'entite' => $crypto->decryptWithIV($user['entite_encrypted_name']) ?? '-',
                'matched_in' => implode(', ', $matchedFields),
            ];
            $seenIds[$user['id']] = true;
        }
    }

    // Chercher dans les utilisateurs restants (pour username et nom chiffrés)
    foreach ($allUsers as $user) {
        if (isset($seenIds[$user['id']])) {
            continue; // Déjà trouvé
        }

        $username = $crypto->decryptSearchable($user['encrypted_user_name']);
        $name = $crypto->decryptWithIV($user['encrypted_name']);

        $matches = false;
        $matchedFields = [];

        if ($username && stripos($username, $searchString) !== false) {
            $matches = true;
            $matchedFields[] = 'username';
        }
        if ($name && stripos($name, $searchString) !== false) {
            $matches = true;
            $matchedFields[] = 'nom';
        }

        if ($matches) {
            $matchedUsers[] = [
                'id' => $user['id'],
                'username' => $username ?? '-',
                'prenom' => $user['first_name'] ?? '-',
                'nom' => $name ?? '-',
                'secteur' => $user['sect_name'] ?? '-',
                'role' => $user['role_name'] ?? '-',
                'entite' => $crypto->decryptWithIV($user['entite_encrypted_name']) ?? '-',
                'matched_in' => implode(', ', $matchedFields),
            ];
            $seenIds[$user['id']] = true;
        }
    }

    if (empty($matchedUsers)) {
        warning("\nAucun utilisateur trouvé avec: '$searchString'");
        exit(0);
    }

    // Affichage
    title("RÉSULTATS DE LA RCAHERCHE - " . count($matchedUsers) . " utilisateur(s) trouvé(s)");

    // Préparer les données pour le tableau
    $tableData = [];
    foreach ($matchedUsers as $user) {
        $tableData[] = [
            'id' => $user['id'],
            'username' => truncate($user['username'], 20),
            'prenom' => truncate($user['prenom'], 15),
            'nom' => truncate($user['nom'], 20),
            'secteur' => truncate($user['secteur'], 15),
            'role' => truncate($user['role'], 12),
            'match' => $user['matched_in'],
        ];
    }

    table(
        [
            'id' => 'ID',
            'username' => 'Username',
            'prenom' => 'Prénom',
            'nom' => 'Nom',
            'secteur' => 'Secteur',
            'role' => 'Rôle',
            'match' => 'Trouvé dans',
        ],
        $tableData,
        true
    );

    success("Recherche terminée");

    // Proposer d'afficher les détails complets
    if (count($matchedUsers) === 1) {
        echo "\n";
        if (confirm("Afficher les détails complets de cet utilisateur ?")) {
            echo "\n";
            $userId = $matchedUsers[0]['id'];
            $decryptUserScript = __DIR__ . '/decrypt-user';
            passthru("$decryptUserScript $environment $userId");
        }
    } elseif (count($matchedUsers) > 1 && count($matchedUsers) <= 10) {
        echo "\n";
        if (confirm("Afficher les détails d'un utilisateur spécifique ?")) {
            echo color("\nEntrez l'ID de l'utilisateur: ", 'yellow');
            $handle = fopen('php://stdin', 'r');
            $userId = trim(fgets($handle));
            fclose($handle);

            if (is_numeric($userId) && (int)$userId > 0) {
                echo "\n";
                $decryptUserScript = __DIR__ . '/decrypt-user';
                passthru("$decryptUserScript $environment $userId");
            }
        }
    }

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