<?php
/**
 * Performance Service
 * Handles frontend performance optimizations for LCP, CLS, and resource hints
 *
 * @package Brandy\Core\Services
 * @since 1.5.0
 */

namespace Brandy\Core\Services;

use Brandy\Traits\SingletonTrait;

defined( 'ABSPATH' ) || exit;

/**
 * PerformanceService class
 * Provides performance optimizations:
 * - LCP image detection and fetchpriority
 * - Lazy-loading control for above-fold images
 * - Preload hints for critical resources
 *
 * @since 1.5.0
 */
class PerformanceService {
	use SingletonTrait;

	/**
	 * Track product index in loop for LCP detection
	 *
	 * @var int
	 */
	private static $product_index = 0;

	/**
	 * Track post index in loop for LCP detection
	 *
	 * @var int
	 */
	private static $post_index = 0;

	/**
	 * Number of items to consider as LCP candidates (above fold)
	 *
	 * @var int
	 */
	const LCP_CANDIDATE_COUNT = 4;

	/**
	 * Constructor
	 */
	protected function __construct() {
		// Reset counters on new queries
		add_action( 'loop_start', array( $this, 'reset_counters' ) );

		// Optimize image attributes for LCP
		add_filter( 'wp_get_attachment_image_attributes', array( $this, 'optimize_image_attributes' ), 10, 3 );

		// Remove lazy-loading from above-fold images (WordPress default filter)
		add_filter( 'wp_img_tag_add_loading_attr', array( $this, 'maybe_skip_lazy_loading' ), 10, 3 );

		// Add preload hints for fonts
		add_action( 'wp_head', array( $this, 'add_font_preload_hints' ), 1 );
	}

	/**
	 * Reset loop counters for new queries
	 *
	 * @param \WP_Query $query The query object.
	 */
	public function reset_counters( $query ) {
		if ( $query->is_main_query() ) {
			self::$product_index = 0;
			self::$post_index    = 0;
		}
	}

	/**
	 * Check if current item is an LCP candidate (above the fold)
	 *
	 * @param string $context Context type (product, post, etc.).
	 * @return bool Whether the item is an LCP candidate.
	 */
	public static function is_lcp_candidate( $context = 'product' ) {
		// Homepage hero and first few products are LCP candidates
		if ( is_front_page() || ( function_exists( 'is_shop' ) && is_shop() ) ) {
			if ( 'product' === $context ) {
				return self::$product_index < self::LCP_CANDIDATE_COUNT;
			}
		}

		// First post on archive pages
		if ( is_archive() || is_home() ) {
			if ( 'post' === $context ) {
				return self::$post_index < 1;
			}
		}

		return false;
	}

	/**
	 * Increment product counter
	 */
	public static function increment_product_index() {
		self::$product_index++;
	}

	/**
	 * Increment post counter
	 */
	public static function increment_post_index() {
		self::$post_index++;
	}

	/**
	 * Get current product index
	 *
	 * @return int Current product index.
	 */
	public static function get_product_index() {
		return self::$product_index;
	}

	/**
	 * Optimize image attributes for performance
	 *
	 * @param array   $attr       Image attributes.
	 * @param WP_Post $attachment Attachment post object.
	 * @param string  $size       Requested image size.
	 * @return array Modified attributes.
	 */
	public function optimize_image_attributes( $attr, $attachment, $size ) {
		// Add decoding async for all images (improves render performance)
		if ( ! isset( $attr['decoding'] ) ) {
			$attr['decoding'] = 'async';
		}

		return $attr;
	}

	/**
	 * Skip lazy loading for above-fold images
	 *
	 * @param string|false $value   The loading attribute value.
	 * @param string       $image   The HTML img tag.
	 * @param string       $context Context for the image.
	 * @return string|false Modified loading attribute.
	 */
	public function maybe_skip_lazy_loading( $value, $image, $context ) {
		// Skip lazy loading for site logo
		if ( strpos( $image, 'custom-logo' ) !== false ) {
			return false;
		}

		// Skip lazy loading for header images
		if ( strpos( $image, 'header-image' ) !== false ) {
			return false;
		}

		return $value;
	}

	/**
	 * Add preload hints for critical fonts
	 */
	public function add_font_preload_hints() {
		// Only output if not in admin
		if ( is_admin() ) {
			return;
		}

		// Preload system fonts hint (browser will optimize)
		// Note: Custom fonts should be added here if used
		$fonts = apply_filters( 'brandy_preload_fonts', array() );

		foreach ( $fonts as $font ) {
			if ( ! empty( $font['href'] ) ) {
				printf(
					'<link rel="preload" href="%s" as="font" type="%s" crossorigin>%s',
					esc_url( $font['href'] ),
					esc_attr( $font['type'] ?? 'font/woff2' ),
					"\n"
				);
			}
		}
	}

	/**
	 * Get image attributes optimized for LCP
	 *
	 * @param bool $is_lcp_candidate Whether this image is an LCP candidate.
	 * @return array Image attributes.
	 */
	public static function get_lcp_image_attrs( $is_lcp_candidate = false ) {
		if ( $is_lcp_candidate ) {
			return array(
				'loading'       => false, // Disable lazy loading
				'fetchpriority' => 'high',
				'decoding'      => 'async',
			);
		}

		return array(
			'loading'  => 'lazy',
			'decoding' => 'async',
		);
	}
}
