<?php
/**
 * Post-Type Sitemap
 *
 * Generates individual post-type sub-sitemaps.
 *
 * @package SEOvaultSEO
 */

namespace SEOvaultSEO\Sitemap;

use SEOvaultSEO\Core\Options;

/**
 * Builds post-type sub-sitemaps
 */
class PostType {

	/**
	 * Output a post-type sub-sitemap.
	 *
	 * @param string $slug Sitemap slug.
	 * @param int    $page Page number.
	 */
	public static function output( $slug, $page ) {
		$post_type = self::parse_slug( $slug );
		if ( false === $post_type ) {
			Router::send_404();
			return;
		}

		$enabled = Options::get_sitemap_post_types();
		if ( ! in_array( $post_type, $enabled, true ) ) {
			Router::send_404();
			return;
		}

		$page = max( 1, (int) $page );

		$cache_key = 'sitemap/' . $post_type . '-page-' . $page . '.xml';
		$cached    = Cache::get( $cache_key );
		if ( false !== $cached ) {
			Renderer::set_stylesheet_url( home_url( '/seovault-sitemap.xsl' ) );
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Pre-built XML sitemap output.
			echo $cached;
			return;
		}

		$urls = self::build_urls( $post_type, $page );
		$xml  = self::render( $urls );
		Cache::store( $cache_key, $xml );
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Pre-built XML sitemap output.
		echo $xml;
	}

	/**
	 * Parse the slug to extract the post type.
	 *
	 * @param string $slug Slug.
	 * @return string|false
	 */
	public static function parse_slug( $slug ) {
		$slug = Sanitizer::slug( $slug );
		if ( '' === $slug ) {
			return false;
		}

		$public = Query::get_public_post_types();
		if ( in_array( $slug, $public, true ) ) {
			return $slug;
		}

		return false;
	}

	/**
	 * Build URL array for the requested page.
	 *
	 * @param string $post_type Post type.
	 * @param int    $page Page.
	 * @return array
	 */
	public static function build_urls( $post_type, $page ) {
		$per_page = Options::get_sitemap_entries_per_page();
		$ids      = Query::get_post_type_ids( $post_type, $page, $per_page );
		$urls     = array();
		$images   = Options::is_sitemap_images_enabled();

		foreach ( $ids as $post_id ) {
			if ( ! Query::is_post_indexed( $post_id ) ) {
				continue;
			}
			$url = get_permalink( $post_id );
			if ( false === $url ) {
				continue;
			}
			$item = array(
				'loc'     => $url,
				'lastmod' => get_the_modified_date( 'Y-m-d\TH:i:sP', $post_id ),
			);
			if ( $images ) {
				$item['images'] = Images::get_for_post( $post_id );
			}
			$urls[] = $item;
		}

		if ( 1 === $page ) {
			$urls = array_merge( self::get_front_page_urls(), $urls );
		}

		return $urls;
	}

	/**
	 * Get front page URLs (included on the posts sitemap page 1).
	 *
	 * Post-type archive landing pages live in {@see Archives}.
	 *
	 * @return array
	 */
	private static function get_front_page_urls() {
		$urls = array();

		if ( 'page' !== get_option( 'show_on_front' ) ) {
			$urls[] = array(
				'loc'     => home_url( '/' ),
				'lastmod' => gmdate( 'Y-m-d\TH:i:sP' ),
			);
		} else {
			$front_page_id = (int) get_option( 'page_on_front' );
			if ( $front_page_id > 0 ) {
				$urls[] = array(
					'loc'     => get_permalink( $front_page_id ),
					'lastmod' => get_the_modified_date( 'Y-m-d\TH:i:sP', $front_page_id ),
				);
			}
		}

		return $urls;
	}

	/**
	 * Render URLs to XML.
	 *
	 * @param array $urls URLs.
	 * @return string
	 */
	private static function render( $urls ) {
		Renderer::set_stylesheet_url( home_url( '/seovault-sitemap.xsl' ) );
		return Renderer::urlset( $urls );
	}

	/**
	 * Build a URL array structure (helper for tests).
	 *
	 * @return array
	 */
	public static function build_url_array_structure() {
		return array(
			'loc'     => 'http://example.com/post',
			'lastmod' => '2026-01-01T00:00:00+00:00',
			'images'  => array(),
		);
	}
}
