<?php

defined( 'ABSPATH' ) || exit;

class ZACLS_Vulnerability_Scanner {

	const WPSCAN_API = 'https://wpscan.com/api/v3';

	public static function scan_plugins() {
		if ( ! function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		$plugins   = get_plugins();
		$results   = array();
		$vuln_count = 0;

		$cached = get_transient( 'zacls_vuln_db' );
		if ( false === $cached ) {
			$cached = self::fetch_vulnerability_feed();
		}

		if ( ! is_array( $cached ) ) {
			return array(
				'status'  => 'error',
				'message' => esc_html__( 'Unable to fetch vulnerability data. Please try again later.', 'za-creative-login-shield' ),
			);
		}

		foreach ( $plugins as $plugin_file => $plugin_data ) {
			$slug       = dirname( $plugin_file );
			$version    = $plugin_data['Version'];
			$vulns      = array();

			if ( isset( $cached[ $slug ] ) ) {
				foreach ( $cached[ $slug ] as $vuln ) {
					if ( version_compare( $version, $vuln['fixed_in'], '<' ) ) {
						$vulns[] = array(
							'title'       => $vuln['title'] ?? esc_html__( 'Unknown vulnerability', 'za-creative-login-shield' ),
							'type'        => $vuln['type'] ?? 'unknown',
							'fixed_in'    => $vuln['fixed_in'] ?? '',
							'severity'    => $vuln['severity'] ?? 'medium',
							'cve'         => $vuln['cve'] ?? '',
							'description' => $vuln['description'] ?? '',
						);
						$vuln_count++;
					}
				}
			}

			$results[ $slug ] = array(
				'name'         => $plugin_data['Name'],
				'version'      => $version,
				'vulnerabilities' => $vulns,
				'vuln_count'   => count( $vulns ),
			);
		}

		update_option( 'zacls_vuln_scan_last', time() );
		update_option( 'zacls_vuln_scan_results', $results );

		ZACLS_Audit_Trail::log(
			'vuln_scan',
			sprintf(
				esc_html__( 'Vulnerability scan complete: %1$d vulnerabilities found across %2$d plugins', 'za-creative-login-shield' ),
				$vuln_count,
				count( $plugins )
			)
		);

		return array(
			'status'    => 'success',
			'results'   => $results,
			'total'     => count( $plugins ),
			'vuln_count'=> $vuln_count,
			'checked'   => count( $plugins ),
		);
	}

	public static function scan_themes() {
		$themes  = wp_get_themes();
		$results = array();
		$vuln_count = 0;

		$cached = get_transient( 'zacls_vuln_db' );
		if ( false === $cached ) {
			return array(
				'status'  => 'error',
				'message' => esc_html__( 'No vulnerability data cached.', 'za-creative-login-shield' ),
			);
		}

		foreach ( $themes as $slug => $theme ) {
			$version = $theme->get( 'Version' );
			$vulns   = array();

			if ( isset( $cached[ 'theme-' . $slug ] ) ) {
				foreach ( $cached[ 'theme-' . $slug ] as $vuln ) {
					if ( version_compare( $version, $vuln['fixed_in'], '<' ) ) {
						$vulns[] = array(
							'title'    => $vuln['title'] ?? esc_html__( 'Unknown vulnerability', 'za-creative-login-shield' ),
							'type'     => $vuln['type'] ?? 'unknown',
							'fixed_in' => $vuln['fixed_in'] ?? '',
							'cve'      => $vuln['cve'] ?? '',
						);
						$vuln_count++;
					}
				}
			}

			$results[ $slug ] = array(
				'name'           => $theme->get( 'Name' ),
				'version'        => $version,
				'vulnerabilities' => $vulns,
				'vuln_count'     => count( $vulns ),
			);
		}

		return array(
			'status'    => 'success',
			'results'   => $results,
			'total'     => count( $themes ),
			'vuln_count'=> $vuln_count,
		);
	}

	private static function fetch_vulnerability_feed() {
		$wpscan_token = get_option( 'zacls_wpscan_api_token', '' );

		if ( ! empty( $wpscan_token ) ) {
			$response = wp_remote_get(
				self::WPSCAN_API . '/plugins',
				array(
					'headers' => array(
						'Authorization' => 'Bearer ' . $wpscan_token,
					),
					'timeout' => 30,
				)
			);

			if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
				$data = json_decode( wp_remote_retrieve_body( $response ), true );
				if ( is_array( $data ) ) {
					set_transient( 'zacls_vuln_db', $data, DAY_IN_SECONDS );
					return $data;
				}
			}
		}

		$fallback_url = 'https://raw.githubusercontent.com/wpscanteam/vulndb/master/data/plugins.json';
		$response     = wp_remote_get( $fallback_url, array( 'timeout' => 30 ) );

		if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
			return false;
		}

		$data = json_decode( wp_remote_retrieve_body( $response ), true );
		if ( ! is_array( $data ) ) {
			return false;
		}

		$indexed = array();
		foreach ( $data as $entry ) {
			$slug = sanitize_key( $entry['slug'] ?? '' );
			if ( empty( $slug ) ) {
				continue;
			}
			$indexed[ $slug ][] = array(
				'title'       => $entry['title'] ?? '',
				'type'        => $entry['type'] ?? 'unknown',
				'fixed_in'    => $entry['fixed_in'] ?? '99.99.99',
				'severity'    => $entry['severity'] ?? 'medium',
				'cve'         => $entry['cve'] ?? '',
				'description' => $entry['description'] ?? '',
			);
		}

		set_transient( 'zacls_vuln_db', $indexed, DAY_IN_SECONDS );
		return $indexed;
	}

	public static function get_cached_results() {
		return get_option( 'zacls_vuln_scan_results', array() );
	}
}
