<?php
/**
 * Tool: check_schema_coverage
 *
 * Analyse rendered pages for missing schema markup types.
 *
 * @package    Agent_Builder
 * @subpackage Tools
 * @since      2.0.0
 *
 * php version 8.1
 */

declare(strict_types=1);

namespace Agentic\Tools;

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

/**
 * Analyse rendered pages for missing schema markup types with recommendations.
 */
class Check_Schema_Coverage extends \Agentic\Tool_Base {

	/**
	 * Get the tool name.
	 *
	 * @return string
	 */
	public function get_name(): string {
		return 'check_schema_coverage';
	}

	/**
	 * Get the tool description.
	 *
	 * @return string
	 */
	public function get_description(): string {
		return 'Analyse rendered page(s) for missing schema markup types (Article, FAQPage, HowTo, BreadcrumbList, Organization, etc.). Can check a single post or scan all published content. Returns found vs expected schema types with recommendations.';
	}

	/**
	 * Get the tool category.
	 *
	 * @return string
	 */
	public function get_category(): string {
		return 'seo';
	}

	/**
	 * Get the parameter schema.
	 *
	 * @return array
	 */
	public function get_parameters(): array {
		return array(
			'type'       => 'object',
			'properties' => array(
				'post_id' => array(
					'type'        => 'integer',
					'description' => 'Check a specific post. Omit to scan all published posts.',
				),
			),
		);
	}

	/**
	 * Execute the tool.
	 *
	 * @param array $arguments Validated arguments from the LLM.
	 * @return array Result data.
	 */
	public function execute( array $arguments ): array {
		$desired_types = array(
			'Article'        => 'Required for blog posts / news articles. Enables rich results in Google.',
			'FAQPage'        => 'Add to pages with Q&A content. Enables FAQ rich results.',
			'HowTo'          => 'Add to step-by-step instructional content.',
			'BreadcrumbList' => 'Shows site hierarchy in search results. Usually auto-generated by Rank Math/Yoast.',
			'WebSite'        => 'Describes the site itself. Enables sitelinks search box. Usually on homepage only.',
			'Organization'   => 'Identifies the publisher. Should be on homepage or every page.',
			'Person'         => 'For personal blogs or author pages. Establishes E-E-A-T authorship.',
		);

		$post_id = isset( $arguments['post_id'] ) ? (int) $arguments['post_id'] : 0;

		if ( $post_id > 0 ) {
			$post = get_post( $post_id );
			if ( ! $post ) {
				return array( 'error' => 'Post not found.' );
			}

			$rendered = \Agentic\Page_Renderer::fetch_by_post_id( $post_id );
			if ( ! $rendered['success'] ) {
				return array( 'error' => 'Could not fetch rendered page: ' . ( $rendered['error'] ?? 'unknown error' ) );
			}

			$found_types = $rendered['meta']['schema_types'] ?? array();
			$is_post     = in_array( $post->post_type, array( 'post' ), true );
			$expected    = array( 'BreadcrumbList' );
			$expected[]  = $is_post ? 'Article' : 'WebPage';

			$has_qa    = preg_match_all( '/<h[23][^>]*>[^<]*\?[^<]*<\/h[23]>/i', $post->post_content ) >= 2;
			$has_steps = (bool) preg_match( '/<h[23][^>]*>[^<]*(?:step|how to)[^<]*<\/h[23]>/i', $post->post_content );
			if ( $has_qa ) {
				$expected[] = 'FAQPage';
			}
			if ( $has_steps ) {
				$expected[] = 'HowTo';
			}

			$missing         = array();
			$present         = array();
			$recommendations = array();
			foreach ( $desired_types as $type => $desc ) {
				if ( in_array( $type, $found_types, true ) ) {
					$present[] = $type;
				} elseif ( in_array( $type, $expected, true ) ) {
					$missing[]         = $type;
					$recommendations[] = "Add {$type} schema: {$desc}";
				}
			}

			return array(
				'post_id'          => $post_id,
				'title'            => $post->post_title,
				'url'              => get_permalink( $post_id ),
				'schema_found'     => $found_types,
				'schema_present'   => $present,
				'schema_missing'   => $missing,
				'content_patterns' => array(
					'has_qa_headings'  => $has_qa,
					'has_step_content' => $has_steps,
				),
				'recommendations'  => $recommendations,
			);
		}

		// Site-wide scan.
		$results  = array();
		$home_url = home_url( '/' );
		$rendered = \Agentic\Page_Renderer::fetch( $home_url );

		if ( $rendered['success'] ) {
			$home_types   = $rendered['meta']['schema_types'] ?? array();
			$home_missing = array();
			foreach ( array( 'WebSite', 'Organization', 'BreadcrumbList' ) as $t ) {
				if ( ! in_array( $t, $home_types, true ) ) {
					$home_missing[] = $t;
				}
			}
			$results[] = array(
				'url'     => $home_url,
				'type'    => 'homepage',
				'found'   => $home_types,
				'missing' => $home_missing,
			);
		}

		$posts = get_posts(
			array(
				'post_type'      => 'post',
				'post_status'    => 'publish',
				'posts_per_page' => 5,
				'orderby'        => 'date',
				'order'          => 'DESC',
			)
		);

		foreach ( $posts as $p ) {
			$rendered = \Agentic\Page_Renderer::fetch_by_post_id( $p->ID );
			if ( ! $rendered['success'] ) {
				continue;
			}
			$found        = $rendered['meta']['schema_types'] ?? array();
			$post_missing = array();
			if ( ! in_array( 'Article', $found, true ) ) {
				$post_missing[] = 'Article';
			}
			if ( ! in_array( 'BreadcrumbList', $found, true ) ) {
				$post_missing[] = 'BreadcrumbList';
			}
			$results[] = array(
				'url'     => get_permalink( $p->ID ),
				'title'   => $p->post_title,
				'type'    => 'post',
				'found'   => $found,
				'missing' => $post_missing,
			);
		}

		$total_missing = array_sum( array_map( fn( $r ) => count( $r['missing'] ), $results ) );

		return array(
			'pages_analysed' => count( $results ),
			'total_missing'  => $total_missing,
			'results'        => $results,
			'recommendation' => $total_missing > 0
				? "Found {$total_missing} missing schema type(s). Enable the appropriate schema modules in your SEO plugin or use add_faq_schema for FAQ content."
				: 'All checked pages have appropriate schema markup.',
		);
	}

	/**
	 * Get tool annotations.
	 *
	 * @return array
	 */
	public function get_annotations(): array {
		return array(
			'readonly' => true,
		);
	}
}

return new Check_Schema_Coverage();
