<?php
/**
 * Listing quality score calculator.
 *
 * Calculates a 0-100 quality score for vehicle listings based on
 * completeness of data. Stores the result in the specs table.
 *
 * @package ThemeREX\AutoDealer
 */

declare(strict_types=1);

namespace ThemeREX\AutoDealer\Admin;

defined( 'ABSPATH' ) || exit;
use ThemeREX\AutoDealer\Database\VehicleSpecsSync;
use ThemeREX\AutoDealer\PostTypes\VehiclePostType;

class ListingQualityScore {

	/**
	 * Specs sync instance.
	 *
	 * @var VehicleSpecsSync
	 */
	private VehicleSpecsSync $specsSync;

	/**
	 * Constructor.
	 *
	 * @param VehicleSpecsSync $specsSync Specs sync instance.
	 */
	public function __construct( VehicleSpecsSync $specsSync ) {
		$this->specsSync = $specsSync;
	}

	/**
	 * Register hooks.
	 *
	 * Runs after VehicleSpecsSync (priority 20), so we use priority 30.
	 *
	 * @return void
	 */
	public function register(): void {
		add_action(
			'save_post_' . VehiclePostType::POST_TYPE,
			array( $this, 'calculateAndStore' ),
			30,
			1
		);
	}

	/**
	 * Calculate the quality score and store it.
	 *
	 * @param int $postId Post ID.
	 * @return int The calculated score (0-100).
	 */
	public function calculateAndStore( int $postId ): int {
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return 0;
		}

		if ( wp_is_post_revision( $postId ) ) {
			return 0;
		}

		$score = $this->calculate( $postId );

		// Update only the listing_quality column.
		global $wpdb;
		$table = $wpdb->prefix . 'trx_ad_vehicle_specs';

		$wpdb->update(
			$table,
			array( 'listing_quality' => $score ),
			array( 'post_id' => $postId ),
			array( '%d' ),
			array( '%d' )
		);

		/**
		 * Fires after the listing quality score is calculated and stored.
		 *
		 * @param int $postId Post ID.
		 * @param int $score  Calculated score (0-100).
		 */
		do_action( 'trx_ad_listing_quality_calculated', $postId, $score );

		return $score;
	}

	/**
	 * Calculate the quality score for a vehicle.
	 *
	 * Scoring breakdown:
	 * - Has featured image:     +20
	 * - Has VIN:                +15
	 * - Has description > 50c:  +15
	 * - Has feature terms:      +10
	 * - Has price > 0:          +15
	 * - All key specs filled:   +25
	 *
	 * @param int $postId Post ID.
	 * @return int Score between 0 and 100.
	 */
	public function calculate( int $postId ): int {
		$score = 0;
		$post  = get_post( $postId );

		if ( ! $post instanceof \WP_Post ) {
			return 0;
		}

		$specs = $this->specsSync->getSpecs( $postId );

		// 1. Has featured image: +20
		if ( has_post_thumbnail( $postId ) ) {
			$score += 20;
		}

		// 2. Has VIN: +15
		if ( $specs !== null && ! empty( $specs->vin ) && strlen( (string) $specs->vin ) > 0 ) {
			$score += 15;
		}

		// 3. Has description (post_content > 50 chars): +15
		$contentLength = mb_strlen( trim( wp_strip_all_tags( $post->post_content ) ) );
		if ( $contentLength > 50 ) {
			$score += 15;
		}

		// 4. Has features (any trx_ad_feature terms assigned): +10
		$features = wp_get_object_terms( $postId, 'trx_ad_feature', array( 'fields' => 'ids' ) );
		if ( ! is_wp_error( $features ) && count( $features ) > 0 ) {
			$score += 10;
		}

		// 5. Has price > 0: +15
		if ( $specs !== null && ! empty( $specs->price ) && (float) $specs->price > 0 ) {
			$score += 15;
		}

		// 6. All key specs filled (year, make, model, fuel_type, transmission, mileage): +25
		if ( $specs !== null ) {
			$keySpecs = array(
				$specs->year ?? null,
				$specs->make ?? null,
				$specs->model ?? null,
				$specs->fuel_type ?? null,
				$specs->transmission ?? null,
				$specs->mileage ?? null,
			);

			$allFilled = true;
			foreach ( $keySpecs as $value ) {
				if ( $value === null || $value === '' || $value === '0' ) {
					$allFilled = false;
					break;
				}
			}

			if ( $allFilled ) {
				$score += 25;
			}
		}

		// Clamp to 0-100.
		return min( 100, max( 0, $score ) );
	}
}
