<?php
/**
 * NotFound recovery page content builder.
 *
 * @package SEOvaultSEO\NotFound
 */

namespace SEOvaultSEO\NotFound;

use SEOvaultSEO\Core\Options;

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

/**
 * Builds structured data for the recovery template.
 */
class RecoveryContent {

	/**
	 * Initialize content builder hooks if needed.
	 *
	 * Stub — no hooks in Phase 2.
	 */
	public static function init() {
	}

	/**
	 * Build recovery template data without rendering markup.
	 *
	 * @return array{
	 *     headline:string,
	 *     message:string,
	 *     show_search:bool,
	 *     show_home_cta:bool,
	 *     home_url:string,
	 *     cta_label:string,
	 *     cta_url:string,
	 *     show_recent:bool,
	 *     recent_posts:array<int, array{title:string,url:string}>,
	 *     use_theme_colors:bool,
	 *     accent:string,
	 *     content_mode:string,
	 *     page_body_html:string
	 * }
	 */
	public static function get() {
		$home_url       = home_url( '/' );
		$show_recent    = Options::is_notfound_recovery_show_recent();
		$cta_url        = Options::get_notfound_recovery_cta_url();
		$content_mode   = Options::get_notfound_recovery_content_mode();
		$page_body_html = self::resolve_page_body_html( $content_mode );

		return array(
			'headline'         => Options::get_notfound_recovery_headline(),
			'message'          => Options::get_notfound_recovery_message(),
			'show_search'      => Options::is_notfound_recovery_show_search(),
			'show_home_cta'    => Options::is_notfound_recovery_show_home_cta(),
			'home_url'         => $home_url,
			'cta_label'        => Options::get_notfound_recovery_cta_label(),
			'cta_url'          => '' !== $cta_url ? $cta_url : $home_url,
			'show_recent'      => $show_recent,
			'recent_posts'     => $show_recent ? self::get_recent_posts() : array(),
			'use_theme_colors' => Options::is_notfound_recovery_use_theme_colors(),
			'accent'           => Options::get_notfound_recovery_accent(),
			'content_mode'     => $content_mode,
			'page_body_html'   => $page_body_html,
		);
	}

	/**
	 * Resolve custom page body HTML for page content mode.
	 *
	 * Returns an empty string when mode is builtin, the page is missing,
	 * or the page is not a published Page — callers then use builtin copy.
	 *
	 * @param string $content_mode Sanitized content mode.
	 * @return string
	 */
	private static function resolve_page_body_html( $content_mode ) {
		if ( 'page' !== $content_mode ) {
			return '';
		}

		$page_id = Options::get_notfound_recovery_page_id();
		if ( $page_id <= 0 ) {
			return '';
		}

		$page = get_post( $page_id );
		if ( ! $page instanceof \WP_Post ) {
			return '';
		}

		if ( 'page' !== $page->post_type || 'publish' !== $page->post_status ) {
			return '';
		}

		return self::render_page_body( $page );
	}

	/**
	 * Render a published page's content for the recovery chrome.
	 *
	 * Shortcodes are stripped before `the_content` so third-party shortcodes
	 * cannot run side effects on a public 404 response. Remaining HTML still
	 * passes through `the_content` (autop, embeds, etc.).
	 *
	 * @param \WP_Post $page Published page.
	 * @return string
	 */
	private static function render_page_body( \WP_Post $page ) {
		$raw = (string) $page->post_content;
		if ( '' === $raw ) {
			return '';
		}

		$raw = strip_shortcodes( $raw );

		$previous_post = isset( $GLOBALS['post'] ) ? $GLOBALS['post'] : null;
		// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Temporary for the_content filters.
		$GLOBALS['post'] = $page;
		setup_postdata( $page );

		// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Intentional core the_content pipeline (autop/embeds) for recovery page HTML.
		$html = apply_filters( 'the_content', $raw );

		if ( $previous_post instanceof \WP_Post ) {
			// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
			$GLOBALS['post'] = $previous_post;
			setup_postdata( $previous_post );
		} else {
			wp_reset_postdata();
			// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
			unset( $GLOBALS['post'] );
		}

		return is_string( $html ) ? $html : '';
	}

	/**
	 * Get the configured number of recent published posts.
	 *
	 * @return array<int, array{title:string,url:string}>
	 */
	private static function get_recent_posts() {
		$posts = get_posts(
			array(
				'post_type'              => 'post',
				'post_status'            => 'publish',
				'posts_per_page'         => Options::get_notfound_recovery_recent_count(),
				'orderby'                => 'date',
				'order'                  => 'DESC',
				'no_found_rows'          => true,
				'update_post_meta_cache' => false,
				'update_post_term_cache' => false,
			)
		);

		$recent_posts = array();
		foreach ( $posts as $post ) {
			if ( ! $post instanceof \WP_Post ) {
				continue;
			}

			$url = get_permalink( $post );
			if ( ! is_string( $url ) || '' === $url ) {
				continue;
			}

			$recent_posts[] = array(
				'title' => get_the_title( $post ),
				'url'   => $url,
			);
		}

		return $recent_posts;
	}
}
