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

class Wtols_Scanner {

	public function __construct() {
		add_action('wp_ajax_wtols_run_scanner', array($this, 'handle_scanner_ajax'));
		add_action('wp_ajax_wtols_clean_issue', array($this, 'handle_clean_issue_ajax'));
	}

	public function handle_clean_issue_ajax() {
		if (!current_user_can('manage_options')) {
			wp_send_json_error('Unauthorized');
		}

		$nonce = isset($_POST['nonce']) ? wp_unslash($_POST['nonce']) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		if (empty($nonce) || !wp_verify_nonce($nonce, 'wtols_scanner_nonce')) {
			wp_send_json_error('Invalid nonce');
		}

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

		if (empty($issue_type) || empty($issue_data)) {
			wp_send_json_error('Missing data');
		}

		if ($issue_type === 'file') {
			$file_path = ABSPATH . ltrim($issue_data, '/');
			// Basic security check before deleting
			if (strpos($file_path, WP_PLUGIN_DIR) === 0 && file_exists($file_path)) {
				if (wp_delete_file($file_path)) {
					wp_send_json_success('File deleted successfully.');
				} else {
					wp_send_json_error('Could not delete file. Check file permissions.');
				}
			} else {
				wp_send_json_error('Invalid file path.');
			}
		} elseif ($issue_type === 'option') {
			$option_name = sanitize_text_field($issue_data);
			$current_val = get_option($option_name);
			if ($current_val) {
				// Remove script and iframe tags
				$clean_val = preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', '', $current_val);
				$clean_val = preg_replace('/<iframe\b[^>]*>(.*?)<\/iframe>/is', '', $clean_val);
				update_option($option_name, $clean_val);
				wp_send_json_success('Option cleaned successfully.');
			} else {
				wp_send_json_error('Option not found.');
			}
		} elseif ($issue_type === 'user') {
			$user_id = absint($issue_data);
			if ($user_id > 0 && get_current_user_id() !== $user_id) {
				require_once(ABSPATH . 'wp-admin/includes/user.php');
				if (wp_delete_user($user_id)) {
					wp_send_json_success('User deleted successfully.');
				} else {
					wp_send_json_error('Could not delete user.');
				}
			} else {
				wp_send_json_error('Invalid user or cannot delete current user.');
			}
		}

		wp_send_json_error('Unknown issue type.');
	}

	public function handle_scanner_ajax() {
		if (!current_user_can('manage_options')) {
			wp_send_json_error('Unauthorized');
		}

		$nonce = isset($_POST['nonce']) ? wp_unslash($_POST['nonce']) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		if (empty($nonce) || !wp_verify_nonce($nonce, 'wtols_scanner_nonce')) {
			wp_send_json_error('Invalid nonce');
		}

		$results = array(
			'files' => array(),
			'db' => array(),
			'status' => 'success'
		);

		$results['files'] = $this->scan_files();
		$results['db'] = $this->scan_database();

		wp_send_json_success($results);
	}

	private function scan_files() {
		$issues = array();
		
		$plugins_dir = WP_PLUGIN_DIR;
		if (!is_dir($plugins_dir)) return $issues;

		$iterator = new RecursiveIteratorIterator(
			new RecursiveDirectoryIterator($plugins_dir, RecursiveDirectoryIterator::SKIP_DOTS),
			RecursiveIteratorIterator::SELF_FIRST
		);
		$iterator->setMaxDepth(2); 

		$suspicious_patterns = array(
			'eval\(base64_decode' => 'Potential Base64 Backdoor',
			'gzinflate\(base64_decode' => 'Potential Encoded Backdoor',
			'assert\($_POST' => 'Potential RCE Backdoor'
		);

		foreach ($iterator as $file) {
			if ($file->isFile() && $file->getExtension() === 'php') {
				if (strpos($file->getPathname(), 'webtaru-site-options-login-security') !== false) {
					continue;
				}

				$content = file_get_contents($file->getPathname(), false, null, 0, 5000); 
				if (!$content) continue;

				foreach ($suspicious_patterns as $pattern => $label) {
					if (preg_match('/' . $pattern . '/i', $content)) {
						$issues[] = array(
							'type' => 'file',
							'path' => str_replace(ABSPATH, '', $file->getPathname()),
							'issue' => $label,
							'action_type' => 'file',
							'action_data' => str_replace(ABSPATH, '', $file->getPathname())
						);
					}
				}
			}
		}

		return $issues;
	}

	private function scan_database() {
		global $wpdb;
		$issues = array();

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$options = $wpdb->get_results("SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name IN ('siteurl', 'home', 'active_plugins') OR option_value LIKE '%<script%' OR option_value LIKE '%<iframe%' LIMIT 100");
		
		foreach ($options as $opt) {
			// phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
			if (preg_match('/<script\s+src=[\'"]http/i', $opt->option_value) || preg_match('/<iframe\s+src=/i', $opt->option_value)) {
				$issues[] = array(
					'type' => 'database',
					'location' => 'wp_options -> ' . $opt->option_name,
					'issue' => 'Suspicious Script/Iframe in Option',
					'action_type' => 'option',
					'action_data' => $opt->option_name
				);
			}
		}

		$admins = get_users(array('role' => 'administrator'));
		foreach ($admins as $admin) {
			if (!user_can($admin->ID, 'manage_options')) {
				$issues[] = array(
					'type' => 'database',
					'location' => 'User: ' . $admin->user_login,
					'issue' => 'Administrator without manage_options capability (Corrupted/Hidden)',
					'action_type' => 'user',
					'action_data' => $admin->ID
				);
			}
		}

		return $issues;
	}
}
