<?php
/**
 * User-facing Schema Health status vocabulary.
 *
 * @package SEOvaultSEO\Schema\Validation
 */

namespace SEOvaultSEO\Schema\Validation;

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

/**
 * Maps internal validation states to the three published-schema statuses.
 */
class SchemaHealthStatus {

	const HEALTHY                 = 'healthy';
	const IMPROVEMENTS_AVAILABLE  = 'improvements_available';
	const ACTION_REQUIRED         = 'action_required';
	const NO_SCHEMA               = 'no_schema';
	const NOT_CHECKED             = 'not_checked';
	const UNAVAILABLE             = 'unavailable';
	const AVAILABLE_AFTER_PUBLISH = 'available_after_publishing';

	/**
	 * Resolve the published-schema user status from a validation response.
	 *
	 * Setup diagnostics are intentionally ignored here — they render separately.
	 *
	 * @param array $validation Validation response (state/result/build).
	 * @return string
	 */
	public static function resolve_published( array $validation ) {
		$state  = isset( $validation['state'] ) ? (string) $validation['state'] : self::NOT_CHECKED;
		$result = isset( $validation['result'] ) && is_array( $validation['result'] ) ? $validation['result'] : array();
		$build  = isset( $validation['build'] ) && is_array( $validation['build'] ) ? $validation['build'] : array();

		if ( self::NOT_CHECKED === $state || 'not_checked' === ( $result['status'] ?? '' ) ) {
			return self::NOT_CHECKED;
		}
		if ( self::UNAVAILABLE === $state ) {
			return self::UNAVAILABLE;
		}
		if ( self::NO_SCHEMA === $state || 'no_schema' === ( $result['status'] ?? '' ) ) {
			return self::NO_SCHEMA;
		}

		$errors          = isset( $result['errors'] ) ? (int) $result['errors'] : 0;
		$warnings        = isset( $result['warnings'] ) ? (int) $result['warnings'] : 0;
		$recommendations = isset( $result['recommendations'] ) ? (int) $result['recommendations'] : 0;
		$improvements    = isset( $build['improvements'] ) && is_array( $build['improvements'] ) ? $build['improvements'] : array();

		if ( $errors > 0 || 'invalid' === $state ) {
			return self::ACTION_REQUIRED;
		}
		if ( $warnings > 0 || 'warning' === $state ) {
			return self::ACTION_REQUIRED;
		}
		if ( $recommendations > 0 || 'valid_with_recommendations' === $state || ! empty( $improvements ) ) {
			return self::IMPROVEMENTS_AVAILABLE;
		}

		return self::HEALTHY;
	}

	/**
	 * Resolve a live/published-page comparison status.
	 *
	 * @param array|null $live Live validation response.
	 * @return string
	 */
	public static function resolve_live( $live ) {
		if ( ! is_array( $live ) || empty( $live['state'] ) ) {
			return self::NOT_CHECKED;
		}

		$state = (string) $live['state'];
		if ( 'matches' === $state ) {
			return self::HEALTHY;
		}
		if ( 'differs' === $state ) {
			return self::ACTION_REQUIRED;
		}
		if ( 'not_public' === $state ) {
			return self::AVAILABLE_AFTER_PUBLISH;
		}
		if ( 'unavailable' === $state ) {
			return self::UNAVAILABLE;
		}

		return self::NOT_CHECKED;
	}

	/**
	 * Whether the status should use failure styling.
	 *
	 * Recommendations / improvements never return true.
	 *
	 * @param string $status User-facing status.
	 * @return bool
	 */
	public static function is_failure( $status ) {
		return in_array(
			(string) $status,
			array( self::ACTION_REQUIRED, self::UNAVAILABLE ),
			true
		);
	}

	/**
	 * CSS-safe status keys used by the panel.
	 *
	 * @return string[]
	 */
	public static function all() {
		return array(
			self::HEALTHY,
			self::IMPROVEMENTS_AVAILABLE,
			self::ACTION_REQUIRED,
			self::NO_SCHEMA,
			self::NOT_CHECKED,
			self::UNAVAILABLE,
			self::AVAILABLE_AFTER_PUBLISH,
		);
	}
}
