<?php
/**
 * Read-only REST endpoints under /wp-json/lens/v1/.
 *
 * @package WPLens
 */

namespace WPLens\Rest;

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

final class Routes {

	public function register(): void {
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
		add_action( 'admin_post_wplens_report_preview', array( $this, 'report_preview' ) );
	}

	public function register_routes(): void {
		$ns = 'lens/v1';

		register_rest_route(
			$ns,
			'/crawler/summary',
			array(
				'methods'             => 'GET',
				'permission_callback' => array( $this, 'permission_read' ),
				'callback'            => array( $this, 'crawler_summary' ),
			)
		);

		register_rest_route(
			$ns,
			'/crawler/recent',
			array(
				'methods'             => 'GET',
				'permission_callback' => array( $this, 'permission_read' ),
				'callback'            => array( $this, 'crawler_recent' ),
				'args'                => array(
					'limit' => array(
						'sanitize_callback' => 'absint',
						'default'           => 100,
					),
				),
			)
		);

		register_rest_route(
			$ns,
			'/scans',
			array(
				'methods'             => 'GET',
				'permission_callback' => array( $this, 'permission_read' ),
				'callback'            => array( $this, 'scans_recent' ),
			)
		);

		register_rest_route(
			$ns,
			'/citations',
			array(
				'methods'             => 'GET',
				'permission_callback' => array( $this, 'permission_read' ),
				'callback'            => array( $this, 'citations_recent' ),
			)
		);
	}

	/**
	 * Permission check for read-only REST endpoints.
	 *
	 * All Lens REST data (crawler logs, scans, citations) is intentionally
	 * restricted to administrators because:
	 *   - Crawler logs include request URIs and user agents that may leak
	 *     unpublished/private content paths.
	 *   - Scans and citations are operational analytics, not public.
	 * The admin-area pages that surface this data already require
	 * manage_options; the REST routes must match that floor.
	 */
	public function permission_read( \WP_REST_Request $request ) {
		if ( ! is_user_logged_in() ) {
			return new \WP_Error(
				'rest_forbidden',
				__( 'Authentication required.', 'lens-ai-visibility-monitor' ),
				array( 'status' => 401 )
			);
		}
		if ( ! current_user_can( 'manage_options' ) ) {
			return new \WP_Error(
				'rest_forbidden',
				__( 'You do not have permission.', 'lens-ai-visibility-monitor' ),
				array( 'status' => 403 )
			);
		}
		return true;
	}

	public function crawler_summary( \WP_REST_Request $request ) {
		$repo = new \WPLens\Crawler\LogRepository();
		return rest_ensure_response(
			array(
				'totals_30d' => $repo->totals_by_bot( 30 ),
				'daily'      => $repo->daily_series( 30 ),
				'top_pages'  => $repo->top_pages( 30, 10 ),
				'total'      => $repo->total_count( 30 ),
			)
		);
	}

	public function crawler_recent( \WP_REST_Request $request ) {
		$repo  = new \WPLens\Crawler\LogRepository();
		$limit = absint( $request->get_param( 'limit' ) ?: 100 );
		return rest_ensure_response( $repo->recent( $limit ) );
	}

	public function scans_recent( \WP_REST_Request $request ) {
		$repo = new \WPLens\Scans\ScanRepository();
		return rest_ensure_response( $repo->recent( 50 ) );
	}

	public function citations_recent( \WP_REST_Request $request ) {
		$repo = new \WPLens\Citations\CitationRepository();
		return rest_ensure_response(
			array(
				'rate'    => $repo->citation_rate( 30 ),
				'recent'  => $repo->recent_checks( 50 ),
				'queries' => $repo->all_queries(),
			)
		);
	}

	/**
	 * Render the weekly report for in-admin preview.
	 */
	public function report_preview(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have permission.', 'lens-ai-visibility-monitor' ) );
		}
		check_admin_referer( 'wplens_report_preview' );

		$builder = new \WPLens\Reports\HtmlReportBuilder();
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo $builder->build_weekly();
		exit;
	}
}
