<?php

/**
 * The public-facing functionality of the plugin.
 *
 * @link       https://yourwebsite.com
 * @since      1.0.0
 *
 * @package    CSPG_Basic_SEO_Helper
 * @subpackage CSPG_Basic_SEO_Helper/public
 */

// If this file is called directly, abort.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * The public-facing functionality of the plugin.
 *
 * Defines the plugin name, version, and two examples hooks for how to
 * enqueue the public-facing stylesheet and JavaScript.
 *
 * @package    CSPG_Basic_SEO_Helper
 * @subpackage CSPG_Basic_SEO_Helper/public
 * @author     CSP Geeks LLC <info@cspgeeks.com>
 */
class CSPG_Basic_SEO_Helper_Public {

	/**
	 * The ID of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $plugin_name    The ID of this plugin.
	 */
	private $plugin_name;

	/**
	 * The version of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $version    The current version of this plugin.
	 */
	private $version;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 * @param      string    $plugin_name       The name of the plugin.
	 * @param      string    $version    The version of this plugin.
	 */
	public function __construct( $plugin_name, $version ) {

		$this->plugin_name = $plugin_name;
		$this->version     = $version;
	}

	/**
	 * Register the stylesheets for the public-facing side of the site.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_styles() {
		wp_enqueue_style( $this->plugin_name, CSPG_BASIC_SEO_HELPER_PLUGIN_URL . 'assets/css/public.css', array(), $this->version, 'all' );
	}

	/**
	 * Register the JavaScript for the public-facing side of the site.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_scripts() {
		wp_enqueue_script( $this->plugin_name, CSPG_BASIC_SEO_HELPER_PLUGIN_URL . 'assets/js/public.js', array( 'jquery' ), $this->version, false );
	}

	/**
	 * Remove WordPress default canonical link if plugin canonical is enabled
	 *
	 * @since    1.2.11
	 */
	public function remove_wp_canonical() {
		$canonical_enabled = get_option( 'cspgbase_enable_canonical', '1' );
		if ( '1' === $canonical_enabled ) {
			remove_action( 'wp_head', 'rel_canonical' );
		}
	}

	/**
	 * Add SEO meta tags to the head section
	 *
	 * @since    1.0.0
	 */
	public function add_seo_meta_tags() {
		$options = get_option( 'cspgbase_options', array() );

		// Get current page information
		$title       = $this->get_page_title();
		$description = $this->get_page_description();
		$image       = $this->get_page_image();
		$url         = $this->get_canonical_url();
		$type        = $this->get_page_type();

		// Standard Meta Description tag
		echo "\n<!-- Basic SEO Helper - Standard Meta Tags -->\n";
		echo '<meta name="description" content="' . esc_attr( $description ) . '">' . "\n";

		// Robots meta tag (only output if non-default)
		$this->output_robots_meta_tag();

		// Check if Open Graph is enabled (default: enabled)
		$og_enabled = get_option( 'cspgbase_enable_open_graph', '1' );
		if ( '1' === $og_enabled ) {
			// Get platform-specific values
			$og_title       = $this->get_og_title();
			$og_description = $this->get_og_description();

			// Output Open Graph meta tags
			echo "\n<!-- Basic SEO Helper - Open Graph Meta Tags -->\n";
			echo '<meta property="og:title" content="' . esc_attr( $og_title ) . '">' . "\n";
			echo '<meta property="og:description" content="' . esc_attr( $og_description ) . '">' . "\n";
			echo '<meta property="og:image" content="' . esc_attr( $image ) . '">' . "\n";
			echo '<meta property="og:url" content="' . esc_attr( $url ) . '">' . "\n";
			echo '<meta property="og:type" content="' . esc_attr( $type ) . '">' . "\n";
			echo '<meta property="og:site_name" content="' . esc_attr( get_bloginfo( 'name' ) ) . '">' . "\n";
			echo '<meta property="og:locale" content="' . esc_attr( $this->get_og_locale() ) . '">' . "\n";

			// Facebook App ID
			if ( ! empty( $options['facebook_app_id'] ) ) {
				echo '<meta property="fb:app_id" content="' . esc_attr( $options['facebook_app_id'] ) . '">' . "\n";
			}
		}

		// Check if Twitter Cards are enabled (default: enabled)
		$twitter_enabled = get_option( 'cspgbase_enable_twitter_cards', '1' );
		if ( '1' === $twitter_enabled ) {
			// Get platform-specific values
			$twitter_title       = $this->get_twitter_title();
			$twitter_description = $this->get_twitter_description();

			// Twitter Card meta tags
			echo "\n<!-- Basic SEO Helper - Twitter Card Meta Tags -->\n";
			echo '<meta name="twitter:card" content="summary_large_image">' . "\n";
			echo '<meta name="twitter:title" content="' . esc_attr( $twitter_title ) . '">' . "\n";
			echo '<meta name="twitter:description" content="' . esc_attr( $twitter_description ) . '">' . "\n";
			echo '<meta name="twitter:image" content="' . esc_attr( $image ) . '">' . "\n";

			// Twitter username
			if ( ! empty( $options['twitter_username'] ) ) {
				echo '<meta name="twitter:site" content="' . esc_attr( $options['twitter_username'] ) . '">' . "\n";
			}
		}

		// Canonical URL (only if enabled)
		$canonical_enabled = get_option( 'cspgbase_enable_canonical', '1' );
		if ( '1' === $canonical_enabled ) {
			echo "\n<!-- Basic SEO Helper - Additional Meta Tags -->\n";
			echo '<link rel="canonical" href="' . esc_url( $url ) . '">' . "\n";
		}

		// Author link (only if enabled)
		$author_meta_enabled = get_option( 'cspgbase_enable_author_meta', '1' );
		if ( '1' === $author_meta_enabled && ! empty( $options['author_url'] ) ) {
			echo '<link rel="author" href="' . esc_url( $options['author_url'] ) . '">' . "\n";
		}

		// Schema.org structured data
		$this->add_schema_markup();
	}

	/**
	 * Get the current page title
	 *
	 * @since    1.0.0
	 * @return   string    The page title
	 */
	private function get_page_title() {
		// Check for custom meta title first
		if ( is_single() || is_page() ) {
			global $post;
			$custom_title = get_post_meta( $post->ID, '_basic_seo_helper_title', true );
			if ( ! empty( $custom_title ) ) {
				return $custom_title;
			}
			return get_the_title();
		} elseif ( is_home() || is_front_page() ) {
			return get_bloginfo( 'name' ) . ' - ' . get_bloginfo( 'description' );
		} elseif ( is_category() ) {
			return single_cat_title( '', false );
		} elseif ( is_tag() ) {
			return single_tag_title( '', false );
		} elseif ( is_archive() ) {
			return get_the_archive_title();
		} else {
			return get_bloginfo( 'name' );
		}
	}

	/**
	 * Get the current page description
	 *
	 * @since    1.0.0
	 * @return   string    The page description
	 */
	private function get_page_description() {
		// Check for custom meta description first
		if ( is_single() || is_page() ) {
			global $post;
			$custom_description = get_post_meta( $post->ID, '_basic_seo_helper_description', true );
			if ( ! empty( $custom_description ) ) {
				return $custom_description;
			}

			$excerpt = get_the_excerpt();
			if ( ! empty( $excerpt ) ) {
				return wp_strip_all_tags( $excerpt );
			}
			// Fallback to content excerpt
			$content = get_the_content();
			return wp_trim_words( wp_strip_all_tags( $content ), 25 );
		} elseif ( is_home() || is_front_page() ) {
			return get_bloginfo( 'description' );
		} elseif ( is_category() ) {
			return category_description();
		} elseif ( is_tag() ) {
			return tag_description();
		} else {
			return get_bloginfo( 'description' );
		}
	}

	/**
	 * Get the current page image
	 *
	 * @since    1.0.0
	 * @return   string    The page image URL
	 */
	private function get_page_image() {
		$options = get_option( 'cspgbase_options', array() );

		// Check for custom meta image first
		if ( is_single() || is_page() ) {
			global $post;
			$custom_image = get_post_meta( $post->ID, '_basic_seo_helper_image', true );
			if ( ! empty( $custom_image ) ) {
				return $custom_image;
			}
		}

		// Try to get featured image
		if ( ( is_single() || is_page() ) && has_post_thumbnail() ) {
			$image_array = wp_get_attachment_image_src( get_post_thumbnail_id(), 'large' );
			if ( $image_array ) {
				return $image_array[0];
			}
		}

		// Fallback to default image
		if ( ! empty( $options['default_image'] ) ) {
			return $options['default_image'];
		}

		// Final fallback to site logo or empty
		$custom_logo_id = get_theme_mod( 'custom_logo' );
		if ( $custom_logo_id ) {
			$logo_array = wp_get_attachment_image_src( $custom_logo_id, 'large' );
			if ( $logo_array ) {
				return $logo_array[0];
			}
		}

		return '';
	}

	/**
	 * Get the canonical URL for the current page
	 *
	 * @since    1.0.0
	 * @return   string    The canonical URL
	 */
	private function get_canonical_url() {
		global $wp;

		if ( is_single() || is_page() ) {
			return get_permalink();
		} else {
			return home_url( add_query_arg( array(), $wp->request ) );
		}
	}

	/**
	 * Get the Open Graph type for the current page
	 *
	 * @since    1.0.0
	 * @return   string    The Open Graph type
	 */
	private function get_page_type() {
		if ( is_single() ) {
			return 'article';
		} else {
			return 'website';
		}
	}

	/**
	 * Get Open Graph title for the current page
	 *
	 * @since    1.0.0
	 * @return   string    The Open Graph title
	 */
	private function get_og_title() {
		// Check for custom Open Graph title first
		if ( is_single() || is_page() ) {
			global $post;
			$og_title = get_post_meta( $post->ID, '_basic_seo_helper_og_title', true );
			if ( ! empty( $og_title ) ) {
				return $og_title;
			}
		}

		// Fallback to regular page title
		return $this->get_page_title();
	}

	/**
	 * Get Open Graph description for the current page
	 *
	 * @since    1.0.0
	 * @return   string    The Open Graph description
	 */
	private function get_og_description() {
		// Check for custom Open Graph description first
		if ( is_single() || is_page() ) {
			global $post;
			$og_description = get_post_meta( $post->ID, '_basic_seo_helper_og_description', true );
			if ( ! empty( $og_description ) ) {
				return $og_description;
			}
		}

		// Fallback to regular page description
		return $this->get_page_description();
	}

	/**
	 * Get Twitter title for the current page
	 *
	 * @since    1.0.0
	 * @return   string    The Twitter title
	 */
	private function get_twitter_title() {
		// Check for custom Twitter title first
		if ( is_single() || is_page() ) {
			global $post;
			$twitter_title = get_post_meta( $post->ID, '_basic_seo_helper_twitter_title', true );
			if ( ! empty( $twitter_title ) ) {
				return $twitter_title;
			}
		}

		// Fallback to Open Graph title, then regular page title
		return $this->get_og_title();
	}

	/**
	 * Get Twitter description for the current page
	 *
	 * @since    1.0.0
	 * @return   string    The Twitter description
	 */
	private function get_twitter_description() {
		// Check for custom Twitter description first
		if ( is_single() || is_page() ) {
			global $post;
			$twitter_description = get_post_meta( $post->ID, '_basic_seo_helper_twitter_description', true );
			if ( ! empty( $twitter_description ) ) {
				return $twitter_description;
			}
		}

		// Fallback to Open Graph description, then regular page description
		return $this->get_og_description();
	}

	/**
	 * Get Open Graph locale
	 *
	 * @since    1.2.17
	 * @return   string    The locale in OG format (e.g., en_US)
	 */
	private function get_og_locale() {
		// Get WordPress locale
		$locale = get_locale();

		// Convert WordPress locale format to OG format (e.g., en_US, fr_FR)
		// WordPress uses formats like en_US, fr_FR which match OG format
		return $locale;
	}

	/**
	 * Output robots meta tag if non-default directives are set
	 *
	 * @since    1.2.17
	 */
	private function output_robots_meta_tag() {
		// Check if robots meta is enabled globally
		$robots_enabled = get_option( 'cspgbase_enable_robots_meta', '1' );
		if ( '1' !== $robots_enabled ) {
			return;
		}

		// Get robots directives for current page
		$directives = $this->get_robots_directives();

		// Only output if directives differ from default (index, follow)
		if ( ! empty( $directives ) ) {
			echo '<meta name="robots" content="' . esc_attr( $directives ) . '">' . "\n";
		}
	}

	/**
	 * Get robots directives for current page
	 *
	 * @since    1.2.17
	 * @return   string    Comma-separated robots directives, empty if default
	 */
	private function get_robots_directives() {
		$directives = array();

		// Check for per-post settings
		if ( is_singular() ) {
			$post_id = get_queried_object_id();

			$noindex   = get_post_meta( $post_id, '_basic_seo_helper_noindex', true );
			$nofollow  = get_post_meta( $post_id, '_basic_seo_helper_nofollow', true );
			$noarchive = get_post_meta( $post_id, '_basic_seo_helper_noarchive', true );
			$nosnippet = get_post_meta( $post_id, '_basic_seo_helper_nosnippet', true );

			// Build directives array
			if ( '1' === $noindex ) {
				$directives[] = 'noindex';
			}

			if ( '1' === $nofollow ) {
				$directives[] = 'nofollow';
			}

			if ( '1' === $noarchive ) {
				$directives[] = 'noarchive';
			}

			if ( '1' === $nosnippet ) {
				$directives[] = 'nosnippet';
			}
		}

		// Return comma-separated directives or empty string if default
		return ! empty( $directives ) ? implode( ', ', $directives ) : '';
	}

	/**
	 * Add Schema.org structured data
	 *
	 * @since    1.0.0
	 */
	private function add_schema_markup() {
		// Check if schema is enabled for this specific post/page
		if ( is_singular() ) {
			$post_id        = get_queried_object_id();
			$schema_enabled = get_post_meta( $post_id, '_basic_seo_helper_schema_enabled', true );

			// Only skip schema if explicitly disabled (empty string means enabled by default)
			if ( '0' === $schema_enabled ) {
				return;
			}
		}

		$options = get_option( 'cspgbase_options', array() );

		$schema = array(
			'@context' => 'https://schema.org',
			'@graph'   => array(),
		);

		// Organization schema
		$organization = array(
			'@type' => 'Organization',
			'name'  => $options['organization_name'] ?? get_bloginfo( 'name' ),
			'url'   => home_url(),
		);

		if ( ! empty( $options['organization_logo'] ) ) {
			$organization['logo'] = array(
				'@type' => 'ImageObject',
				'url'   => $options['organization_logo'],
			);
		}

		if ( ! empty( $options['social_profiles'] ) ) {
			$organization['sameAs'] = array_values( array_filter( $options['social_profiles'] ) );
		}

		$schema['@graph'][] = $organization;

		// Website schema
		$website = array(
			'@type'       => 'WebSite',
			'name'        => get_bloginfo( 'name' ),
			'url'         => home_url(),
			'description' => get_bloginfo( 'description' ),
		);

		$schema['@graph'][] = $website;

		// Article schema for posts
		if ( is_single() ) {
			global $post;
			$article = array(
				'@type'         => 'Article',
				'headline'      => $this->get_page_title(),
				'description'   => $this->get_page_description(),
				'url'           => get_permalink(),
				'datePublished' => get_the_date( 'c' ),
				'dateModified'  => get_the_modified_date( 'c' ),
				'author'        => array(
					'@type' => 'Person',
					'name'  => get_the_author(),
				),
				'publisher'     => array(
					'@type' => 'Organization',
					'name'  => get_bloginfo( 'name' ),
				),
			);

			$image = $this->get_page_image();
			if ( ! empty( $image ) ) {
				$article['image'] = array(
					'@type' => 'ImageObject',
					'url'   => $image,
				);
			}

			$schema['@graph'][] = $article;
		}

		// Output JSON-LD schema using WordPress helper function
		echo "\n<!-- Basic SEO Helper - Schema.org Structured Data -->\n";
		wp_print_inline_script_tag(
			wp_json_encode( $schema ),
			array(
				'type' => 'application/ld+json',
			)
		);
	}

	/**
	 * Filter the document title to use custom SEO title
	 *
	 * @since    1.0.0
	 * @param    array    $title_parts    The title parts array
	 * @return   array    Modified title parts
	 */
	public function filter_document_title( $title_parts ) {
		if ( is_single() || is_page() ) {
			global $post;
			$custom_title = get_post_meta( $post->ID, '_basic_seo_helper_title', true );
			if ( ! empty( $custom_title ) ) {
				$title_parts['title'] = $custom_title;
			}
		}

		return $title_parts;
	}

	/**
	 * Generate XML sitemap
	 *
	 * @since    1.0.3
	 * @deprecated Use generate_sitemap_index() instead
	 */
	public function generate_sitemap() {
		// Redirect to new sitemap index for backward compatibility
		$this->generate_sitemap_index();
	}

	/**
	 * Generate sitemap index (main sitemap.xml)
	 *
	 * @since    1.0.3
	 */
	public function generate_sitemap_index() {
		$sitemap_settings = get_option( 'cspgbase_sitemap_settings', array() );

		// Check if sitemap is enabled
		if ( empty( $sitemap_settings['enabled'] ) || '1' !== $sitemap_settings['enabled'] ) {
			wp_die( esc_html__( 'Sitemap is not enabled.', 'cspg-basic-seo-helper' ), esc_html__( 'Sitemap Disabled', 'cspg-basic-seo-helper' ), array( 'response' => 404 ) );
		}

		// Set XML headers
		header( 'Content-Type: application/xml; charset=utf-8' );

		// Generate sitemap index XML
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- XML content generated by get_sitemap_index_xml(), validated internally
		echo $this->get_sitemap_index_xml();
		exit;
	}

	/**
	 * Generate posts sitemap
	 *
	 * @since    1.0.3
	 */
	public function generate_posts_sitemap() {
		$sitemap_settings = get_option( 'cspgbase_sitemap_settings', array() );

		// Check if sitemap is enabled
		if ( empty( $sitemap_settings['enabled'] ) || '1' !== $sitemap_settings['enabled'] ) {
			wp_die( esc_html__( 'Sitemap is not enabled.', 'cspg-basic-seo-helper' ), esc_html__( 'Sitemap Disabled', 'cspg-basic-seo-helper' ), array( 'response' => 404 ) );
		}

		// Set XML headers
		header( 'Content-Type: application/xml; charset=utf-8' );

		// Generate posts sitemap XML
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- XML content generated by get_posts_sitemap_xml(), validated internally
		echo $this->get_posts_sitemap_xml();
		exit;
	}

	/**
	 * Generate pages sitemap
	 *
	 * @since    1.0.3
	 */
	public function generate_pages_sitemap() {
		$sitemap_settings = get_option( 'cspgbase_sitemap_settings', array() );

		// Check if sitemap is enabled
		if ( empty( $sitemap_settings['enabled'] ) || '1' !== $sitemap_settings['enabled'] ) {
			wp_die( esc_html__( 'Sitemap is not enabled.', 'cspg-basic-seo-helper' ), esc_html__( 'Sitemap Disabled', 'cspg-basic-seo-helper' ), array( 'response' => 404 ) );
		}

		// Set XML headers
		header( 'Content-Type: application/xml; charset=utf-8' );

		// Generate pages sitemap XML
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- XML content generated by get_pages_sitemap_xml(), validated internally
		echo $this->get_pages_sitemap_xml();
		exit;
	}



	/**
	 * Get sitemap XML content
	 *
	 * @since    1.0.3
	 * @return   string    XML sitemap content
	 */
	private function get_sitemap_xml() {
		$sitemap_settings = get_option( 'cspgbase_sitemap_settings', array() );

		// Default settings
		$defaults = array(
			'include_post_types'         => array( 'post', 'page' ),
			'max_entries'                => 1000,
			'exclude_private'            => '1',
			'exclude_password_protected' => '1',
		);

		$sitemap_settings = wp_parse_args( $sitemap_settings, $defaults );

		// Get posts for sitemap
		$posts = $this->get_sitemap_posts( $sitemap_settings );

		// Generate XML
		$xml  = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
		$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";

		// Add homepage
		$xml .= $this->get_sitemap_url_entry( home_url( '/' ), get_option( 'date_format' ), '1.0', 'daily' );

		// Add posts
		foreach ( $posts as $post ) {
			$url        = get_permalink( $post->ID );
			$lastmod    = $post->post_modified;
			$priority   = $this->get_post_priority( $post );
			$changefreq = $this->get_post_changefreq( $post );

			$xml .= $this->get_sitemap_url_entry( $url, $lastmod, $priority, $changefreq );
		}

		$xml .= '</urlset>';

		return $xml;
	}

	/**
	 * Get sitemap index XML content
	 *
	 * @since    1.0.3
	 * @return   string    XML sitemap index content
	 */
	private function get_sitemap_index_xml() {
		$sitemap_settings = get_option( 'cspgbase_sitemap_settings', array() );

		// Default settings
		$defaults = array(
			'include_post_types' => array( 'post', 'page' ),
		);

		$sitemap_settings = wp_parse_args( $sitemap_settings, $defaults );

		$xml  = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
		$xml .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";

		// Posts sitemap - only include if posts are enabled in settings
		if ( in_array( 'post', $sitemap_settings['include_post_types'], true ) ) {
			$posts_count = wp_count_posts( 'post' );
			if ( ! empty( $posts_count->publish ) ) {
				$posts_lastmod = $this->get_posts_last_modified();
				$xml          .= $this->get_sitemap_index_entry( home_url( '/posts-sitemap.xml' ), $posts_lastmod );
			}
		}

		// Pages sitemap - only include if pages are enabled in settings
		if ( in_array( 'page', $sitemap_settings['include_post_types'], true ) ) {
			$pages_count = wp_count_posts( 'page' );
			if ( ! empty( $pages_count->publish ) ) {
				$pages_lastmod = $this->get_pages_last_modified();
				$xml          .= $this->get_sitemap_index_entry( home_url( '/pages-sitemap.xml' ), $pages_lastmod );
			}
		}

		$xml .= '</sitemapindex>';

		return $xml;
	}

	/**
	 * Get posts sitemap XML content
	 *
	 * @since    1.0.3
	 * @return   string    XML posts sitemap content
	 */
	private function get_posts_sitemap_xml() {
		$sitemap_settings = get_option( 'cspgbase_sitemap_settings', array() );

		$defaults = array(
			'max_entries'                => 50000,
			'exclude_password_protected' => '1',
			'exclude_private'            => '1',
		);

		$sitemap_settings = wp_parse_args( $sitemap_settings, $defaults );

		// Get posts
		$posts = $this->get_posts_for_sitemap( $sitemap_settings );

		// Generate XML
		$xml  = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
		$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";

		// Add posts
		foreach ( $posts as $post ) {
			$url        = get_permalink( $post->ID );
			$lastmod    = $post->post_modified;
			$priority   = '0.8';
			$changefreq = 'weekly';

			$xml .= $this->get_sitemap_url_entry( $url, $lastmod, $priority, $changefreq );
		}

		$xml .= '</urlset>';

		return $xml;
	}

	/**
	 * Get pages sitemap XML content
	 *
	 * @since    1.0.3
	 * @return   string    XML pages sitemap content
	 */
	private function get_pages_sitemap_xml() {
		$sitemap_settings = get_option( 'cspgbase_sitemap_settings', array() );

		$defaults = array(
			'max_entries'                => 50000,
			'exclude_password_protected' => '1',
			'exclude_private'            => '1',
		);

		$sitemap_settings = wp_parse_args( $sitemap_settings, $defaults );

		// Get pages
		$pages = $this->get_pages_for_sitemap( $sitemap_settings );

		// Generate XML
		$xml  = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
		$xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";

		// Add pages
		foreach ( $pages as $page ) {
			$url        = get_permalink( $page->ID );
			$lastmod    = $page->post_modified;
			$priority   = '0.6';
			$changefreq = 'monthly';

			$xml .= $this->get_sitemap_url_entry( $url, $lastmod, $priority, $changefreq );
		}

		$xml .= '</urlset>';

		return $xml;
	}



	/**
	 * Get posts for sitemap based on settings
	 *
	 * @since    1.0.3
	 * @param    array    $settings    Sitemap settings
	 * @return   array    Array of post objects
	 */
	private function get_sitemap_posts( $settings ) {
		$args = array(
			'post_type'              => $settings['include_post_types'],
			'post_status'            => 'publish',
			'posts_per_page'         => $settings['max_entries'],
			'orderby'                => 'modified',
			'order'                  => 'DESC',
			'no_found_rows'          => true,
			'update_post_meta_cache' => false,
			'update_post_term_cache' => false,
		);

		// Include private posts if not explicitly excluded
		if ( ! isset( $settings['exclude_private'] ) || '1' !== $settings['exclude_private'] ) {
			$args['post_status'] = array( 'publish', 'private' );
		}

		// Exclude password protected posts
		if ( isset( $settings['exclude_password_protected'] ) && '1' === $settings['exclude_password_protected'] ) {
			$args['has_password'] = false;
		}

		return get_posts( $args );
	}

	/**
	 * Generate sitemap URL entry
	 *
	 * @since    1.0.3
	 * @param    string    $url         URL of the page
	 * @param    string    $lastmod     Last modification date
	 * @param    string    $priority    Priority (0.0 to 1.0)
	 * @param    string    $changefreq  Change frequency
	 * @return   string    XML URL entry
	 */
	private function get_sitemap_url_entry( $url, $lastmod, $priority, $changefreq ) {
		$xml  = "  <url>\n";
		$xml .= '    <loc>' . esc_url( $url ) . "</loc>\n";
		$xml .= '    <lastmod>' . esc_html( gmdate( 'c', strtotime( $lastmod ) ) ) . "</lastmod>\n";
		$xml .= '    <changefreq>' . esc_html( $changefreq ) . "</changefreq>\n";
		$xml .= '    <priority>' . esc_html( $priority ) . "</priority>\n";
		$xml .= "  </url>\n";

		return $xml;
	}

	/**
	 * Get post priority for sitemap
	 *
	 * @since    1.0.3
	 * @param    WP_Post    $post    Post object
	 * @return   string     Priority value
	 */
	private function get_post_priority( $post ) {
		switch ( $post->post_type ) {
			case 'page':
				return is_front_page() && get_option( 'page_on_front' ) === $post->ID ? '1.0' : '0.8';
			case 'post':
				return '0.6';
			default:
				return '0.5';
		}
	}

	/**
	 * Get post change frequency for sitemap
	 *
	 * @since    1.0.3
	 * @param    WP_Post    $post    Post object
	 * @return   string     Change frequency
	 */
	private function get_post_changefreq( $post ) {
		$days_old = ( time() - strtotime( $post->post_date ) ) / DAY_IN_SECONDS;

		if ( $days_old < 1 ) {
			return 'daily';
		} elseif ( $days_old < 7 ) {
			return 'weekly';
		} elseif ( $days_old < 30 ) {
			return 'monthly';
		} else {
			return 'yearly';
		}
	}

	/**
	 * Handle sitemap request
	 *
	 * @since    1.0.3
	 */
	public function handle_sitemap_request() {
		$sitemap_query = get_query_var( 'basic_seo_sitemap' );

		if ( ! empty( $sitemap_query ) ) {
			switch ( $sitemap_query ) {
				case 'index':
				case '1': // Backward compatibility
					$this->generate_sitemap_index();
					break;
				case 'posts':
					$this->generate_posts_sitemap();
					break;
				case 'pages':
					$this->generate_pages_sitemap();
					break;
				default:
					// Default to index for any other value
					$this->generate_sitemap_index();
					break;
			}
		}
	}

	/**
	 * Get sitemap index entry
	 *
	 * @since    1.0.3
	 * @param    string    $url         URL of the sitemap
	 * @param    string    $lastmod     Last modification date
	 * @return   string    XML sitemap index entry
	 */
	private function get_sitemap_index_entry( $url, $lastmod ) {
		$xml  = "  <sitemap>\n";
		$xml .= '    <loc>' . esc_url( $url ) . "</loc>\n";
		$xml .= '    <lastmod>' . esc_html( gmdate( 'c', strtotime( $lastmod ) ) ) . "</lastmod>\n";
		$xml .= "  </sitemap>\n";

		return $xml;
	}

	/**
	 * Get posts for sitemap
	 *
	 * @since    1.0.3
	 * @param    array    $settings    Sitemap settings
	 * @return   array    Array of post objects
	 */
	private function get_posts_for_sitemap( $settings ) {
		$args = array(
			'post_type'              => 'post',
			'post_status'            => 'publish',
			'posts_per_page'         => $settings['max_entries'],
			'orderby'                => 'modified',
			'order'                  => 'DESC',
			'no_found_rows'          => true,
			'update_post_meta_cache' => false,
			'update_post_term_cache' => false,
		);

		// Include private posts if not explicitly excluded
		if ( ! isset( $settings['exclude_private'] ) || '1' !== $settings['exclude_private'] ) {
			$args['post_status'] = array( 'publish', 'private' );
		}

		// Exclude password protected posts
		if ( isset( $settings['exclude_password_protected'] ) && '1' === $settings['exclude_password_protected'] ) {
			$args['has_password'] = false;
		}

		return get_posts( $args );
	}

	/**
	 * Get pages for sitemap
	 *
	 * @since    1.0.3
	 * @param    array    $settings    Sitemap settings
	 * @return   array    Array of page objects
	 */
	private function get_pages_for_sitemap( $settings ) {
		$args = array(
			'post_type'              => 'page',
			'post_status'            => 'publish',
			'posts_per_page'         => $settings['max_entries'],
			'orderby'                => 'modified',
			'order'                  => 'DESC',
			'no_found_rows'          => true,
			'update_post_meta_cache' => false,
			'update_post_term_cache' => false,
		);

		// Include private pages if not explicitly excluded
		if ( ! isset( $settings['exclude_private'] ) || '1' !== $settings['exclude_private'] ) {
			$args['post_status'] = array( 'publish', 'private' );
		}

		// Exclude password protected pages
		if ( isset( $settings['exclude_password_protected'] ) && '1' === $settings['exclude_password_protected'] ) {
			$args['has_password'] = false;
		}

		return get_posts( $args );
	}

	/**
	 * Get last modified date for posts
	 *
	 * @since    1.0.3
	 * @return   string    Last modified date
	 */
	private function get_posts_last_modified() {
		$posts = get_posts(
			array(
				'post_type'   => 'post',
				'post_status' => 'publish',
				'numberposts' => 1,
				'orderby'     => 'modified',
				'order'       => 'DESC',
			)
		);

		if ( ! empty( $posts ) ) {
			return $posts[0]->post_modified;
		}

		return current_time( 'mysql' );
	}

	/**
	 * Get last modified date for pages
	 *
	 * @since    1.0.3
	 * @return   string    Last modified date
	 */
	private function get_pages_last_modified() {
		$pages = get_posts(
			array(
				'post_type'   => 'page',
				'post_status' => 'publish',
				'numberposts' => 1,
				'orderby'     => 'modified',
				'order'       => 'DESC',
			)
		);

		if ( ! empty( $pages ) ) {
			return $pages[0]->post_modified;
		}

		return current_time( 'mysql' );
	}

	/**
	 * Invalidate sitemap cache when content changes
	 *
	 * @since    1.0.3
	 * @param    int    $post_id    Post ID
	 */
	public function invalidate_sitemap_cache( $post_id ) {
		// Clear any cached sitemap data
		// This method is called when posts/pages are created, updated, or deleted
		// to ensure sitemap reflects the latest content

		// You can add caching logic here if needed in the future
		// For now, sitemaps are generated dynamically

		// Clear opcode cache if available
		if ( function_exists( 'opcache_reset' ) ) {
			opcache_reset();
		}
	}
}
