<?php
/**
 * Frontend Feed Optimizations
 *
 * @package SEOvaultSEO
 */

namespace SEOvaultSEO\Frontend;

use SEOvaultSEO\Core\Options;

/**
 * Provides optional feed modifications: excerpting content,
 * appending a source backlink, and sending X-Robots-Tag: noindex.
 */
class Feed {

	/**
	 * Initialize feed hooks.
	 */
	public static function init() {
		if ( ! \SEOvaultSEO\Compatibility\Detector::should_output_seo() ) {
			return;
		}

		add_action( 'template_redirect', array( __CLASS__, 'output_robots_noindex_headers_on_feed' ), 10 );
		add_filter( 'the_content_feed', array( __CLASS__, 'modify_the_content_feed' ), 10, 2 );
		add_filter( 'the_excerpt_rss', array( __CLASS__, 'modify_the_excerpt_rss' ), 10 );
	}

	/**
	 * Send X-Robots-Tag: noindex header on feeds when enabled.
	 *
	 * @hook template_redirect 10
	 */
	public static function output_robots_noindex_headers_on_feed() {
		if ( ! is_feed() ) {
			return;
		}

		if ( ! Options::is_feed_noindex() ) {
			return;
		}

		if ( headers_sent() ) {
			return;
		}

		header( 'X-Robots-Tag: noindex, nofollow', true );
	}

	/**
	 * Modify feed content: optionally excerpt and append source link.
	 *
	 * @hook the_content_feed 10
	 *
	 * @param string      $content   Feed content.
	 * @param null|string $feed_type Feed type (only set on the_content_feed filter).
	 * @return string
	 */
	public static function modify_the_content_feed( $content = '', $feed_type = null ) {
		if ( empty( $content ) ) {
			return '';
		}

		if ( Options::is_feed_excerpt_enabled() ) {
			$content = self::excerpt_content( $content );
		}

		if ( Options::is_feed_source_link_enabled() ) {
			$content = self::append_source_link( $content );
		}

		return $content;
	}

	/**
	 * Modify feed excerpt: optionally append source link.
	 *
	 * @hook the_excerpt_rss 10
	 *
	 * @param string $content Feed excerpt.
	 * @return string
	 */
	public static function modify_the_excerpt_rss( $content = '' ) {
		if ( empty( $content ) ) {
			return '';
		}

		// Excerpt conversion is not applied here because WordPress already
		// provides the excerpt. Only the source link is appended.
		if ( Options::is_feed_source_link_enabled() ) {
			$content = self::append_source_link( $content );
		}

		return $content;
	}

	/**
	 * Convert full content to an excerpt of configured length.
	 *
	 * @param string $content Full post content.
	 * @return string Excerpted content wrapped in <p> tags.
	 */
	private static function excerpt_content( $content ) {
		$clamp_length = (int) apply_filters( 'seovaultseo_feed_excerpt_length', Options::get_feed_excerpt_length() );

		if ( $clamp_length < 1 ) {
			$clamp_length = 400;
		}

		// Strip shortcodes, tags, and excessive whitespace.
		$text = wp_strip_all_tags( strip_shortcodes( $content ) );
		$text = trim( preg_replace( '/\s+/', ' ', $text ) );

		// Multibyte-safe truncation.
		if ( function_exists( 'mb_strlen' ) && mb_strlen( $text ) > $clamp_length ) {
			$text = mb_substr( $text, 0, $clamp_length );
			$text = preg_replace( '/ [^ ]*$/', '', $text );
			$text = trim( $text ) . '...';
		} elseif ( strlen( $text ) > $clamp_length ) {
			$text = substr( $text, 0, $clamp_length );
			$text = preg_replace( '/ [^ ]*$/', '', $text );
			$text = trim( $text ) . '...';
		}

		return '<p>' . esc_html( $text ) . '</p>';
	}

	/**
	 * Append a nofollow source backlink to feed content.
	 *
	 * @param string $content Feed content.
	 * @return string
	 */
	private static function append_source_link( $content ) {
		$permalink = get_permalink();

		if ( empty( $permalink ) ) {
			return $content;
		}

		$link_text = apply_filters( 'seovaultseo_feed_source_link_text', __( 'Source', 'seovault-ai' ) );

		$content .= sprintf(
			"\n" . '<p><a href="%s" rel="nofollow">%s</a></p>',
			esc_url( $permalink ),
			esc_html( $link_text )
		);

		return $content;
	}
}
