<?php
/**
 * Plugin Lifecycle — activation, deactivation, and uninstall hooks.
 *
 * Kept in a separate file so it can be loaded early (before the autoloader
 * is called for everything else) and to avoid cluttering the main plugin file.
 *
 * @package UltraguardPro
 */

namespace UltraguardPro;

if ( ! defined( 'ABSPATH' ) ) { exit; }

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange -- Lifecycle routines intentionally perform activation, uninstall, and schema maintenance queries.

require_once __DIR__ . '/core/class-database.php';
require_once __DIR__ . '/core/class-database-schema.php';

// ─── Shared Lifecycle Helpers ────────────────────────────────────────────────

/**
 * Run a callback inside each relevant site context for multisite operations.
 *
 * @param callable  $callback     Callback receiving current blog ID.
 * @param bool|null $network_wide Whether to iterate all network sites.
 * @return void
 */
function ultraguard_pro_for_each_site( callable $callback, ?bool $network_wide = null ): void {
    if ( ! is_multisite() || ! $network_wide ) {
        $callback( get_current_blog_id() );
        return;
    }

    $site_ids = get_sites(
        [
            'fields' => 'ids',
            'number' => 0,
        ]
    );

    foreach ( $site_ids as $site_id ) {
        switch_to_blog( (int) $site_id );
        try {
            $callback( (int) $site_id );
        } finally {
            restore_current_blog();
        }
    }
}

/**
 * Determine whether UltraGuard Pro is network-active.
 *
 * @return bool
 */
function ultraguard_pro_is_network_active(): bool {
    if ( ! is_multisite() ) {
        return false;
    }

    if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
        require_once ABSPATH . 'wp-admin/includes/plugin.php';
    }

    return function_exists( 'is_plugin_active_for_network' ) && is_plugin_active_for_network( ULTRAGUARD_PRO_BASENAME );
}

/**
 * Check whether the current user can manage plugin lifecycle actions in this context.
 *
 * @param string $single_cap  Single-site capability.
 * @param string $network_cap Multisite/network capability.
 * @return bool
 */
function ultraguard_pro_current_user_can_lifecycle( string $single_cap, string $network_cap ): bool {
    if ( current_user_can( $single_cap ) ) {
        return true;
    }

    return is_multisite() && current_user_can( $network_cap );
}

/**
 * Cleanup intent persisted from the deactivation questionnaire.
 */
function ultraguard_pro_get_cleanup_mode(): string {
    $mode = get_option( 'ultraguard_cleanup_on_uninstall', 'none' );

    if ( is_multisite() ) {
        $network_mode = get_site_option( 'ultraguard_cleanup_on_uninstall', '' );
        if ( in_array( $network_mode, [ 'soft', 'full' ], true ) ) {
            return $network_mode;
        }
    }

    return in_array( $mode, [ 'none', 'soft', 'full' ], true ) ? $mode : 'none';
}

function ultraguard_pro_set_cleanup_mode( string $mode ): void {
    $safe_mode = in_array( $mode, [ 'none', 'soft', 'full' ], true ) ? $mode : 'none';
    update_option( 'ultraguard_cleanup_on_uninstall', $safe_mode, false );

    if ( is_multisite() ) {
        update_site_option( 'ultraguard_cleanup_on_uninstall', $safe_mode );
    }
}

/**
 * Return all built-in module manifests sorted by priority.
 *
 * @return array<int, array<string, mixed>>
 */
function ultraguard_pro_get_builtin_module_manifests(): array {
    $manifests   = [];
    $modules_dir = __DIR__ . '/modules/';

    foreach ( glob( $modules_dir . '*/module.json' ) ?: [] as $json_file ) {
        $raw = file_get_contents( $json_file );
        if ( ! $raw ) {
            continue;
        }

        $manifest = json_decode( $raw, true );
        if ( ! is_array( $manifest ) || empty( $manifest['id'] ) || empty( $manifest['class'] ) ) {
            continue;
        }

        $manifest['id']       = sanitize_key( $manifest['id'] );
        $manifest['priority'] = (int) ( $manifest['priority'] ?? 50 );
        $manifests[]          = $manifest;
    }

    usort(
        $manifests,
        static function ( array $a, array $b ): int {
            return (int) ( $a['priority'] ?? 50 ) <=> (int) ( $b['priority'] ?? 50 );
        }
    );

    return $manifests;
}

/**
 * Seed safe default module settings for newer self-contained modules.
 *
 * Missing keys are added, existing user values are preserved.
 */
function ultraguard_pro_seed_default_module_settings(): array {
    $site_name = wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );
    if ( '' === $site_name ) {
        $site_name = (string) wp_parse_url( home_url(), PHP_URL_HOST );
    }

    $defaults = [
        'api_security' => [
            'api_security_enabled'           => true,
            'api_security_enable_xmlrpc'     => true,
            'api_security_default_rate_limit'=> 60,
        ],
        'two_factor' => [
            'two_factor_enabled'           => true,
            'two_factor_allow_self_enroll' => true,
            'two_factor_show_setup_prompt' => true,
            'two_factor_backup_code_count' => '8',
            'two_factor_issuer_name'       => $site_name ?: 'WordPress',
        ],
        'auto_updater' => [
            'auto_updater_plugins_enabled'    => true,
            'auto_updater_themes_enabled'     => true,
            'auto_updater_core_minor_enabled' => true,
            'auto_updater_core_major_enabled' => false,
        ],
        'notifications' => [
            'notifications_enabled'       => true,
            'notifications_email_enabled' => true,
        ],
        'filechecker' => [
            'filechecker_enabled' => true,
        ],
        'traffic_monitor' => [
            'traffic_monitor_enabled'          => true,
            'traffic_monitor_retention_days'   => 7,
            'traffic_monitor_ignore_logged_in' => true,
            'traffic_monitor_skip_localhost'   => true,
        ],
        'ip_intelligence' => [
            'ip_intelligence_enabled'                  => true,
            'ip_intelligence_enable_spamhaus'          => true,
            'ip_intelligence_enable_ultraguard_network'=> true,
        ],
        'reputation_monitor' => [
            'reputation_monitor_enabled'         => true,
            'reputation_monitor_enable_spamhaus' => true,
        ],
        'uptime_monitor' => [
            'uptime_monitor_enabled'    => true,
            'uptime_monitor_enable_ssl' => true,
        ],
        'vulnerability' => [
            'vulnerability_auto_scan'          => true,
            'vulnerability_virtual_patch'      => true,
            'vulnerability_notify_on_critical' => true,
        ],
        'woo_security' => [
            'woo_security_enabled' => true,
        ],
        'login_protect' => [
            'login_protect_enabled'              => true,
            'login_protect_log_attempts'         => true,
            'login_protect_auto_block'           => false,
            'login_protect_auto_block_threshold' => 5,
            'login_protect_notify_admin'         => false,
            'login_protect_original_action'      => '404',
        ],
    ];

    $seeded = [];

    foreach ( $defaults as $storage_key => $data ) {
        $option_key = 'ultraguard_' . $storage_key . '_settings';
        $existing   = (array) get_option( $option_key, [] );
        $merged     = $existing;
        $changed    = false;

        foreach ( $data as $key => $value ) {
            if ( ! array_key_exists( $key, $merged ) ) {
                $merged[ $key ] = $value;
                $changed        = true;
            }
        }

        if ( $changed ) {
            update_option( $option_key, $merged, false );
            $seeded[] = $storage_key;
        }
    }

    if ( class_exists( '\UltraguardPro\modules\settings\Settings' ) ) {
        try {
            \UltraguardPro\modules\settings\Settings::get_instance()->clear_cache();
        } catch ( \Throwable $e ) {
        }
    }

    return $seeded;
}

/**
 * Clear all scheduled UltraGuard hooks, including new module cron jobs.
 */
function ultraguard_pro_clear_all_cron_hooks(): array {
    $cleared = [];
    $cron    = _get_cron_array();

    if ( ! is_array( $cron ) ) {
        return $cleared;
    }

    foreach ( $cron as $timestamp => $hooks ) {
        if ( ! is_array( $hooks ) ) {
            continue;
        }

        foreach ( array_keys( $hooks ) as $hook ) {
            if ( 0 !== strpos( (string) $hook, 'ultraguard_' ) ) {
                continue;
            }

            wp_clear_scheduled_hook( $hook );
            $cleared[] = $hook;
        }
    }

    return array_values( array_unique( $cleared ) );
}

/**
 * Remove plugin-owned options and transient rows.
 */
function ultraguard_pro_remove_options_and_transients( bool $include_settings = true ): array {
    global $wpdb;

    $removed = [];

    $bare_enabled_options = [ 'loginlimiter_enabled', 'login_protect_enabled' ];
    foreach ( ultraguard_pro_get_builtin_module_manifests() as $manifest ) {
        $bare_enabled_options[] = sanitize_key( $manifest['id'] ) . '_enabled';
    }

    $bare_enabled_options = array_values( array_unique( $bare_enabled_options ) );

    if ( $include_settings ) {
        if ( ! empty( $bare_enabled_options ) ) {
            $placeholders = implode( ',', array_fill( 0, count( $bare_enabled_options ), '%s' ) );
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- query uses prepare(); interpolated table names come from trusted wpdb properties and placeholders are expanded explicitly.
            $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name IN ($placeholders)", ...$bare_enabled_options ) );

            if ( is_multisite() ) {
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- query uses prepare(); interpolated table names come from trusted wpdb properties and placeholders are expanded explicitly.
                $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->sitemeta} WHERE meta_key IN ($placeholders)", ...$bare_enabled_options ) );
            }
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- query uses prepare(); interpolated table names come from trusted wpdb properties.
        $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", $wpdb->esc_like( 'ultraguard_' ) . '%' ) );
        $removed[] = 'ultraguard_* options';

        if ( is_multisite() ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared -- query uses prepare(); interpolated table names come from trusted wpdb properties.
            $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->sitemeta} WHERE meta_key LIKE %s", $wpdb->esc_like( 'ultraguard_' ) . '%' ) );
            $removed[] = 'ultraguard_* site options';
        }
    }

    // phpcs:ignore WordPress.DB.DirectDatabaseQuery
    $wpdb->query(  // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- static query, no user input
        $wpdb->prepare(
            "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s",
            $wpdb->esc_like( '_transient_ultraguard_' ) . '%',
            $wpdb->esc_like( '_transient_timeout_ultraguard_' ) . '%'
        )
    );
    $removed[] = 'ultraguard transients';

    if ( is_multisite() ) {
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery
        $wpdb->query(  // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- static query, no user input
            $wpdb->prepare(
                "DELETE FROM {$wpdb->sitemeta} WHERE meta_key LIKE %s OR meta_key LIKE %s",
                $wpdb->esc_like( '_site_transient_ultraguard_' ) . '%',
                $wpdb->esc_like( '_site_transient_timeout_ultraguard_' ) . '%'
            )
        );
        $removed[] = 'ultraguard site transients';
    }

    return $removed;
}

/**
 * Drop every table owned by a built-in module schema, regardless of active state.
 */
function ultraguard_pro_drop_all_module_tables(): array {
    $dropped = [];

    foreach ( ultraguard_pro_get_builtin_module_manifests() as $manifest ) {
        $schema_class = (string) ( $manifest['schema_class'] ?? '' );
        if ( '' === $schema_class || ! class_exists( $schema_class ) ) {
            continue;
        }

        try {
            $schema = new $schema_class();
            if ( method_exists( $schema, 'uninstall' ) ) {
                $schema->uninstall();
                $dropped[] = $manifest['id'];
            }
        } catch ( \Throwable $e ) {
            \UltraguardPro\core\Logger::error( 'UltraGuard Pro uninstall: schema drop failed for ' . ( $manifest['id'] ?? 'unknown' ), [ 'error' => $e->getMessage() ] );
        }
    }

    \UltraguardPro\core\DatabaseSchema::flush_cache();
    return $dropped;
}

/**
 * Remove plugin upload directories and third-party module uploads.
 */
function ultraguard_pro_remove_upload_directories(): array {
    $removed = [];
    $upload  = wp_upload_dir();
    $dirs    = [
        trailingslashit( $upload['basedir'] ) . 'ultraguard-security-suite',
        trailingslashit( $upload['basedir'] ) . 'ultraguard-modules',
    ];

    foreach ( $dirs as $dir ) {
        if ( ! is_dir( $dir ) ) {
            continue;
        }

        try {
            $files = new \RecursiveIteratorIterator(
                new \RecursiveDirectoryIterator( $dir, \RecursiveDirectoryIterator::SKIP_DOTS ),
                \RecursiveIteratorIterator::CHILD_FIRST
            );

            foreach ( $files as $fi ) {
                $fi->isDir()
                    ? ( /* phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- cleanup of empty plugin-owned directories during uninstall. */ @rmdir( $fi->getRealPath() ) )
                    : wp_delete_file( $fi->getRealPath() );
            }

            // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- cleanup of empty plugin-owned upload directory during uninstall.
            @rmdir( $dir );
            $removed[] = basename( $dir );
        } catch ( \Throwable $e ) {
            \UltraguardPro\core\Logger::error( 'UltraGuard Pro cleanup: failed to remove directory ' . $dir, [ 'error' => $e->getMessage() ] );
        }
    }

    return $removed;
}

/**
 * Flush runtime artifacts only.
 */
function ultraguard_pro_cleanup_runtime(): array {
    $summary = [
        'crons'      => ultraguard_pro_clear_all_cron_hooks(),
        'transients' => ultraguard_pro_remove_options_and_transients( false ),
    ];

    try {
        \UltraguardPro\core\CacheManager::get_instance()->flush_all_plugin_transients();
        \UltraguardPro\core\Utils::clear_caches();
    } catch ( \Throwable $e ) {
    }

    return $summary;
}

/**
 * Shared cleanup entry point for deactivation/uninstall.
 *
 * @return array<string, array>
 */
function ultraguard_pro_cleanup_data( string $mode ): array {
    $safe_mode = in_array( $mode, [ 'none', 'soft', 'full' ], true ) ? $mode : 'none';
    $summary   = ultraguard_pro_cleanup_runtime();

    if ( 'none' === $safe_mode ) {
        return $summary;
    }

    $summary['options'] = ultraguard_pro_remove_options_and_transients( true );

    if ( 'full' === $safe_mode ) {
        $summary['tables']  = ultraguard_pro_drop_all_module_tables();
        $summary['uploads'] = ultraguard_pro_remove_upload_directories();
    }

    return $summary;
}

// ─── Activation ───────────────────────────────────────────────────────────────

function ultraguard_pro_activate( bool $network_wide = false ): void {
    if ( ! ultraguard_pro_current_user_can_lifecycle( 'activate_plugins', 'manage_network_plugins' ) ) {
        wp_die( esc_html__( 'You do not have permission to activate plugins.', 'ultraguard-security-suite' ) );
    }

    do_action( 'ultraguard_pro/activation/before' );

    try {
        ultraguard_pro_for_each_site(
            static function (): void {
                ultraguard_pro_activate_current_site();
            },
            $network_wide
        );

        if ( $network_wide ) {
            update_site_option( 'ultraguard_pro_activated', true );
            update_site_option( 'ultraguard_pro_version', ULTRAGUARD_PRO_VERSION );
        }

        ultraguard_pro_set_cleanup_mode( 'none' );

        if ( ! $network_wide ) {
            set_transient( 'ultraguard_pro_activation_redirect', true, 30 );
        }
        do_action( 'ultraguard_pro/activation/after' );

    } catch ( \Exception $e ) {
        \UltraguardPro\core\Logger::error( 'Ultraguard Pro activation failed', [ 'error' => $e->getMessage() ] );
        wp_die(
            /* translators: %1$s: error message */
            sprintf( esc_html__( 'Ultraguard Pro activation failed: %s', 'ultraguard-security-suite' ), esc_html( $e->getMessage() ) ),
            esc_html__( 'Plugin Activation Error', 'ultraguard-security-suite' ),
            [ 'back_link' => true ]
        );
    }
}

function ultraguard_pro_activate_current_site(): void {
    update_option( 'ultraguard_pro_activated', true );
    update_option( 'ultraguard_pro_version', ULTRAGUARD_PRO_VERSION );
    _ultraguard_single_site_activate();
}

function _ultraguard_single_site_activate(): void {
    do_action( 'ultraguard_pro/single_site_activation/before' );

    $core_deps = [
        '/core/class-cache-manager.php',
        '/core/class-sanitization-engine.php',
        '/core/class-validation-engine.php',
        '/support/class-ajax-response-builder.php',
        '/modules/settings/class-settings.php',
    ];
    foreach ( $core_deps as $dep ) {
        $path = __DIR__ . $dep;
        if ( file_exists( $path ) ) {
            require_once $path;
        } else {
            \UltraguardPro\core\Logger::error( 'UltraGuard Pro activation: core dependency not found', [ 'path' => $path ] );
        }
    }

    $modules_dir = __DIR__ . '/modules/';
    foreach ( glob( $modules_dir . '*/module.json' ) ?: [] as $json_file ) {
        $manifest = json_decode( file_get_contents( $json_file ), true );
        if ( ! is_array( $manifest ) || empty( $manifest['activation_dep'] ) ) { continue; }
        $dep_path = __DIR__ . '/' . ltrim( $manifest['activation_dep'], '/' );
        if ( file_exists( $dep_path ) ) {
            require_once $dep_path;
        } else {
            \UltraguardPro\core\Logger::error( 'UltraGuard Pro activation: module dependency not found', [ 'path' => $dep_path ] );
        }
    }

    // Create upload directories
    $base = trailingslashit( wp_upload_dir()['basedir'] ) . 'ultraguard-security-suite';
    $dirs = [ $base, "$base/logs", "$base/quarantine", "$base/backups", "$base/temp", "$base/scans" ];

    foreach ( $dirs as $dir ) {
        if ( ! file_exists( $dir ) ) {
            if ( ! wp_mkdir_p( $dir ) ) {
                throw new \Exception( esc_html( "Failed to create directory: {$dir}" ) );
            }
            file_put_contents( "{$dir}/index.php", "<?php\n// Silence is golden\n" );
        }
    }

    if ( ! function_exists( 'dbDelta' ) ) {
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    }

    $schema_manifests = [];
    foreach ( glob( $modules_dir . '*/module.json' ) ?: [] as $json_file ) {
        $manifest = json_decode( file_get_contents( $json_file ), true );
        if ( ! is_array( $manifest ) || empty( $manifest['schema_class'] ) ) { continue; }
        $schema_manifests[] = [
            'schema_class' => $manifest['schema_class'],
            'priority'     => (int) ( $manifest['priority'] ?? 50 ),
        ];
    }
    usort( $schema_manifests, static fn( $a, $b ) => $a['priority'] <=> $b['priority'] );

    foreach ( $schema_manifests as $entry ) {
        $schema_class = $entry['schema_class'];
        try {
            if ( class_exists( $schema_class ) ) {
                ( new $schema_class() )->install();
            }
        } catch ( \Throwable $e ) {
            throw new \Exception(
                /* translators: %1\: schema class, %2\: error message */
                esc_html( sprintf( 'Failed to install schema [%s]: %s', $schema_class, $e->getMessage() ) )
            );
        }
    }

    update_option( 'ultraguard_pro_db_version', ULTRAGUARD_PRO_DB_VERSION );

    // Schedule cron events
    \UltraguardPro\support\CronManager::init();

    \UltraguardPro\support\CronManager::make()
        ->hook( 'ultraguard_pro_daily_scan' )
        ->label( 'UltraGuard Daily Malware Scan' )
        ->recurrence( \UltraguardPro\support\CronManager::DAILY )
        ->register();

    \UltraguardPro\support\CronManager::make()
        ->hook( 'ultraguard_pro_file_integrity_check' )
        ->label( 'UltraGuard File Integrity Check' )
        ->recurrence( \UltraguardPro\support\CronManager::TWICEDAILY )
        ->withLock( 'ultraguard_integrity_lock', 1800 )
        ->register();

    \UltraguardPro\support\CronManager::make()
        ->hook( 'ultraguard_pro_cleanup_logs' )
        ->label( 'UltraGuard Log Cleanup' )
        ->recurrence( \UltraguardPro\support\CronManager::WEEKLY )
        ->register();

    // Initialise default settings
    \UltraguardPro\modules\settings\Settings::get_instance()->set_default_options();
    ultraguard_pro_seed_default_module_settings();

    // Seed the malware signature database from the bundled JSON file.
    $seeder_class = \UltraguardPro\modules\antivirus\SignatureSeeder::class;
    if ( class_exists( $seeder_class ) ) {
        try {
            ( new $seeder_class() )->seed();
        } catch ( \Throwable $e ) {
            \UltraguardPro\core\Logger::error( 'UltraGuard Pro: Signature seeding failed during activation', [ 'error' => $e->getMessage() ] );
        }
    }

    // Seed firewall attack patterns and default rules from bundled JSON
    $firewall_seeder_class = \UltraguardPro\modules\firewall\FirewallSeeder::class;
    if ( class_exists( $firewall_seeder_class ) ) {
        try {
            ( new $firewall_seeder_class() )->seed();
        } catch ( \Throwable $e ) {
            \UltraguardPro\core\Logger::error( 'UltraGuard Pro: Firewall seeding failed during activation', [ 'error' => $e->getMessage() ] );
        }
    }

    // Fresh installs should start in an explicit Free state and queue the first
    // registration/heartbeat attempt without blocking activation on the remote server.
    \UltraguardPro\support\LicenseInfo::init();
    \UltraguardPro\support\LicenseInfo::make()->validate();
    delete_transient( \UltraguardPro\support\LicenseInfo::TRANSIENT_REGISTER_RETRY );
    wp_schedule_single_event( time() + MINUTE_IN_SECONDS, 'ultraguard_register_installation' );

    do_action( 'ultraguard_pro/single_site_activation/after' );
}

// ─── Deactivation ─────────────────────────────────────────────────────────────

function ultraguard_pro_deactivate( bool $network_wide = false ): void {
    if ( ! ultraguard_pro_current_user_can_lifecycle( 'activate_plugins', 'manage_network_plugins' ) ) {
        wp_die( esc_html__( 'You do not have permission to deactivate plugins.', 'ultraguard-security-suite' ) );
    }

    do_action( 'ultraguard_pro/deactivation/before' );

    try {
        ultraguard_pro_for_each_site(
            static function (): void {
                ultraguard_pro_cleanup_runtime();

                // Clean temp files older than 1 hour
                $temp_dir = trailingslashit( wp_upload_dir()['basedir'] ) . 'ultraguard-security-suite/temp';
                if ( is_dir( $temp_dir ) ) {
                    foreach ( glob( trailingslashit( $temp_dir ) . '*' ) ?: [] as $file ) {
                        if ( is_file( $file ) && filemtime( $file ) < strtotime( '-1 hour' ) ) {
                            wp_delete_file( $file );
                        }
                    }
                }

                delete_option( 'ultraguard_pro_activated' );
                delete_option( 'ultraguard_pro_version' );
                delete_transient( 'ultraguard_pro_activation_redirect' );

                // Flush plugin caches
                \UltraguardPro\core\CacheManager::get_instance()->flush_all_plugin_transients();
                \UltraguardPro\core\Utils::clear_caches();
            },
            $network_wide
        );

        if ( is_multisite() ) {
            delete_site_option( 'ultraguard_pro_activated' );
            delete_site_option( 'ultraguard_pro_version' );
        }
        delete_transient( 'ultraguard_pro_activation_redirect' );

        do_action( 'ultraguard_pro/deactivation/after' );

    } catch ( \Exception $e ) {
        \UltraguardPro\core\Logger::error( 'Ultraguard Pro deactivation error', [ 'error' => $e->getMessage() ] );
    }
}

// ─── Uninstall ────────────────────────────────────────────────────────────────

function ultraguard_pro_uninstall(): void {
    if ( ! ultraguard_pro_current_user_can_lifecycle( 'delete_plugins', 'manage_network_plugins' ) ) {
        wp_die( esc_html__( 'You do not have permission to delete plugins.', 'ultraguard-security-suite' ) );
    }

    do_action( 'ultraguard_pro/uninstall/before' );

    $mode      = ultraguard_pro_get_cleanup_mode();
    $summaries = [];

    ultraguard_pro_for_each_site(
        static function ( int $blog_id ) use ( $mode, &$summaries ): void {
            $summary = ultraguard_pro_cleanup_data( $mode );

            delete_option( 'ultraguard_pro_activated' );
            delete_option( 'ultraguard_pro_version' );
            delete_option( 'ultraguard_cleanup_on_uninstall' );

            $summaries[ $blog_id ] = $summary;
        },
        is_multisite()
    );

    if ( is_multisite() ) {
        delete_site_option( 'ultraguard_pro_activated' );
        delete_site_option( 'ultraguard_pro_version' );
        delete_site_option( 'ultraguard_cleanup_on_uninstall' );
    }

    do_action( 'ultraguard_pro/uninstall/after', $summaries );
}

/**
 * Initialize UltraGuard Pro on newly created sites when the plugin is network-active.
 *
 * @param \WP_Site $new_site New site object.
 * @return void
 */
function ultraguard_pro_initialize_new_site( \WP_Site $new_site ): void {
    if ( ! ultraguard_pro_is_network_active() ) {
        return;
    }

    switch_to_blog( (int) $new_site->blog_id );
    try {
        ultraguard_pro_activate_current_site();
    } finally {
        restore_current_blog();
    }
}
