<?php
/**
 * Plugin Uninstaller for BotFend Anti-Bot Firewall
 *
 * Handles complete removal when the plugin is uninstalled.
 * Respects the "remove_data_on_uninstall" setting.
 *
 * @package BotFend\Core
 * @version 4.8.3 - Rebranded from SafeBot, file storage location fixed
 */

namespace BotFend\Core;

defined('ABSPATH') || exit;

/**
 * Class Uninstaller
 */
class Uninstaller {

    /**
     * Get the plugin data directory path (using WordPress uploads directory)
     * FIXED: No longer uses WP_CONTENT_DIR directly
     *
     * @return string
     */
    private function get_data_dir(): string {
        $upload_dir = wp_upload_dir();
        return $upload_dir['basedir'] . '/botfend-anti-bot-firewall/';
    }

    /**
     * Get the old log directory path (for cleanup during upgrade)
     *
     * @return string
     */
    private function get_old_log_dir(): string {
        return WP_CONTENT_DIR . '/botfend-logs/';
    }

    /**
     * Entry point for uninstallation.
     */
    public function uninstall(): void {
        // 1. Security Check - only allow during uninstall
        if (!defined('WP_UNINSTALL_PLUGIN')) {
            return;
        }
        
        if (!current_user_can('activate_plugins')) {
            return;
        }

        try {
            // 2. Determine Scope
            $config = Config::get_instance();
            $remove_all_data = $config->get_bool('remove_data_on_uninstall', false);

            if ($remove_all_data) {
                $this->purge_all_data();
            } else {
                $this->clean_system_footprint();
            }

            // 3. Always Flush Caches
            $this->flush_caches();
            $this->log_uninstall();

            do_action('botfend_defender_uninstalled');

        } catch (\Throwable $e) {
            error_log('BotFend Anti-Bot Firewall Uninstall Error: ' . $e->getMessage());
        }
    }

    /**
     * Total Purge: Tables, Options, Meta, Files
     * Complete removal of all plugin data
     */
    private function purge_all_data(): void {
        $this->drop_database_tables();
        $this->delete_all_options();
        $this->delete_user_meta();
        $this->remove_firewall_directory(); // Remove firewall files on full purge
        $this->clean_system_footprint(); // Files, Cron, Htaccess
    }

    /**
     * Surface Clean: Removes hooks and rules, but leaves data for future reinstall.
     * Preserves all data - ideal for temporary deactivation
     */
    private function clean_system_footprint(): void {
        $this->delete_cron_jobs();
        $this->remove_htaccess_rules();
        $this->remove_firewall_directives(); // Remove directives but keep files
        $this->remove_temporary_files();
    }

    /**
     * Database Table Removal
     */
    private function drop_database_tables(): void {
        global $wpdb;

        // Use core database handler if available
        if (class_exists('BotFend\Database\Database')) {
            (new \BotFend\Database\Database())->drop_tables();
        }

        // Extra tables that might exist (using botfend prefix)
        $extra_tables = [
            $wpdb->prefix . 'botfend_fingerprints',
            $wpdb->prefix . 'botfend_dedup_queue',
            $wpdb->prefix . 'botfend_session_data',
            $wpdb->prefix . 'botfend_system_logs',
        ];

        foreach ($extra_tables as $table) {
            $wpdb->query("DROP TABLE IF EXISTS `$table`");
        }
    }

    /**
     * Option Cleanup using direct SQL for "botfend_" prefix
     */
    private function delete_all_options(): void {
        global $wpdb;
        
        // Delete all options with botfend_ prefix
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'botfend_%'");
        
        // Also delete any transients that might have been missed
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_botfend_%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_botfend_%'");
    }

    /**
     * User Meta Cleanup
     */
    private function delete_user_meta(): void {
        global $wpdb;
        $wpdb->query("DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE 'botfend_%'");
    }

    /**
     * Cron Cleanup
     */
    private function delete_cron_jobs(): void {
        $hooks = [
            'botfend_daily_maintenance',
            'botfend_update_threat_intel',
            'botfend_update_tor_nodes',
            'botfend_auto_unblock',
            'botfend_import_tor_nodes',
            'botfend_file_guard_weekly',
            'botfend_file_guard_daily',
            'botfend_cleanup_transients',
            'botfend_cleanup_sessions',
            'botfend_fingerprint_cleanup',
            'botfend_calculate_enhanced_attack_level',
            'botfend_update_threat_feeds',
            'botfend_preload_threat_feeds',
        ];

        foreach ($hooks as $hook) {
            wp_clear_scheduled_hook($hook);
        }
    }

    /**
     * Rule Removal (.htaccess / web.config)
     */
    private function remove_htaccess_rules(): void {
        $upload_dir = wp_upload_dir();
        $path = $upload_dir['basedir'];

        // Clean .htaccess
        $htaccess = $path . '/.htaccess';
        if (file_exists($htaccess) && is_writable($htaccess)) {
            $content = file_get_contents($htaccess);
            $pattern = '/# BotFend Anti-Bot Firewall Multi-Layer Protection.*?# End BotFend Anti-Bot Firewall/s';
            $new_content = preg_replace($pattern, '', $content);
            $new_content = trim($new_content);
            file_put_contents($htaccess, $new_content);
        }

        // Remove web.config entirely if BotFend managed
        $web_config = $path . '/web.config';
        if (file_exists($web_config)) {
            $content = file_get_contents($web_config);
            if (strpos($content, 'BotFend Anti-Bot Firewall') !== false) {
                @unlink($web_config);
            }
        }
    }

    /**
     * ============================================
     * FIREWALL UNINSTALL
     * ============================================
     */

    /**
     * Remove firewall directives from server configuration files
     * Called during surface clean (preserves files)
     *
     * @return void
     */
    private function remove_firewall_directives(): void {
        // 1. Clean up .user.ini
        $this->cleanup_user_ini_firewall();
        
        // 2. Clean up root .htaccess
        $this->cleanup_root_htaccess_firewall();
        
        // 3. Clear firewall pending transient
        delete_transient('botfend_firewall_pending');
    }

    /**
     * Remove BotFend Anti-Bot Firewall directives from .user.ini
     *
     * @return void
     */
    private function cleanup_user_ini_firewall(): void {
        $user_ini_file = ABSPATH . '.user.ini';
        
        if (!file_exists($user_ini_file) || !is_writable($user_ini_file)) {
            return;
        }
        
        $content = file_get_contents($user_ini_file);
        if ($content === false) {
            return;
        }
        
        // Remove BotFend Anti-Bot Firewall lines
        $content = preg_replace('/^; BotFend Anti-Bot Firewall Firewall.*$/m', '', $content);
        $content = preg_replace('/^auto_prepend_file\s*=.*$/m', '', $content);
        $content = preg_replace("/\n{3,}/", "\n\n", trim($content));
        
        file_put_contents($user_ini_file, $content);
        
        // Clear opcache for the INI file
        if (function_exists('opcache_invalidate')) {
            opcache_invalidate($user_ini_file, true);
        }
    }

    /**
     * Remove BotFend Anti-Bot Firewall directives from root .htaccess
     *
     * @return void
     */
    private function cleanup_root_htaccess_firewall(): void {
        $htaccess_file = ABSPATH . '.htaccess';
        
        if (!file_exists($htaccess_file) || !is_writable($htaccess_file)) {
            return;
        }
        
        $content = file_get_contents($htaccess_file);
        if ($content === false) {
            return;
        }
        
        // Remove BotFend Anti-Bot Firewall firewall block
        $pattern = '/# BotFend Anti-Bot Firewall Firewall.*?# End BotFend Anti-Bot Firewall Firewall\n/s';
        $content = preg_replace($pattern, '', $content);
        
        file_put_contents($htaccess_file, $content);
    }

    /**
     * Remove the dedicated firewall directory
     * Called during full purge only (when remove_data_on_uninstall is true)
     *
     * @return void
     */
    private function remove_firewall_directory(): void {
        $firewall_dir = $this->get_data_dir() . 'firewall';
        
        if (!is_dir($firewall_dir)) {
            return;
        }
        
        // Also remove directives since we're deleting everything
        $this->remove_firewall_directives();
        
        // Recursively delete the firewall directory
        $this->recursive_delete($firewall_dir);
    }

    /**
     * ============================================
     * END FIREWALL UNINSTALL
     * ============================================
     */

    /**
     * Directory & File Removal
     * FIXED: Uses uploads directory instead of WP_CONTENT_DIR
     */
    private function remove_temporary_files(): void {
        // Remove plugin data directory from uploads
        $data_dir = $this->get_data_dir();
        if (is_dir($data_dir)) {
            $this->recursive_delete($data_dir);
        }

        // Remove old log directory from WP_CONTENT_DIR if it exists (legacy cleanup)
        $old_log_dir = $this->get_old_log_dir();
        if (is_dir($old_log_dir)) {
            $this->recursive_delete($old_log_dir);
        }

        // Remove index.php protection files from uploads if they exist and are BotFend's
        $upload_dir = wp_upload_dir();
        $index_file = $upload_dir['basedir'] . '/index.php';
        if (file_exists($index_file)) {
            $content = file_get_contents($index_file);
            if (strpos($content, 'BotFend Anti-Bot Firewall') !== false) {
                @unlink($index_file);
            }
        }
        
        // Remove any backup files created by FileGuard
        $backup_pattern = $upload_dir['basedir'] . '/*.botfend-backup';
        foreach (glob($backup_pattern) as $backup_file) {
            @unlink($backup_file);
        }
    }

    /**
     * Recursively delete a directory
     *
     * @param string $dir
     * @return void
     */
    private function recursive_delete(string $dir): void {
        if (!is_dir($dir)) {
            return;
        }
        
        $files = array_diff(scandir($dir), ['.', '..']);
        
        foreach ($files as $file) {
            $path = $dir . '/' . $file;
            if (is_dir($path)) {
                $this->recursive_delete($path);
            } else {
                @unlink($path);
            }
        }
        
        @rmdir($dir);
    }

    /**
     * Flush all caches
     */
    private function flush_caches(): void {
        $groups = ['botfend_defender', 'botfend_admin', 'botfend_config', 'botfend_sessions'];
        
        foreach ($groups as $group) {
            if (function_exists('wp_cache_flush_group')) {
                wp_cache_flush_group($group);
            }
        }
        
        // Clear config cache
        if (class_exists('BotFend\Core\Config')) {
            Config::get_instance()->clear_cache();
        }
        
        // Clear autoloader cache
        if (class_exists('BotFend\Core\Autoloader')) {
            Autoloader::clear_cache();
        }
    }

    /**
     * Log uninstall completion
     */
    private function log_uninstall(): void {
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('BotFend Anti-Bot Firewall: Uninstall complete.');
        }
    }
}