<?php
/**
 * Handles plugin uninstallation cleanup.
 *
 * WordPress.org FR-018 Compliant:
 * - Deletes all plugin options (aipt_* prefix)
 * - Drops all custom database tables
 * - Deletes all user meta (aipt_* prefix)
 * - Deletes all transients (aipt_* prefix)
 * - Clears all scheduled cron events
 * - Removes plugin capabilities
 * - Calls Freemius cleanup if available
 *
 * NOTE: AI provider API keys are user-owned credentials.
 * Users must revoke them in their respective provider dashboards.
 *
 * NOTE: Ctrl credit usage data is retained on Ctrl servers for
 * billing/fraud-prevention per terms of service. To request complete
 * Ctrl account deletion, contact support@aiforwoo.com
 *
 * @package AIPT\Core
 * @since   2.0.4
 */

namespace AIPT\Core;

use AIPT\Core\CreditSystem\CreditManager;
use AIPT\Core\Database\Migration;

/**
 * Uninstaller class for complete plugin data cleanup.
 */
class Uninstaller {
    private static $api_endpoint = 'https://api.aiforwoo.com/api/v2/uninstall';

    /**
     * Clean up plugin data after uninstall.
     * This method is hooked to Freemius after_uninstall action.
     * Completely fail-safe - user should never see errors.
     *
     * @return void
     */
    public static function cleanup() {
        try {

            $is_cli = defined('WP_CLI') && WP_CLI;
            $is_wp_uninstall = defined('WP_UNINSTALL_PLUGIN');
            $has_capability = current_user_can('activate_plugins');

            if (!$is_cli && !$is_wp_uninstall && !$has_capability) {
                return;
            }

            self::log_debug('Uninstall process started');

            try {
                self::log_security_event('site_uninstall_initiated', [
                    'uninstall_method' => 'plugin_uninstall',
                    'site_url' => get_site_url(),
                    'admin_email' => get_option('admin_email'),
                    'user_can_activate_plugins' => current_user_can('activate_plugins')
                ]);
            } catch (\Exception $e) {
                self::log_debug('Security event logging failed: ' . $e->getMessage());

            }

            try {
                self::send_uninstall_request();
            } catch (\Exception $e) {
                self::log_debug('API notification failed: ' . $e->getMessage());

            }

            try {
                self::cleanup_options();
            } catch (\Exception $e) {
                self::log_debug('Options cleanup failed: ' . $e->getMessage());

            }

            try {
                self::cleanup_cron_jobs();
            } catch (\Exception $e) {
                self::log_debug('Cron cleanup failed: ' . $e->getMessage());

            }

            try {
                self::cleanup_cache();
            } catch (\Exception $e) {
                self::log_debug('Cache cleanup failed: ' . $e->getMessage());

            }

            try {
                $migration = Migration::get_instance();
                $migration->drop_tables();
            } catch (\Exception $e) {
                self::log_debug('Tables could not be dropped: ' . $e->getMessage());
                self::drop_prompt_templates_table();
            }

            try {
                self::cleanup_user_meta();
            } catch (\Exception $e) {
                self::log_debug('User meta cleanup failed: ' . $e->getMessage());
            }

            try {
                self::cleanup_capabilities();
            } catch (\Exception $e) {
                self::log_debug('Capabilities cleanup failed: ' . $e->getMessage());
            }

            try {
                self::cleanup_freemius();
            } catch (\Exception $e) {
                self::log_debug('Freemius cleanup failed: ' . $e->getMessage());
            }

            self::log_debug('Uninstall process completed');

        } catch (\Exception $e) {

            self::log_debug('General uninstall error: ' . $e->getMessage());

        }
    }

    private static function send_uninstall_request() {
        try {
            $api_key = get_option('aipt_credit_api_key', '');
            $secret_key = get_option('aipt_credit_secret_key', '');

            if (empty($api_key) || empty($secret_key)) {
                self::log_debug('API keys not found - uninstall continuing');
                return true;
            }

            $site_url = get_site_url();
            if (empty($site_url)) {
                self::log_debug('Site URL not found - uninstall continuing');
                return true;
            }

            $timestamp = time();
            $signature = hash_hmac('sha256', $api_key . ':' . $timestamp, $secret_key);

            wp_remote_post(self::$api_endpoint, [
                'timeout' => 1,
                'blocking' => false,
                'body' => wp_json_encode([
                    'site_url' => $site_url,
                    'api_key' => $api_key,
                    'timestamp' => $timestamp,
                    'signature' => $signature,
                    'version' => defined('AIPT_VERSION') ? AIPT_VERSION : '2.0.0'
                ]),
                'headers' => [
                    'Content-Type' => 'application/json'
                ]
            ]);

            self::log_debug('V2 uninstall API notification sent');
            return true;

        } catch (\Exception $e) {
            self::log_debug('Uninstall API error: ' . $e->getMessage());
            return true;
        }
    }

    /**
     * Cleans plugin data from options table.
     * Removes all AIPT related options.
     * Continues even if errors occur.
     *
     * @return void
     */
    private static function cleanup_options() {
        self::log_debug('Database cleanup started');

        try {

            $credit_options = [

                'aipt_credits_cache_' . md5(get_site_url()),
                'aipt_credits_costs_cache',

                'aipt_usage_summary',

                'aipt_last_sync_time',
                'aipt_last_heartbeat_time',
                'aipt_sync_counter',

                'aipt_ctrl_api_key',
                'aipt_ctrl_secret_key',
                'aipt_site_registered',
                'aipt_bulk_terms_accepted',
                'aipt_credits_enabled',
                'aipt_security_events_queue'
            ];

            $main_options = [

                'aipt_version',
                'aipt_db_version',
                'aipt_cache_version',

                'aipt_openai_api_key',
                'aipt_gemini_api_key',
                'aipt_api_provider',
                'aipt_model',

                'aipt_system_prompt',
                'aipt_user_prompt',
                'aipt_short_system_prompt',
                'aipt_short_user_prompt',
                'aipt_full_system_prompt',
                'aipt_full_user_prompt',

                'aipt_standard_short_system_prompt',
                'aipt_standard_short_user_prompt',
                'aipt_standard_full_system_prompt',
                'aipt_standard_full_user_prompt',

                'aipt_title_additional_prompt',
                'aipt_faq_additional_prompt',
                'aipt_seo_meta_additional_prompt',
                'aipt_taxonomy_additional_prompt',

                'aipt_custom_variables',
                'aipt_language',
                'aipt_writing_style',
                'aipt_max_length',
                'aipt_max_short_length',
                'aipt_max_tags_count',

                'aipt_needs_setup',
                'aipt_setup_completed',
                'aipt_first_activation',
                'aipt_redirect_to_setup',
                'aipt_display_terms_notice',

                'aipt_faq_display_settings',
            ];

            foreach ($credit_options as $option) {
                try {
                    delete_option($option);
                } catch (\Exception $e) {
                    self::log_debug("Could not delete credit option ($option): " . $e->getMessage());

                }
            }

            foreach ($main_options as $option) {
                try {
                    delete_option($option);
                } catch (\Exception $e) {
                    self::log_debug("Could not delete main option ($option): " . $e->getMessage());

                }
            }

        } catch (\Exception $e) {
            self::log_debug('General error during option cleanup: ' . $e->getMessage());
        }

        try {
            global $wpdb;

            $wpdb->query(
                $wpdb->prepare(
                    "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s AND option_name LIKE %s",
                    '%aipt_%',
                    '%_transient_%'
                )
            );

            $wpdb->query(
                $wpdb->prepare(
                    "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
                    'aipt_%'
                )
            );

        } catch (\Exception $e) {
            self::log_debug('Error during database queries: ' . $e->getMessage());

        }

        self::log_debug('Database cleanup completed');
    }

    /**
     * Cleans up cron jobs.
     * Continues even if errors occur.
     *
     * @return void
     */
    private static function cleanup_cron_jobs() {
        self::log_debug('Cron jobs cleanup started');

        try {

            $cron_hooks = [
                'aipt_credit_sync', 
            ];

            foreach ($cron_hooks as $hook) {
                try {
                    $timestamp = wp_next_scheduled($hook);
                    if ($timestamp) {
                        wp_unschedule_event($timestamp, $hook);
                        self::log_debug("$hook cron job stopped");
                    }
                } catch (\Exception $e) {
                    self::log_debug("Could not stop cron job ($hook): " . $e->getMessage());

                }
            }

            try {
                $cron_tasks = _get_cron_array();
                if (!empty($cron_tasks)) {
                    foreach ($cron_tasks as $timestamp => $cron) {
                        foreach (array_keys($cron) as $hook) {
                            if (strpos($hook, 'aipt_') === 0) {
                                try {
                                    wp_unschedule_event($timestamp, $hook);
                                    self::log_debug("Other cron job stopped: $hook");
                                } catch (\Exception $e) {
                                    self::log_debug("Could not stop other cron job ($hook): " . $e->getMessage());

                                }
                            }
                        }
                    }
                }
            } catch (\Exception $e) {
                self::log_debug('Could not get cron jobs list: ' . $e->getMessage());
            }

        } catch (\Exception $e) {
            self::log_debug('General error during cron cleanup: ' . $e->getMessage());
        }

        self::log_debug('Cron jobs cleanup completed');
    }

    /**
     * Cleans up caches.
     * Continues even if errors occur.
     *
     * @return void
     */
    private static function cleanup_cache() {
        self::log_debug('Cache cleanup started');

        try {

            if (function_exists('wp_cache_flush')) {
                try {
                    wp_cache_flush();
                    self::log_debug('WP Object Cache cleared');
                } catch (\Exception $e) {
                    self::log_debug('Could not clear WP Object Cache: ' . $e->getMessage());
                }
            }

            try {
                delete_transient('aipt_credits_status');
                delete_transient('aipt_api_check');
                self::log_debug('Transients cleared');
            } catch (\Exception $e) {
                self::log_debug('Could not clear transients: ' . $e->getMessage());
            }

            try {
                $upload_dir = wp_upload_dir();
                $temp_dir = $upload_dir['basedir'] . '/aipt-temp';

                if (file_exists($temp_dir) && is_dir($temp_dir)) {
                    self::delete_directory($temp_dir);
                    self::log_debug('Temp directory cleared: ' . $temp_dir);
                }
            } catch (\Exception $e) {
                self::log_debug('Could not clear temp directory: ' . $e->getMessage());
            }

        } catch (\Exception $e) {
            self::log_debug('General error during cache cleanup: ' . $e->getMessage());
        }

        self::log_debug('Cache cleanup completed');
    }

    /**
     * Safely deletes directory and all files within it.
     *
     * @param string $dir Directory to delete.
     * @return bool Whether the operation was successful.
     */
    private static function delete_directory($dir) {
        try {
            if (!file_exists($dir)) {
                return true;
            }

            if (!is_dir($dir)) {
                return wp_delete_file($dir);
            }

            $objects = scandir($dir);
            if ($objects === false) {
                return false;
            }

            foreach ($objects as $object) {
                if ($object != "." && $object != "..") {
                    $path = $dir . "/" . $object;
                    try {
                        if (is_dir($path)) {
                            self::delete_directory($path);
                        } else {
                            wp_delete_file($path);
                        }
                    } catch (\Exception $e) {
                        self::log_debug("Could not delete file/directory ($path): " . $e->getMessage());

                    }
                }
            }

            return rmdir($dir);
        } catch (\Exception $e) {
            self::log_debug("Could not delete directory ($dir): " . $e->getMessage());
            return false;
        }
    }

    /**
     * SECURITY: Log security event via API service
     *
     * @param string $event_type Event type
     * @param array $details Event details
     * @return void
     */
    private static function log_security_event(string $event_type, array $details): void {
        try {

            $api_key = get_option('aipt_credit_api_key', '');
            if (empty($api_key)) {
                return; 
            }

            self::log_debug("Security event: $event_type - " . wp_json_encode($details));

        } catch (\Exception $e) {

            self::log_debug('Security Event Logging Failed: ' . $e->getMessage());
        }
    }

    /**
     * FR-018: Delete all user meta with aipt_ prefix.
     *
     * @return void
     */
    private static function cleanup_user_meta() {
        global $wpdb;

        self::log_debug('User meta cleanup started');

        try {

            $wpdb->query(
                $wpdb->prepare(
                    "DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE %s",
                    'aipt_%'
                )
            );

            self::log_debug('User meta cleanup completed');
        } catch (\Exception $e) {
            self::log_debug('User meta cleanup error: ' . $e->getMessage());
        }
    }

    /**
     * FR-018: Remove plugin capabilities from roles.
     *
     * @return void
     */
    private static function cleanup_capabilities() {
        self::log_debug('Capabilities cleanup started');

        try {

            $roles = array( 'administrator', 'shop_manager' );

            foreach ( $roles as $role_name ) {
                $role = get_role( $role_name );
                if ( $role ) {
                    $role->remove_cap( 'manage_aipt_settings' );
                }
            }

            self::log_debug('Capabilities cleanup completed');
        } catch (\Exception $e) {
            self::log_debug('Capabilities cleanup error: ' . $e->getMessage());
        }
    }

    /**
     * FR-018: Call Freemius cleanup if available.
     *
     * @return void
     */
    private static function cleanup_freemius() {
        self::log_debug('Freemius cleanup started');

        try {

            if ( function_exists( 'fs_uninstall_cleanup' ) ) {
                fs_uninstall_cleanup();
                self::log_debug('Freemius cleanup called');
            }
        } catch (\Exception $e) {
            self::log_debug('Freemius cleanup error: ' . $e->getMessage());
        }
    }

    /**
     * Fallback cleanup for prompt templates table.
     *
     * @return void
     */
    private static function drop_prompt_templates_table() {
        global $wpdb;

        try {

            $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}aipt_prompt_templates" );
        } catch (\Exception $e) {
            self::log_debug('Prompt templates table could not be dropped: ' . $e->getMessage());
        }
    }

    /**
     * Creates log entry for debugging purposes.
     *
     * @param string $message Log message.
     * @return void
     */
    private static function log_debug($message) {
        if (defined('WP_DEBUG') && WP_DEBUG) {
        }
    }
}
