<?php
/**
 * Taxonomy Sitemap
 *
 * Generates taxonomy sub-sitemaps.
 *
 * @package SEOvaultSEO
 */

namespace SEOvaultSEO\Sitemap;

use SEOvaultSEO\Core\Options;

/**
 * Builds taxonomy sub-sitemaps
 */
class Taxonomy {

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

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

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

		$cache_key = 'sitemap/taxonomy-' . $taxonomy . '-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( $taxonomy, $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 taxonomy.
	 *
	 * @param string $slug Slug.
	 * @return string|false
	 */
	public static function parse_slug( $slug ) {
		$slug = Sanitizer::slug( $slug );
		if ( '' === $slug ) {
			return false;
		}

		$prefix = 'taxonomy-';
		if ( 0 === strpos( $slug, $prefix ) ) {
			$slug = substr( $slug, strlen( $prefix ) );
		}

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

		return false;
	}

	/**
	 * Build URL array for the requested page.
	 *
	 * @param string $taxonomy Taxonomy.
	 * @param int    $page Page.
	 * @return array
	 */
	public static function build_urls( $taxonomy, $page ) {
		$per_page = Options::get_sitemap_entries_per_page();
		$ids      = Query::get_term_ids( $taxonomy, $page, $per_page );
		$urls     = array();

		foreach ( $ids as $term_id ) {
			if ( ! Query::is_term_indexed( $term_id ) ) {
				continue;
			}
			$url = get_term_link( (int) $term_id, $taxonomy );
			if ( is_wp_error( $url ) ) {
				continue;
			}
			$urls[] = array(
				'loc'     => $url,
				'lastmod' => gmdate( 'Y-m-d\TH:i:sP' ),
			);
		}

		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 );
	}
}
