<?php

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

require_once VSERPB_PLUGIN_DIR . '/Schema_classes/class-vserpb-propertyvalue.php';
require_once VSERPB_PLUGIN_DIR . '/Schema_classes/class-vserpb-product.php';

class Vserpb_AggregateRating {

	private $product_id;
	private $product;
	private $average_rating = 0;
	private $review_count   = 0;
	private $rating_count   = 0;
	private $product_name;
	private $product_url;
	private $schema = null;

	public function __construct( $product_id ) {
		$this->product_id = $product_id;
		$this->product    = wc_get_product( $product_id );

		if ( $this->product ) {
			$this->generate_schema();
		}
	}

	/**
	 * Generate aggregateRating schema
	 */
	private function generate_schema() {

		$this->average_rating = (float) $this->product->get_average_rating();
		$this->review_count   = (int) $this->product->get_review_count();
		$this->rating_count   = $this->review_count > 0
					? $this->review_count
					: (int) get_post_meta( $this->product_id, '_wc_review_count', true );

		$this->product_name = $this->product->get_name();
		$this->product_url  = get_permalink( $this->product_id );

		/**
		 * ❗Exit clean if no rating exists, prevents invalid schema
		 */
		if ( $this->average_rating <= 0 || $this->review_count <= 0 ) {
			return; // keep → $schema = null (safe fallback)
		}

		/**
		 * Determine best/worst rating via filters (allow dynamic override) or default to 5/1
		 */
		$best_rating = apply_filters( 'vserpb_best_rating', 5 );
		$worst_rating = apply_filters( 'vserpb_worst_rating', 1 );

		// Ensure numeric and sensible values
		$best_rating = is_numeric( $best_rating ) ? floatval( $best_rating ) : 5;
		$worst_rating = is_numeric( $worst_rating ) ? floatval( $worst_rating ) : 1;

		// Prepare human-friendly strings used in description/explanation
		$avg_display = round( $this->average_rating, 1 );
		$review_count_display = (int) $this->review_count;

		$description = sprintf( 'Average rating from %d customer reviews.', $review_count_display );
		$rating_explanation = sprintf( '%s out of %s based on %d customer ratings.', $avg_display, $best_rating, $review_count_display );

		/**
		 * Product image (fallback to post thumbnail)
		 */
		$image = get_the_post_thumbnail_url( $this->product_id, 'full' );

		/**
		 * 🔥 FINAL RATING SCHEMA
		 */
		$this->schema = array(
			'@type'        => 'AggregateRating',
			'ratingValue'  => $this->average_rating,
			'ratingCount'  => $this->rating_count,
			'reviewCount'  => $review_count_display,
			'name'         => $this->product_name . ' Rating',
			'url'          => $this->product_url,
			'identifier'   => ( new Vserpb_PropertyValue( $this->product_id ) )->vserpb_getSchema(),

			// new requested sub-properties
			'description' => $description,
			'image'       => $image ? esc_url( $image ) : null,
			'bestRating'  => $best_rating,
			'worstRating' => $worst_rating,
			'ratingExplanation' => $rating_explanation,


			'author' => array(
				'@type' => 'Organization',
				'name'  => get_bloginfo( 'name' ),
			),
			'mainEntityOfPage'    => array(
					'@type' => 'WebPage',
					'@id'   => $this->product_url,
				),
			"potentialAction" => array(
				'@type'=> "ReviewAction",
				'target'=> $this->product_url . '#reviews',
			),
		);
	}

	/**
	 * Return full schema
	 */
	public function vserpb_getSchema() {
		return $this->schema; // null if no rating → valid safe output
	}

	/**
	 * Return specific parts of rating if needed
	 */
	public function vserpb_getSchemaByProperties( ...$properties ) {

		if ( empty( $this->schema ) ) return null;

		$schema = array( '@type' => 'AggregateRating' );

		foreach ( $properties as $property ) {
			switch ( $property ) {
				case 'ratingValue': $schema['ratingValue'] = $this->average_rating; break;
				case 'reviewCount': $schema['reviewCount'] = $this->review_count; break;
				case 'name':        $schema['name']        = $this->product_name . ' Rating'; break;
				case 'description': $schema['description'] = sprintf( 'Average rating from %d customer reviews.', (int) $this->review_count ); break;
				case 'image':       $schema['image'] = get_the_post_thumbnail_url( $this->product_id, 'full' ); break;
				case 'bestRating':  $schema['bestRating'] = apply_filters( 'vserpb_best_rating', 5 ); break;
				case 'worstRating': $schema['worstRating'] = apply_filters( 'vserpb_worst_rating', 1 ); break;
				case 'ratingExplanation': $schema['ratingExplanation'] = sprintf( '%s out of %s based on %d customer ratings.', round( $this->average_rating, 1 ), apply_filters( 'vserpb_best_rating', 5 ), (int) $this->review_count ); break;
			}
		}

		return $schema;
	}
}
