<?php
/**
 * Detects AI bot requests on `init` and forwards them to the Logger.
 *
 * @package WPLens
 */

namespace WPLens\Crawler;

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

final class Detector {

	public function register(): void {
		// Priority 1 = run as early as possible to keep work cheap.
		add_action( 'init', array( $this, 'detect' ), 1 );
	}

	public function detect(): void {
		if ( is_admin() ) {
			return;
		}
		if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
			return;
		}
		if ( defined( 'WP_CLI' ) && WP_CLI ) {
			return;
		}
		if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
			// Logging REST traffic creates feedback loops. Skip.
			return;
		}

		$settings = \WPLens\Utils\Options::all();
		if ( empty( $settings['modules']['crawler_log'] ) ) {
			return;
		}

		// Sampling.
		$sample = isset( $settings['crawler']['sample_rate'] )
			? (float) $settings['crawler']['sample_rate']
			: 1.0;
		if ( $sample < 1.0 ) {
			if ( wp_rand( 0, PHP_INT_MAX ) / PHP_INT_MAX > $sample ) {
				return;
			}
		}

		$ua = isset( $_SERVER['HTTP_USER_AGENT'] )
			? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) )
			: '';

		$bot = BotRegistry::match( $ua );
		if ( null === $bot ) {
			return;
		}

		// Optional skip: admin paths and 404s.
		$uri = isset( $_SERVER['REQUEST_URI'] )
			? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) )
			: '/';

		if ( empty( $settings['crawler']['log_admin_paths'] ) && false !== stripos( $uri, '/wp-admin' ) ) {
			return;
		}

		( new Logger() )->log(
			array(
				'bot_slug'       => $bot['slug'],
				'bot_family'     => $bot['family'],
				'user_agent'     => $ua,
				'request_uri'    => $uri,
				'request_method' => isset( $_SERVER['REQUEST_METHOD'] )
					? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) )
					: 'GET',
				'response_code'  => http_response_code() ?: 200,
				'ip'             => isset( $_SERVER['REMOTE_ADDR'] )
					? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) )
					: '',
			)
		);
	}
}
