<?php
if ( ! defined( 'ABSPATH' ) ) exit;

add_action('wp_ajax_wpkginst_get_stats', 'wpkginst_ajax_get_stats');

function wpkginst_ajax_get_stats() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error('Interdit');
    }

    $stats = wpkginst_get_system_stats_data();
    wp_send_json_success($stats);
}

/**
 * Récupère le statut de tous les paquets PHP définis.
 */
function wpkginst_fetch_packages() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => __('Permissions insuffisantes.', 'package-installator')]);
    }

    $packages = [
        'php-xml', 'php-mbstring', 'php-curl', 'php-mysql', 'php-gd', 'php-imagick',
        'php-zip', 'php-intl', 'php-bcmath', 'php-soap', 'php-redis', 'php-memcached',
        'php-json', 'php-opcache', 'php-apcu', 'php-uuid', 'php-pgsql', 'php-sqlite3',
        'php-ldap', 'php-imap'
    ];

    $result = [];
    foreach ($packages as $package) {
        // Nettoyage des transients obsolètes
        delete_transient('wpkginst_progress_' . $package);
        delete_transient('wpkginst_output_' . $package);
        delete_transient('wpkginst_installed_' . $package);

        $status = wpkginst_get_package_status($package);
        $result[] = [
            'name'      => $package,
            'installed' => (bool)$status['installed'],
            'message'   => $status['message'] ?? ''
        ];
    }

    wp_send_json_success(['packages' => $result]);
}
add_action('wp_ajax_wpkginst_fetch_packages', 'wpkginst_fetch_packages');

/**
 * Installe un paquet via SSH.
 */
function wpkginst_install_package() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => __('Non autorisé.', 'package-installator')]);
    }

    $package = isset($_POST['package']) ? sanitize_text_field(wp_unslash($_POST['package'])) : '';
    if (empty($package)) {
        wp_send_json_error(['message' => __('Paquet non spécifié.', 'package-installator')]);
    }

    $mapping     = wpkginst_get_os_commands_mapping();
    $update_cmd  = $mapping['update'];
    $install_cmd = $mapping['install'];
    $sudo        = (get_option('wpkginst_ssh_username') === 'root') ? '' : 'sudo ';

    $package_esc = escapeshellarg($package);
    $command     = "{$sudo}{$update_cmd} && {$sudo}{$install_cmd} $package_esc 2>&1";

    $result = wpkginst_execute_ssh_background($command, 'install_' . $package);

    if (!$result['success']) {
        wp_send_json_error(['message' => $result['message']]);
    }

    $status = wpkginst_get_package_status($package);
    set_transient('wpkginst_pid_' . $package, $result['pid'], HOUR_IN_SECONDS);
    wp_send_json_success([
        'background' => true,
        'log_file'   => $result['log'], // C'est CA que le JS doit surveiller
        'package'    => $package
        //'installed'  => false          // On ne sait pas encore s'il est installé
    ]);

}
add_action('wp_ajax_wpkginst_install_package', 'wpkginst_install_package');

/**
 * Désinstalle un paquet via SSH.
 */
function wpkginst_uninstall_package() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => __('Non autorisé.', 'package-installator')]);
    }

    $package = isset($_POST['package']) ? sanitize_text_field(wp_unslash($_POST['package'])) : '';
    if (empty($package)) {
        wp_send_json_error(['message' => __('Paquet non spécifié.', 'package-installator')]);
    }

    $mapping = wpkginst_get_os_commands_mapping();
    $sudo    = (get_option('wpkginst_ssh_username') === 'root') ? '' : 'sudo ';

    $package_esc = escapeshellarg($package);
    // On récupère la commande de suppression du mapping
    $command     = "{$sudo}{$mapping['remove']} $package_esc 2>&1";

    // ON PASSE EN BACKGROUND ICI (Identifiant : uninstall_)
    $result = wpkginst_execute_ssh_background($command, 'uninstall_' . $package);

    if (!$result['success']) {
        wp_send_json_error(['message' => $result['message']]);
    }

    // ON STOCKÉ LE PID POUR LE POLLING
    set_transient('wpkginst_pid_' . $package, $result['pid'], HOUR_IN_SECONDS);

    wp_send_json_success([
        'background' => true,
        'log_file'   => $result['log'],
        'package'    => $package
    ]);
}
/*function wpkginst_uninstall_package() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => __('Non autorisé.', 'package-installator')]);
    }

    $package = isset($_POST['package']) ? sanitize_text_field(wp_unslash($_POST['package'])) : '';
    if (empty($package)) {
        wp_send_json_error(['message' => __('Paquet non spécifié.', 'package-installator')]);
    }

    $mapping = wpkginst_get_os_commands_mapping();
    $sudo    = (get_option('wpkginst_ssh_username') === 'root') ? '' : 'sudo ';

    $package_esc = escapeshellarg($package);
    $command     = "{$sudo}{$mapping['remove']} $package_esc 2>&1";

    $result = wpkginst_execute_ssh_command($command);

    if (!$result['success']) {
        wp_send_json_error(['message' => $result['message']]);
    }

    wp_send_json_success([
        'output'    => $result['output'],
        'installed' => false
    ]);
}*/
add_action('wp_ajax_wpkginst_uninstall_package', 'wpkginst_uninstall_package');

/**
 * Récupère la liste des containers Docker au format JSON.
 */
function wpkginst_fetch_docker_containers() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error();
    }

    $command = 'docker ps -a --format "{{json .}}"';
    $result  = wpkginst_execute_ssh_command($command);

    // Normalisation de l'output (doit être une string)
    $output = is_array($result) ? ($result['output'] ?? '') : (string)$result;

    if (empty(trim($output))) {
        wp_send_json_success(['containers' => []]);
        return;
    }

    $lines = explode("\n", trim($output));
    $containers = [];

    foreach ($lines as $line) {
        $decoded = json_decode(trim($line), true);
        if ($decoded) {
            $containers[] = $decoded;
        }
    }

    wp_send_json_success(['containers' => $containers]);
}
add_action('wp_ajax_wpkginst_fetch_docker_containers', 'wpkginst_fetch_docker_containers');

/**
 * Actions Docker (start/stop/restart) avec validation stricte.
 */
function wpkginst_docker_action() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => __('Accès refusé.', 'package-installator')]);
    }

	$id = isset($_POST['id']) ? sanitize_text_field(wp_unslash($_POST['id'])) : '';
	$docker_action = isset($_POST['docker_action']) ? sanitize_text_field(wp_unslash($_POST['docker_action'])) : '';

    // Whitelist des actions autorisées
    $allowed_actions = ['start', 'stop', 'restart'];
    if (!in_array($docker_action, $allowed_actions, true)) {
        wp_send_json_error(['message' => __('Action Docker non autorisée.', 'package-installator')]);
    }

    // Sécurisation de l'ID pour la commande SSH
    $safe_id = escapeshellarg($id);
    $command = "docker $docker_action $safe_id 2>&1";

    $result = wpkginst_execute_ssh_command($command);

    if ($result['success']) {
		/* translators: %s: Type d'action Docker (ex: start, stop, restart) */
        wp_send_json_success(['message' => sprintf(__('Container %s effectué avec succès.', 'package-installator'), $docker_action)]);
    } else {
        wp_send_json_error(['message' => $result['message']]);
    }
}
add_action('wp_ajax_wpkginst_docker_action', 'wpkginst_docker_action');

/**
 * Test de connexion SSH.
 */
function wpkginst_local_test_ssh_connection() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => __('Permission refusée.', 'package-installator')]);
    }

    $result = wpkginst_test_ssh_connection();
    wp_send_json($result);
}
add_action('wp_ajax_wpkginst_test_ssh_connection', 'wpkginst_local_test_ssh_connection');

/**
 * Tente de corriger un outil système manquant (ex: Ansible)
 */
function wpkginst_ajax_fix_readiness() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => __('Accès refusé.', 'package-installator')]);
    }

    $tool_key = isset($_POST['tool_key']) ? sanitize_text_field(wp_unslash($_POST['tool_key'])) : '';

    // On récupère la liste des commandes via ton checker système
    $readiness = wpkginst_get_automation_readiness();

    if (!isset($readiness[$tool_key]) || empty($readiness[$tool_key]['install_cmd'])) {
        wp_send_json_error(['message' => __('Outil inconnu ou non automatisable.', 'package-installator')]);
    }

    $command = $readiness[$tool_key]['install_cmd'];
    $result  = wpkginst_execute_ssh_command($command);

    if ($result['success']) {
        delete_transient('wpkginst_readiness');
        wp_send_json_success([
            'output'  => $result['output'],
            /* translators: %s: Tool name e.g. Docker, Git */
            'message' => sprintf(__('%s installed successfully.', 'package-installator'), $tool_key)
        ]);
    } else {
        wp_send_json_error(['message' => $result['message']]);
    }
}
add_action('wp_ajax_wpkginst_fix_readiness', 'wpkginst_ajax_fix_readiness');

/**
 * AJAX : Lancement de la grue (Sync Catalog)
 */
add_action('wp_ajax_wpkginst_sync_catalog', 'wpkginst_ajax_sync_catalog');
function wpkginst_ajax_sync_catalog() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error('Interdit');
    }

    // On appelle la logique située dans automation-handler.php
    $result = wpkginst_sync_automation_catalog();

    if ($result['success']) {
        wp_send_json_success($result);
    } else {
        wp_send_json_error($result);
    }
}

/**
 * AJAX : Retourne la liste des playbooks chargés depuis le manifest.json
 */
function wpkginst_ajax_get_ansible_catalog() {
    check_ajax_referer('wpkginst_nonce', 'nonce');
    if (!current_user_can('manage_options')) wp_send_json_error();

    $folder_name = get_option('wpkginst_automation_folder_name', 'wp-playbooks');
    $target_dir  = '/tmp/' . $folder_name;

    // On vérifie physiquement si le dossier existe via SSH
    $check = wpkginst_execute_ssh_command("[ -d \"$target_dir\" ] && echo 'OK' || echo 'KO'");

    // Extraction sécurisée de l'output
    $output = '';
    if (is_array($check) && isset($check['output'])) {
        $output = trim((string)$check['output']);
    } elseif (is_string($check)) {
        $output = trim($check);
    }

    $dir_exists = ($output === 'OK');

    if (!$dir_exists) {
        // C'est cette erreur que le JS va surveiller
        wp_send_json_error([
            'code'    => 'FOLDER_MISSING',
            'message' => 'Le dossier de travail est absent.'
        ]);
        exit;
    }

    // Si le dossier existe, on tente de lire le catalogue
    $sync = wpkginst_sync_automation_catalog();

    if ($sync['success']) {
        wp_send_json_success(['packages' => $sync['packages']]);
    } else {
        wp_send_json_error(['message' => $sync['message']]);
    }
}
add_action('wp_ajax_wpkginst_get_ansible_catalog', 'wpkginst_ajax_get_ansible_catalog');

/**
 * AJAX : Exécute un playbook spécifique
 */
function wpkginst_ajax_run_playbook() {
    check_ajax_referer('wpkginst_nonce', 'nonce');
    if (!current_user_can('manage_options')) wp_send_json_error();

    $playbook_file = isset($_POST['playbook']) ? sanitize_text_field(wp_unslash($_POST['playbook'])) : '';
    if (empty($playbook_file)) {
        wp_send_json_error(['message' => 'Fichier playbook manquant.']);
    }

    $folder_name = get_option('wpkginst_automation_folder_name', 'wp-playbooks');
    $target_path = "/tmp/$folder_name/" . $playbook_file;

    // Commande pour lancer Ansible
    // On ajoute -i localhost, pour forcer l'exécution locale sur la cible SSH
    $command = "ansible-playbook " . escapeshellarg($target_path) . " -i localhost, -c local 2>&1";

    $result = wpkginst_execute_ssh_background($command, 'playbook_' . sanitize_title($playbook_file));

    if ($result['success']) {
        wp_send_json_success([
            'message'  => 'Playbook lancé en arrière-plan',
            'pid'      => $result['pid'],
            'log_file' => $result['log'] // INDISPENSABLE pour le JS
        ]);
    } else {
        wp_send_json_error([
            'message' => $result['message'],
            'output'  => $result['output'] ?? ''
        ]);
    }
}
add_action('wp_ajax_wpkginst_run_playbook', 'wpkginst_ajax_run_playbook');

/**
 * AJAX : Lit le contenu d'un log généré par nohup.
 * Nom fixe : wpkginst_get_background_log
 */
/*function wpkginst_ajax_get_background_log() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    $log_file = isset($_POST['log_file']) ? sanitize_text_field($_POST['log_file']) : '';
    $package  = isset($_POST['package']) ? sanitize_text_field($_POST['package']) : '';

    // On récupère le PID (il faudrait idéalement le stocker en transient lors du lancement)
    $pid = get_transient("wpkginst_pid_" . $package);

    // Vérification universelle : est-ce que le processus existe encore ?
    $is_running = false;
    if ($pid) {
        $check_pid = wpkginst_execute_ssh_command("ps -p $pid > /dev/null && echo 'RUNNING'");
        $is_running = (trim($check_pid['output']) === 'RUNNING');
    }

    $res = wpkginst_execute_ssh_command("tail -n 50 " . escapeshellarg($log_file));

    wp_send_json_success([
        'output'   => $res['output'],
        'finished' => !$is_running // Si ça ne tourne plus, c'est que c'est fini
    ]);
}*/
add_action('wp_ajax_wpkginst_get_background_log', 'wpkginst_ajax_get_background_log');
/**
 * AJAX : Lit le log et vérifie si le processus SSH est toujours actif via son PID.
 */
function wpkginst_ajax_get_background_log() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error('Interdit');
    }

    $log_file = isset($_POST['log_file']) ? sanitize_text_field(wp_unslash($_POST['log_file'])) : '';
    $package  = isset($_POST['package']) ? sanitize_text_field(wp_unslash($_POST['package'])) : '';

    // 1. On récupère le PID stocké lors du lancement de l'install
    $pid = get_transient("wpkginst_pid_" . $package);

    // 2. On vérifie si le processus tourne encore (Universal Linux check)
    $is_running = false;
    if ($pid) {
        // ps -p renvoie un code retour 0 si le PID existe, d'où le && echo
        $check_pid = wpkginst_execute_ssh_command("ps -p $pid > /dev/null && echo 'RUNNING'");
        $is_running = (isset($check_pid['output']) && trim($check_pid['output']) === 'RUNNING');

        // Si c'est fini, on nettoie le transient pour ne pas polluer la DB
        if (!$is_running) {
            delete_transient("wpkginst_pid_" . $package);
        }
    }

    // 3. On lit les dernières lignes du log (limité à 50 pour ne pas saturer l'AJAX)
    $output = "";
    if (!empty($log_file) && strpos($log_file, '/tmp/wpkginst_') === 0) {
        $res = wpkginst_execute_ssh_command("tail -n 50 " . escapeshellarg($log_file));
        $output = $res['success'] ? $res['output'] : "Impossible de lire le log.";
    }

    wp_send_json_success([
        'output'   => $output,
        'finished' => !$is_running, // Dit au JS d'arrêter le setInterval
        'package'  => $package
    ]);
}
/*function wpkginst_ajax_get_background_log() {
    check_ajax_referer('wpkginst_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error('Interdit');
    }

    $log_file = isset($_POST['log_file']) ? sanitize_text_field(wp_unslash($_POST['log_file'])) : '';

    // Sécurité : on n'autorise la lecture que des fichiers créés par notre plugin dans /tmp
    if (!empty($log_file) && strpos($log_file, '/tmp/wpkginst_') === 0) {

        // On utilise TA fonction synchrone habituelle pour lire le log
        $res = wpkginst_execute_ssh_command("tail -n 50 " . escapeshellarg($log_file));

        wp_send_json_success([
            'output' => $res['success'] ? $res['output'] : '',
            'file'   => $log_file
        ]);
    }

    wp_send_json_error('Log non trouvé ou chemin invalide');
}*/
