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

declare(strict_types=1);

/**
 * Script de recherche d'entité par nom/adresse/ville/email
 * Usage: ./search-entite <environment> <search_term>
 */

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_term>");
    error("Exemple: " . basename($argv[0]) . " dva plumeliau");
    error("Exemple: " . basename($argv[0]) . " rca amicale");
    exit(1);
}

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

if (strlen($searchTerm) < 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: \"$searchTerm\"");
    info("Champs: nom, email, adresse1, adresse2, ville\n");

    // Pré-filtrage sur les champs en clair (adresse1, adresse2, ville)
    $stmt = $pdo->prepare("
        SELECT
            e.id,
            e.encrypted_name,
            e.encrypted_email,
            e.adresse1,
            e.adresse2,
            e.code_postal,
            e.ville,
            e.chk_stripe,
            COUNT(DISTINCT u.id) as nb_users,
            COUNT(DISTINCT o.id) as nb_operations
        FROM entites e
        LEFT JOIN users u ON u.fk_entite = e.id
        LEFT JOIN operations o ON o.fk_entite = e.id
        WHERE e.chk_active = 1
          AND (LOWER(e.adresse1) LIKE :search1
           OR LOWER(e.adresse2) LIKE :search2
           OR LOWER(e.ville) LIKE :search3)
        GROUP BY e.id
        ORDER BY e.id
    ");

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

    $preFilteredEntites = $stmt->fetchAll();

    // Récupérer TOUTES les entités pour chercher dans les champs chiffrés
    $stmtAll = $pdo->query("
        SELECT
            e.id,
            e.encrypted_name,
            e.encrypted_email,
            e.adresse1,
            e.adresse2,
            e.code_postal,
            e.ville,
            e.chk_stripe,
            COUNT(DISTINCT u.id) as nb_users,
            COUNT(DISTINCT o.id) as nb_operations
        FROM entites e
        LEFT JOIN users u ON u.fk_entite = e.id
        LEFT JOIN operations o ON o.fk_entite = e.id
        WHERE e.chk_active = 1
        GROUP BY e.id
        ORDER BY e.id
    ");

    $allEntites = $stmtAll->fetchAll();

    info("Analyse de " . count($allEntites) . " entités actives...\n");

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

    $matchedEntites = [];
    $seenIds = [];

    // Ajouter d'abord les résultats pré-filtrés (adresse1, adresse2, ville)
    foreach ($preFilteredEntites as $entite) {
        $name = $crypto->decryptWithIV($entite['encrypted_name']);
        $email = $crypto->decryptSearchable($entite['encrypted_email']);

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

        if (stripos($entite['adresse1'], $searchTerm) !== false) {
            $matches = true;
            $matchedFields[] = 'adresse1';
        }
        if (stripos($entite['adresse2'], $searchTerm) !== false) {
            $matches = true;
            $matchedFields[] = 'adresse2';
        }
        if (stripos($entite['ville'], $searchTerm) !== false) {
            $matches = true;
            $matchedFields[] = 'ville';
        }
        if ($name && stripos($name, $searchTerm) !== false) {
            $matches = true;
            $matchedFields[] = 'nom';
        }
        if ($email && stripos($email, $searchTerm) !== false) {
            $matches = true;
            $matchedFields[] = 'email';
        }

        if ($matches) {
            $matchedEntites[] = [
                'id' => $entite['id'],
                'name' => $name ?? '-',
                'email' => $email ?? '-',
                'adresse1' => $entite['adresse1'] ?? '-',
                'code_postal' => $entite['code_postal'] ?? '-',
                'ville' => $entite['ville'] ?? '-',
                'stripe' => $entite['chk_stripe'] ? 'Oui' : 'Non',
                'nb_users' => $entite['nb_users'],
                'nb_operations' => $entite['nb_operations'],
                'matched_in' => implode(', ', $matchedFields),
            ];
            $seenIds[$entite['id']] = true;
        }
    }

    // Chercher dans les entités restantes (pour nom et email chiffrés)
    foreach ($allEntites as $entite) {
        if (isset($seenIds[$entite['id']])) {
            continue; // Déjà trouvé
        }

        $name = $crypto->decryptWithIV($entite['encrypted_name']);
        $email = $crypto->decryptSearchable($entite['encrypted_email']);

        $matches = false;
        $matchedFields = [];

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

        if ($matches) {
            $matchedEntites[] = [
                'id' => $entite['id'],
                'name' => $name ?? '-',
                'email' => $email ?? '-',
                'adresse1' => $entite['adresse1'] ?? '-',
                'code_postal' => $entite['code_postal'] ?? '-',
                'ville' => $entite['ville'] ?? '-',
                'stripe' => $entite['chk_stripe'] ? 'Oui' : 'Non',
                'nb_users' => $entite['nb_users'],
                'nb_operations' => $entite['nb_operations'],
                'matched_in' => implode(', ', $matchedFields),
            ];
            $seenIds[$entite['id']] = true;
        }
    }

    if (empty($matchedEntites)) {
        warning("\nAucune entité trouvée avec: \"$searchTerm\"");
        exit(0);
    }

    // Affichage
    title("RÉSULTATS - " . count($matchedEntites) . " entité(s) trouvée(s)");

    // Préparer les données pour le tableau
    $tableData = [];
    $lineNumber = 1;
    foreach ($matchedEntites as $entite) {
        $tableData[] = [
            'line' => $lineNumber++,
            'id' => $entite['id'],
            'name' => truncate($entite['name'], 30),
            'ville' => truncate($entite['ville'], 20),
            'cp' => $entite['code_postal'],
            'users' => $entite['nb_users'],
            'ops' => $entite['nb_operations'],
            'stripe' => $entite['stripe'],
            'match' => $entite['matched_in'],
        ];
    }

    table(
        [
            'line' => '#',
            'id' => 'ID',
            'name' => 'Nom',
            'ville' => 'Ville',
            'cp' => 'CP',
            'users' => 'Users',
            'ops' => 'Ops',
            'stripe' => 'Stripe',
            'match' => 'Trouvé dans',
        ],
        $tableData,
        true
    );

    success("Recherche terminée");

    // Menu interactif
    if (count($matchedEntites) > 0) {
        echo "\n";
        echo color("═══════════════════════════════════════\n", 'cyan');
        echo color("  Actions disponibles\n", 'bold');
        echo color("═══════════════════════════════════════\n", 'cyan');
        echo "  1. Détail d'une entité\n";
        echo "  2. Opérations d'une entité\n";
        echo "  3. Membres d'une entité\n";
        echo "  0. Quitter\n";
        echo color("═══════════════════════════════════════\n", 'cyan');

        echo color("\nVotre choix: ", 'yellow');
        $handle = fopen('php://stdin', 'r');
        $choice = fgets($handle);
        $choice = $choice !== false ? trim($choice) : '';

        if ($choice === '0' || $choice === '') {
            echo "\n";
            info("Au revoir !");
            exit(0);
        }

        // Demander le numéro de ligne (sauf si une seule trouvée)
        $entiteId = null;
        if (count($matchedEntites) === 1) {
            $entiteId = $matchedEntites[0]['id'];
            info("\nEntité sélectionnée: #$entiteId - " . $matchedEntites[0]['name']);
        } else {
            echo color("\nEntrez le n° de ligne (1-" . count($matchedEntites) . "): ", 'yellow');
            $lineInput = trim(fgets($handle));

            if (!is_numeric($lineInput) || (int)$lineInput < 1 || (int)$lineInput > count($matchedEntites)) {
                fclose($handle);
                error("Numéro de ligne invalide (doit être entre 1 et " . count($matchedEntites) . ")");
                exit(1);
            }

            $lineNumber = (int)$lineInput;
            $entiteId = $matchedEntites[$lineNumber - 1]['id'];
            info("\nEntité sélectionnée: #$entiteId - " . $matchedEntites[$lineNumber - 1]['name']);
        }

        fclose($handle);
        echo "\n";

        // Exécuter l'action choisie
        switch ($choice) {
            case '1':
                // Détail de l'entité
                $decryptEntiteScript = __DIR__ . '/decrypt-entite';
                passthru("$decryptEntiteScript $environment $entiteId");
                break;

            case '2':
                // Opérations de l'entité
                $listOperationsScript = __DIR__ . '/list-operations';
                passthru("$listOperationsScript $environment --entite=$entiteId");
                break;

            case '3':
                // Membres de l'entité
                $listUsersScript = __DIR__ . '/list-users';
                passthru("$listUsersScript $environment --entite=$entiteId");
                break;

            default:
                error("Choix invalide: $choice");
                exit(1);
        }
    }

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