<?php
/**
 * This file is part of the Wisewand WordPress plugin.
 *
 * @package Wisewand
 * @since 1.0.0
 * @license GPL-2.0-or-later
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
namespace Wisewand\SEO;

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Wisewand\Utils\Options;
use Wisewand\Logging\Logger;

class SEO_Manager {

	private $options;
	private $logger;

	public function __construct( Options $options, Logger $logger ) {
		$this->options = $options;
		$this->logger  = $logger;

		// Hook into post save to process SEO data
		add_action( 'save_post', array( $this, 'process_post_seo_data' ), 20, 1 );

		// Hook into category/taxonomy creation for SEO
		add_action( 'create_term', array( $this, 'process_taxonomy_seo_data' ), 20, 3 );
		add_action( 'edit_term', array( $this, 'process_taxonomy_seo_data' ), 20, 3 );
	}

	public function process_post_seo_data( $post_id ) {
		// Only process posts with Wisewand SEO data
		$seo_data = get_post_meta( $post_id, '_wisewand_seo_data', true );
		if ( empty( $seo_data ) ) {
			return;
		}

		$post_type = get_post_type( $post_id );

		// Check if this post type supports SEO with current plugins
		if ( ! $this->post_type_supports_seo( $post_type ) ) {
			$this->logger->info(
				'Post type does not support SEO with current plugins',
				array(
					'post_id'   => $post_id,
					'post_type' => $post_type,
				)
			);
			// Store as fallback meta anyway
			$this->process_fallback_seo( $post_id, $seo_data );
			return;
		}

		$seo_settings = $this->options->get_seo_settings();

		// Ensure we have all expected SEO fields from Wisewand
		$seo_data = $this->normalize_seo_data( $seo_data, $post_id );

		switch ( $seo_settings['mode'] ) {
			case 'yoast_api':
				$this->process_yoast_seo( $post_id, $seo_data );
				break;

			case 'rankmath_api':
				$this->process_rankmath_seo( $post_id, $seo_data );
				break;

			case 'seopress_api':
				$this->process_seopress_seo( $post_id, $seo_data );
				break;

			case 'meta_mapping':
				$this->process_meta_mapping_seo( $post_id, $seo_data, $seo_settings['meta_mapping'] );
				break;

			case 'auto':
			default:
				$this->process_auto_seo( $post_id, $seo_data );
				break;
		}

		// Store processed SEO data for reference (keep a backup)
		update_post_meta( $post_id, '_wisewand_seo_processed', $seo_data );
		update_post_meta( $post_id, '_wisewand_seo_processed_at', current_time( 'mysql' ) );

		// Remove the temporary processing data
		delete_post_meta( $post_id, '_wisewand_seo_data' );

		// Invalidate sitemap caches so new/updated posts appear immediately
		$this->invalidate_sitemap_cache();

		$this->logger->info(
			'SEO data processed successfully',
			array(
				'post_id'          => $post_id,
				'mode'             => $seo_settings['mode'],
				'fields_processed' => array_keys( $seo_data ),
				'yoast_active'     => $this->options->is_yoast_active(),
				'rankmath_active'  => $this->options->is_rankmath_active(),
				'seopress_active'  => $this->options->is_seopress_active(),
			)
		);
	}

	private function normalize_seo_data( $seo_data, $post_id ) {
		$post = get_post( $post_id );

		// Get Wisewand input and output data
		$input_data  = get_post_meta( $post_id, '_wisewand_input_data', true );
		$output_data = get_post_meta( $post_id, '_wisewand_output_data', true );

		// FOCUS KEYWORD: Only use target_keyword (single keyword)
		if ( ! empty( $input_data['target_keyword'] ) && empty( $seo_data['focus_keyword'] ) ) {
			$seo_data['focus_keyword'] = trim( $input_data['target_keyword'] ); // Clean single keyword only
		}

		// META TITLE: Use Wisewand meta_title
		if ( ! empty( $output_data['meta_title'] ) && empty( $seo_data['title'] ) ) {
			$seo_data['title'] = $output_data['meta_title'];
		}

		// META DESCRIPTION: Use Wisewand meta_description
		if ( ! empty( $output_data['meta_description'] ) && empty( $seo_data['description'] ) ) {
			$seo_data['description'] = $output_data['meta_description'];
		}

		// CANONICAL URL: Use Wisewand URL
		if ( ! empty( $output_data['url'] ) && empty( $seo_data['canonical_url'] ) ) {
			$seo_data['canonical_url'] = $output_data['url'];
		}

		// Remove same-site canonical — let SEO plugin auto-generate from permalink
		if ( ! empty( $seo_data['canonical_url'] ) && $this->is_same_site_url( $seo_data['canonical_url'] ) ) {
			unset( $seo_data['canonical_url'] );
		}

		// SOCIAL MEDIA: Use meta fields for consistency
		if ( ! empty( $output_data['meta_title'] ) ) {
			$seo_data['og_title']      = $output_data['meta_title'];
			$seo_data['twitter_title'] = $output_data['meta_title'];
		}

		if ( ! empty( $output_data['meta_description'] ) ) {
			$seo_data['og_description']      = $output_data['meta_description'];
			$seo_data['twitter_description'] = $output_data['meta_description'];
		}

		// SOCIAL IMAGE: Use local featured image
		$featured_image_id = get_post_thumbnail_id( $post_id );
		if ( $featured_image_id ) {
			$local_image_url = wp_get_attachment_image_url( $featured_image_id, 'large' );
			if ( $local_image_url ) {
				$seo_data['og_image']      = $local_image_url;
				$seo_data['twitter_image'] = $local_image_url;
			}
		}

		return $seo_data;
	}

	private function process_auto_seo( $post_id, array $seo_data ) {
		if ( $this->options->is_yoast_active() ) {
			$this->process_yoast_seo( $post_id, $seo_data );
		} elseif ( $this->options->is_rankmath_active() ) {
			$this->process_rankmath_seo( $post_id, $seo_data );
		} elseif ( $this->options->is_seopress_active() ) {
			$this->process_seopress_seo( $post_id, $seo_data );
		} else {
			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
				error_log( 'Wisewand SEO: No SEO plugin detected (Yoast/RankMath/SEOPress), using fallback meta storage for post ' . $post_id );
			}
			$this->process_fallback_seo( $post_id, $seo_data );
		}
	}

	private function process_yoast_seo( $post_id, array $seo_data ) {
		if ( ! $this->options->is_yoast_active() ) {
			$this->logger->warning( 'Yoast SEO not active, falling back to meta storage' );
			$this->process_fallback_seo( $post_id, $seo_data );
			return;
		}

		$this->logger->debug(
			'Processing Yoast SEO data',
			array(
				'post_id'    => $post_id,
				'seo_fields' => array_keys( $seo_data ),
			)
		);

		// Use direct meta approach for reliability
		$yoast_meta_map = $this->get_yoast_meta_mapping();

		// Process each SEO field
		foreach ( $seo_data as $field => $value ) {
			if ( empty( $value ) ) {
				continue;
			}

			$processed = false;

			// Direct meta key mapping for all fields
			if ( isset( $yoast_meta_map[ $field ] ) ) {
				$meta_key        = $yoast_meta_map[ $field ];
				$sanitized_value = $this->sanitize_seo_value( $value );

				update_post_meta( $post_id, $meta_key, $sanitized_value );
				$processed = true;

				$this->logger->debug(
					'Set Yoast meta field',
					array(
						'post_id'  => $post_id,
						'field'    => $field,
						'meta_key' => $meta_key, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- False positive: 'meta_key' is a logging context parameter, not a database query
					'value_length' => strlen( $sanitized_value ),
					)
				);
			}

			// Special handling for complex fields
			if ( ! $processed ) {
				switch ( $field ) {
					case 'robots':
						$this->set_yoast_robots( $post_id, $value );
						$processed = true;
						break;

					case 'secondary_keywords':
						// Don't add secondary keywords to focus field - keep focus keyword clean
						// Secondary keywords can be stored separately if needed
						update_post_meta( $post_id, '_wisewand_secondary_keywords', $value );
						$processed = true;
						break;
				}
			}
		}

		// Process social/OpenGraph data
		$this->process_yoast_social( $post_id, $seo_data );

		// Process FAQ schema (if FAQ data is in SEO data)
		// NOTE: Import_Enhancer now handles FAQ directly after import
		// This code path is for backward compatibility or manual FAQ addition
		if ( ! empty( $seo_data['faq'] ) ) {
			$faq_result = $this->process_yoast_faq( $post_id, $seo_data['faq'] );
			if ( $faq_result ) {
				$this->logger->info(
					'Yoast FAQ schema added (via SEO_Manager)',
					array(
						'post_id'   => $post_id,
						'faq_count' => count( $seo_data['faq'] ),
					)
				);
				// Note: FAQ removal handled by Import_Enhancer
			}
		}

		$this->logger->info(
			'Yoast SEO data processed',
			array(
				'post_id'      => $post_id,
				'fields_count' => count( $seo_data ),
			)
		);
	}

	private function process_rankmath_seo( $post_id, array $seo_data ) {
		if ( ! $this->options->is_rankmath_active() ) {
			$this->logger->warning( 'Rank Math not active, falling back to meta storage' );
			$this->process_fallback_seo( $post_id, $seo_data );
			return;
		}

		$this->logger->debug(
			'Processing Rank Math SEO data',
			array(
				'post_id'    => $post_id,
				'seo_fields' => array_keys( $seo_data ),
			)
		);

		// Use direct meta approach for reliability
		$rankmath_meta_map = $this->get_rankmath_meta_mapping();

		foreach ( $seo_data as $field => $value ) {
			if ( empty( $value ) ) {
				continue;
			}

			$processed = false;

			// Direct meta key mapping
			if ( isset( $rankmath_meta_map[ $field ] ) ) {
				$meta_key        = $rankmath_meta_map[ $field ];
				$sanitized_value = $this->sanitize_seo_value( $value );

				update_post_meta( $post_id, $meta_key, $sanitized_value );
				$processed = true;

				$this->logger->debug(
					'Set Rank Math meta field',
					array(
						'post_id'  => $post_id,
						'field'    => $field,
						'meta_key' => $meta_key, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- False positive: 'meta_key' is a logging context parameter, not a database query
					'value_length' => strlen( $sanitized_value ),
					)
				);
			}

			// Special handling for complex fields
			if ( ! $processed ) {
				switch ( $field ) {
					case 'robots':
						$this->set_rankmath_robots( $post_id, $value );
						$processed = true;
						break;

					case 'secondary_keywords':
						// Don't pollute focus keyword - store secondary keywords separately
						update_post_meta( $post_id, '_wisewand_secondary_keywords', $value );
						$processed = true;
						break;
				}
			}
		}

		// Process social data
		$this->process_rankmath_social( $post_id, $seo_data );

		// Process FAQ schema (if FAQ data is in SEO data)
		// NOTE: Import_Enhancer now handles FAQ directly after import
		// This code path is for backward compatibility or manual FAQ addition
		if ( ! empty( $seo_data['faq'] ) ) {
			$faq_result = $this->process_rankmath_faq( $post_id, $seo_data['faq'] );
			if ( $faq_result ) {
				$this->logger->info(
					'RankMath FAQ schema added (via SEO_Manager)',
					array(
						'post_id'   => $post_id,
						'faq_count' => count( $seo_data['faq'] ),
					)
				);
				// Note: FAQ removal handled by Import_Enhancer
			}
		}

		$this->logger->info(
			'Rank Math SEO data processed',
			array(
				'post_id'      => $post_id,
				'fields_count' => count( $seo_data ),
			)
		);
	}

	private function process_seopress_seo( $post_id, array $seo_data ) {
		if ( ! $this->options->is_seopress_active() ) {
			$this->logger->warning( 'SEOPress not active, falling back to meta storage' );
			$this->process_fallback_seo( $post_id, $seo_data );
			return;
		}

		$this->logger->debug(
			'Processing SEOPress SEO data',
			array(
				'post_id'    => $post_id,
				'seo_fields' => array_keys( $seo_data ),
			)
		);

		// Use direct meta approach for reliability
		$seopress_meta_map = $this->get_seopress_meta_mapping();

		foreach ( $seo_data as $field => $value ) {
			if ( empty( $value ) ) {
				continue;
			}

			$processed = false;

			// Direct meta key mapping
			if ( isset( $seopress_meta_map[ $field ] ) ) {
				$meta_key        = $seopress_meta_map[ $field ];
				$sanitized_value = $this->sanitize_seo_value( $value );

				update_post_meta( $post_id, $meta_key, $sanitized_value );
				$processed = true;

				$this->logger->debug(
					'Set SEOPress meta field',
					array(
						'post_id'  => $post_id,
						'field'    => $field,
						'meta_key' => $meta_key, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- False positive: 'meta_key' is a logging context parameter, not a database query
					'value_length' => strlen( $sanitized_value ),
					)
				);
			}

			// Special handling for complex fields
			if ( ! $processed ) {
				switch ( $field ) {
					case 'robots':
						$this->set_seopress_robots( $post_id, $value );
						$processed = true;
						break;

					case 'secondary_keywords':
						// SEOPress uses comma-separated keywords in the same field
						// Store secondary keywords separately to avoid polluting focus keyword
						update_post_meta( $post_id, '_wisewand_secondary_keywords', $value );
						$processed = true;
						break;
				}
			}
		}

		// Process social data
		$this->process_seopress_social( $post_id, $seo_data );

		// Process FAQ schema (if FAQ data is in SEO data)
		// NOTE: Import_Enhancer now handles FAQ directly after import
		// This code path is for backward compatibility or manual FAQ addition
		if ( ! empty( $seo_data['faq'] ) ) {
			$faq_result = $this->process_seopress_faq( $post_id, $seo_data['faq'] );
			if ( $faq_result ) {
				$this->logger->info(
					'SEOPress FAQ schema added (via SEO_Manager)',
					array(
						'post_id'   => $post_id,
						'faq_count' => count( $seo_data['faq'] ),
					)
				);
			}
		}

		$this->logger->info(
			'SEOPress SEO data processed',
			array(
				'post_id'      => $post_id,
				'fields_count' => count( $seo_data ),
			)
		);
	}

	private function process_meta_mapping_seo( $post_id, array $seo_data, array $meta_mapping ) {
		foreach ( $seo_data as $field => $value ) {
			if ( empty( $value ) || ! isset( $meta_mapping[ $field ] ) ) {
				continue;
			}

			$meta_key = $meta_mapping[ $field ];
			if ( ! empty( $meta_key ) ) {
				update_post_meta( $post_id, $meta_key, $this->sanitize_seo_value( $value ) );
			}
		}
	}

	private function process_fallback_seo( $post_id, array $seo_data ) {
		// Store in Wisewand namespaced meta keys for theme/plugin integration
		foreach ( $seo_data as $field => $value ) {
			if ( ! empty( $value ) ) {
				update_post_meta( $post_id, "_wisewand_seo_{$field}", $this->sanitize_seo_value( $value ) );
			}
		}
	}

	// Yoast SEO specific methods

	private function set_yoast_title( $post_id, $title ) {
		// Try using Yoast's filter/action hooks if available
		if ( function_exists( 'YoastSEO' ) && method_exists( YoastSEO()->meta, 'for_post' ) ) {
			update_post_meta( $post_id, '_yoast_wpseo_title', $title );
			return true;
		}

		// Fall back to direct meta
		update_post_meta( $post_id, '_yoast_wpseo_title', $title );
		return true;
	}

	private function set_yoast_description( $post_id, $description ) {
		update_post_meta( $post_id, '_yoast_wpseo_metadesc', $description );
		return true;
	}

	private function set_yoast_canonical( $post_id, $canonical_url ) {
		update_post_meta( $post_id, '_yoast_wpseo_canonical', $canonical_url );
		return true;
	}

	private function set_yoast_focus_keyword( $post_id, $keyword ) {
		if ( is_array( $keyword ) ) {
			$keyword = implode( ', ', $keyword );
		}
		update_post_meta( $post_id, '_yoast_wpseo_focuskw', $keyword );
		return true;
	}

	private function set_yoast_robots( $post_id, $robots ) {
		if ( is_array( $robots ) ) {
			foreach ( $robots as $directive => $value ) {
				switch ( $directive ) {
					case 'index':
						update_post_meta( $post_id, '_yoast_wpseo_meta-robots-noindex', $value ? '0' : '1' );
						break;
					case 'follow':
						update_post_meta( $post_id, '_yoast_wpseo_meta-robots-nofollow', $value ? '0' : '1' );
						break;
					case 'archive':
						update_post_meta( $post_id, '_yoast_wpseo_meta-robots-noarchive', $value ? '0' : '1' );
						break;
					case 'snippet':
						update_post_meta( $post_id, '_yoast_wpseo_meta-robots-nosnippet', $value ? '0' : '1' );
						break;
				}
			}
		}
		return true;
	}

	private function process_yoast_social( $post_id, array $seo_data ) {
		// OpenGraph
		if ( isset( $seo_data['og_title'] ) ) {
			update_post_meta( $post_id, '_yoast_wpseo_opengraph-title', $seo_data['og_title'] );
		}
		if ( isset( $seo_data['og_description'] ) ) {
			update_post_meta( $post_id, '_yoast_wpseo_opengraph-description', $seo_data['og_description'] );
		}
		if ( isset( $seo_data['og_image'] ) ) {
			update_post_meta( $post_id, '_yoast_wpseo_opengraph-image', $seo_data['og_image'] );
		}

		// Twitter
		if ( isset( $seo_data['twitter_title'] ) ) {
			update_post_meta( $post_id, '_yoast_wpseo_twitter-title', $seo_data['twitter_title'] );
		}
		if ( isset( $seo_data['twitter_description'] ) ) {
			update_post_meta( $post_id, '_yoast_wpseo_twitter-description', $seo_data['twitter_description'] );
		}
		if ( isset( $seo_data['twitter_image'] ) ) {
			update_post_meta( $post_id, '_yoast_wpseo_twitter-image', $seo_data['twitter_image'] );
		}
	}

	// Rank Math specific methods

	private function set_rankmath_title( $post_id, $title ) {
		update_post_meta( $post_id, 'rank_math_title', $title );
		return true;
	}

	private function set_rankmath_description( $post_id, $description ) {
		update_post_meta( $post_id, 'rank_math_description', $description );
		return true;
	}

	private function set_rankmath_canonical( $post_id, $canonical_url ) {
		update_post_meta( $post_id, 'rank_math_canonical_url', $canonical_url );
		return true;
	}

	private function set_rankmath_focus_keyword( $post_id, $keyword ) {
		if ( is_array( $keyword ) ) {
			$keyword = implode( ', ', $keyword );
		}
		update_post_meta( $post_id, 'rank_math_focus_keyword', $keyword );
		return true;
	}

	private function set_rankmath_robots( $post_id, $robots ) {
		if ( is_array( $robots ) ) {
			$robots_meta = array();
			foreach ( $robots as $directive => $value ) {
				if ( $value ) {
					$robots_meta[] = $directive;
				} else {
					$robots_meta[] = 'no' . $directive;
				}
			}
			update_post_meta( $post_id, 'rank_math_robots', $robots_meta );
		}
		return true;
	}

	private function process_rankmath_social( $post_id, array $seo_data ) {
		// Facebook/OpenGraph
		if ( isset( $seo_data['og_title'] ) ) {
			update_post_meta( $post_id, 'rank_math_facebook_title', $seo_data['og_title'] );
		}
		if ( isset( $seo_data['og_description'] ) ) {
			update_post_meta( $post_id, 'rank_math_facebook_description', $seo_data['og_description'] );
		}
		if ( isset( $seo_data['og_image'] ) ) {
			update_post_meta( $post_id, 'rank_math_facebook_image', $seo_data['og_image'] );
		}

		// Twitter
		if ( isset( $seo_data['twitter_title'] ) ) {
			update_post_meta( $post_id, 'rank_math_twitter_title', $seo_data['twitter_title'] );
		}
		if ( isset( $seo_data['twitter_description'] ) ) {
			update_post_meta( $post_id, 'rank_math_twitter_description', $seo_data['twitter_description'] );
		}
		if ( isset( $seo_data['twitter_image'] ) ) {
			update_post_meta( $post_id, 'rank_math_twitter_image', $seo_data['twitter_image'] );
		}
	}

	// SEOPress specific methods

	private function set_seopress_robots( $post_id, $robots ) {
		if ( is_array( $robots ) ) {
			foreach ( $robots as $directive => $value ) {
				// SEOPress uses "yes" for enabled, empty for disabled
				switch ( $directive ) {
					case 'index':
						update_post_meta( $post_id, '_seopress_robots_index', $value ? 'yes' : '' );
						break;
					case 'follow':
						update_post_meta( $post_id, '_seopress_robots_follow', $value ? 'yes' : '' );
						break;
					case 'imageindex':
						update_post_meta( $post_id, '_seopress_robots_imageindex', $value ? 'yes' : '' );
						break;
					case 'archive':
						update_post_meta( $post_id, '_seopress_robots_archive', $value ? 'yes' : '' );
						break;
					case 'snippet':
						update_post_meta( $post_id, '_seopress_robots_snippet', $value ? 'yes' : '' );
						break;
				}
			}
		}
		return true;
	}

	private function process_seopress_social( $post_id, array $seo_data ) {
		// Facebook/OpenGraph
		if ( isset( $seo_data['og_title'] ) ) {
			update_post_meta( $post_id, '_seopress_social_fb_title', $seo_data['og_title'] );
		}
		if ( isset( $seo_data['og_description'] ) ) {
			update_post_meta( $post_id, '_seopress_social_fb_desc', $seo_data['og_description'] );
		}
		if ( isset( $seo_data['og_image'] ) ) {
			update_post_meta( $post_id, '_seopress_social_fb_img', $seo_data['og_image'] );
		}

		// Twitter
		if ( isset( $seo_data['twitter_title'] ) ) {
			update_post_meta( $post_id, '_seopress_social_twitter_title', $seo_data['twitter_title'] );
		}
		if ( isset( $seo_data['twitter_description'] ) ) {
			update_post_meta( $post_id, '_seopress_social_twitter_desc', $seo_data['twitter_description'] );
		}
		if ( isset( $seo_data['twitter_image'] ) ) {
			update_post_meta( $post_id, '_seopress_social_twitter_img', $seo_data['twitter_image'] );
		}
	}

	private function process_seopress_faq( $post_id, $faq_items ) {
		if ( empty( $faq_items ) || ! is_array( $faq_items ) ) {
			return false;
		}

		// Build SEOPress FAQ schema format
		// SEOPress uses standard Schema.org FAQPage format
		$faq_schema = array(
			'@context'   => 'https://schema.org',
			'@type'      => 'FAQPage',
			'mainEntity' => array(),
		);

		foreach ( $faq_items as $item ) {
			if ( empty( $item['question'] ) || empty( $item['answer'] ) ) {
				continue;
			}

			$faq_schema['mainEntity'][] = array(
				'@type'          => 'Question',
				'name'           => wp_strip_all_tags( $item['question'] ),
				'acceptedAnswer' => array(
					'@type' => 'Answer',
					'text'  => wp_strip_all_tags( $item['answer'] ),
				),
			);
		}

		if ( empty( $faq_schema['mainEntity'] ) ) {
			return false;
		}

		// Store in SEOPress PRO schemas format
		// Note: This requires SEOPress PRO for full schema support
		// For free version, the schema will be stored but may not render
		$existing_schemas = get_post_meta( $post_id, '_seopress_pro_schemas_manual', true );
		$schemas_array    = ! empty( $existing_schemas ) ? json_decode( $existing_schemas, true ) : array();

		if ( ! is_array( $schemas_array ) ) {
			$schemas_array = array();
		}

		// Add FAQ schema to array
		$schemas_array[] = $faq_schema;

		update_post_meta( $post_id, '_seopress_pro_schemas_manual', wp_json_encode( $schemas_array ) );

		$this->logger->info(
			'SEOPress FAQ schema created',
			array(
				'post_id'   => $post_id,
				'faq_count' => count( $faq_schema['mainEntity'] ),
				'has_pro'   => defined( 'SEOPRESS_PRO_VERSION' ),
			)
		);

		return true;
	}

	// Meta mapping methods

	private function get_yoast_meta_mapping() {
		// Comprehensive Yoast meta keys mapping
		return array(
			'title'                 => '_yoast_wpseo_title',
			'description'           => '_yoast_wpseo_metadesc',
			'canonical_url'         => '_yoast_wpseo_canonical',
			'focus_keyword'         => '_yoast_wpseo_focuskw',
			'og_title'              => '_yoast_wpseo_opengraph-title',
			'og_description'        => '_yoast_wpseo_opengraph-description',
			'og_image'              => '_yoast_wpseo_opengraph-image',
			'twitter_title'         => '_yoast_wpseo_twitter-title',
			'twitter_description'   => '_yoast_wpseo_twitter-description',
			'twitter_image'         => '_yoast_wpseo_twitter-image',
			'breadcrumb_title'      => '_yoast_wpseo_bctitle',
			'meta_robots_noindex'   => '_yoast_wpseo_meta-robots-noindex',
			'meta_robots_nofollow'  => '_yoast_wpseo_meta-robots-nofollow',
			'meta_robots_noarchive' => '_yoast_wpseo_meta-robots-noarchive',
			'meta_robots_nosnippet' => '_yoast_wpseo_meta-robots-nosnippet',
			'link_count'            => '_yoast_wpseo_linkdex',
			'content_score'         => '_yoast_wpseo_content_score',
		);
	}

	private function get_rankmath_meta_mapping() {
		// Comprehensive Rank Math meta keys mapping
		return array(
			'title'                 => 'rank_math_title',
			'description'           => 'rank_math_description',
			'canonical_url'         => 'rank_math_canonical_url',
			'focus_keyword'         => 'rank_math_focus_keyword',
			'og_title'              => 'rank_math_facebook_title',
			'og_description'        => 'rank_math_facebook_description',
			'og_image'              => 'rank_math_facebook_image',
			'twitter_title'         => 'rank_math_twitter_title',
			'twitter_description'   => 'rank_math_twitter_description',
			'twitter_image'         => 'rank_math_twitter_image',
			'robots'                => 'rank_math_robots',
			'breadcrumb_title'      => 'rank_math_breadcrumb_title',
			'pillar_content'        => 'rank_math_pillar_content',
			'snippet_data'          => 'rank_math_snippet_data',
			'primary_focus_keyword' => 'rank_math_focus_keyword',
			'secondary_keywords'    => 'rank_math_focus_keyword', // Rank Math handles multiple keywords differently
		);
	}

	private function get_seopress_meta_mapping() {
		// Comprehensive SEOPress meta keys mapping
		// Reference: https://www.seopress.org/support/guides/list-of-all-post-metas-generated-by-seopress/
		return array(
			// Core SEO fields
			'title'               => '_seopress_titles_title',
			'description'         => '_seopress_titles_desc',
			'canonical_url'       => '_seopress_robots_canonical',
			'focus_keyword'       => '_seopress_analysis_target_kw',

			// Social - Facebook/OpenGraph
			'og_title'            => '_seopress_social_fb_title',
			'og_description'      => '_seopress_social_fb_desc',
			'og_image'            => '_seopress_social_fb_img',

			// Social - Twitter
			'twitter_title'       => '_seopress_social_twitter_title',
			'twitter_description' => '_seopress_social_twitter_desc',
			'twitter_image'       => '_seopress_social_twitter_img',

			// Additional fields
			'breadcrumb_title'    => '_seopress_robots_breadcrumbs',
			'primary_category'    => '_seopress_robots_primary_cat',
		);
	}

	private function is_same_site_url( $url ) {
		if ( empty( $url ) ) {
			return true;
		}

		$parsed = wp_parse_url( $url );

		if ( empty( $parsed['host'] ) ) {
			return true;
		}

		$site_host = wp_parse_url( home_url(), PHP_URL_HOST );

		// Compare hosts after stripping www. prefix
		$url_host  = strtolower( preg_replace( '/^www\./i', '', $parsed['host'] ) );
		$site_host = strtolower( preg_replace( '/^www\./i', '', $site_host ) );

		return $url_host === $site_host;
	}

	private function invalidate_sitemap_cache() {
		// Rank Math: API-first, then file cache fallback
		if ( class_exists( '\\RankMath\\Sitemap\\Cache' ) ) {
			\RankMath\Sitemap\Cache::invalidate_storage();
		}

		// Rank Math: Clear file-based sitemap cache
		$upload_dir     = wp_upload_dir();
		$rankmath_cache = $upload_dir['basedir'] . '/rank-math/';
		if ( is_dir( $rankmath_cache ) ) {
			$files = glob( $rankmath_cache . '*.xml' );
			if ( $files ) {
				foreach ( $files as $file ) {
					wp_delete_file( $file );
				}
			}
		}

		// Yoast: Clear sitemap cache
		if ( class_exists( '\\WPSEO_Sitemaps_Cache' ) ) {
			\WPSEO_Sitemaps_Cache::clear();
		}

		// SEOPress: Uses transients, auto-invalidated by WordPress — no action needed
	}

	private function sanitize_seo_value( $value ) {
		if ( is_array( $value ) ) {
			return array_map( array( $this, 'sanitize_seo_value' ), $value );
		}

		if ( is_string( $value ) ) {
			// For SEO fields, we want to preserve some HTML entities but strip tags
			return sanitize_textarea_field( $value );
		}

		return $value;
	}

	// Public methods for admin interface

	public function get_detected_seo_plugins() {
		$plugins = array();

		if ( $this->options->is_yoast_active() ) {
			$plugins['yoast'] = array(
				'name'    => 'Yoast SEO',
				'version' => defined( 'WPSEO_VERSION' ) ? WPSEO_VERSION : 'unknown',
				'active'  => true,
			);
		}

		if ( $this->options->is_rankmath_active() ) {
			$plugins['rankmath'] = array(
				'name'    => 'Rank Math',
				'version' => defined( 'RANK_MATH_VERSION' ) ? RANK_MATH_VERSION : 'unknown',
				'active'  => true,
			);
		}

		if ( $this->options->is_seopress_active() ) {
			$plugins['seopress'] = array(
				'name'    => 'SEOPress',
				'version' => defined( 'SEOPRESS_VERSION' ) ? SEOPRESS_VERSION : 'unknown',
				'active'  => true,
				'has_pro' => defined( 'SEOPRESS_PRO_VERSION' ),
			);
		}

		return $plugins;
	}

	public function get_recommended_mode() {
		if ( $this->options->is_yoast_active() ) {
			return 'yoast_api';
		}

		if ( $this->options->is_rankmath_active() ) {
			return 'rankmath_api';
		}

		if ( $this->options->is_seopress_active() ) {
			return 'seopress_api';
		}

		return 'meta_mapping';
	}

	public function get_default_meta_mapping( $plugin = null ) {
		switch ( $plugin ) {
			case 'yoast':
				return $this->get_yoast_meta_mapping();
			case 'rankmath':
				return $this->get_rankmath_meta_mapping();
			case 'seopress':
				return $this->get_seopress_meta_mapping();
			default:
				return array(
					'title'               => '_wisewand_seo_title',
					'description'         => '_wisewand_seo_description',
					'canonical_url'       => '_wisewand_seo_canonical',
					'focus_keyword'       => '_wisewand_seo_focus_keyword',
					'og_title'            => '_wisewand_seo_og_title',
					'og_description'      => '_wisewand_seo_og_description',
					'og_image'            => '_wisewand_seo_og_image',
					'twitter_title'       => '_wisewand_seo_twitter_title',
					'twitter_description' => '_wisewand_seo_twitter_description',
					'twitter_image'       => '_wisewand_seo_twitter_image',
				);
		}
	}

	public function validate_meta_mapping( $mapping ) {
		$errors = array();

		foreach ( $mapping as $field => $meta_key ) {
			if ( ! empty( $meta_key ) ) {
				// Check if meta key follows WordPress conventions
				if ( ! preg_match( '/^[a-zA-Z0-9_-]+$/', $meta_key ) ) {
					$errors[ $field ] = __( 'Meta key contains invalid characters', 'wisewand-ai-content-writer-seo-content-generator' );
				}

				// Warn about potential conflicts
				if ( ! $this->starts_with( $meta_key, '_' ) && ! $this->starts_with( $meta_key, 'wisewand_' ) ) {
					$errors[ $field ] = __( 'Meta key should start with underscore or wisewand_ prefix', 'wisewand-ai-content-writer-seo-content-generator' );
				}
			}
		}

		return $errors;
	}

	public function export_seo_data( $post_id ) {
		$seo_data = array();

		// Get Wisewand SEO data
		$meta_keys = get_post_meta( $post_id );
		foreach ( $meta_keys as $key => $values ) {
			if ( $this->starts_with( $key, '_wisewand_seo_' ) ) {
				$field                          = str_replace( '_wisewand_seo_', '', $key );
				$seo_data['wisewand'][ $field ] = $values[0] ?? '';
			}
		}

		// Get Yoast data if active
		if ( $this->options->is_yoast_active() ) {
			$yoast_mapping = $this->get_yoast_meta_mapping();
			foreach ( $yoast_mapping as $field => $meta_key ) {
				$value = get_post_meta( $post_id, $meta_key, true );
				if ( ! empty( $value ) ) {
					$seo_data['yoast'][ $field ] = $value;
				}
			}
		}

		// Get Rank Math data if active
		if ( $this->options->is_rankmath_active() ) {
			$rankmath_mapping = $this->get_rankmath_meta_mapping();
			foreach ( $rankmath_mapping as $field => $meta_key ) {
				$value = get_post_meta( $post_id, $meta_key, true );
				if ( ! empty( $value ) ) {
					$seo_data['rankmath'][ $field ] = $value;
				}
			}
		}

		// Get SEOPress data if active
		if ( $this->options->is_seopress_active() ) {
			$seopress_mapping = $this->get_seopress_meta_mapping();
			foreach ( $seopress_mapping as $field => $meta_key ) {
				$value = get_post_meta( $post_id, $meta_key, true );
				if ( ! empty( $value ) ) {
					$seo_data['seopress'][ $field ] = $value;
				}
			}
		}

		return $seo_data;
	}

	private function post_type_supports_seo( $post_type ) {
		// Load Plugin_Detector if not already loaded
		if ( ! class_exists( 'Wisewand\\Utils\\Plugin_Detector' ) ) {
			$detector_file = WISEWAND_PLUGIN_DIR . 'includes/Utils/Plugin_Detector.php';
			if ( file_exists( $detector_file ) ) {
				require_once $detector_file;
			}
		}

		if ( class_exists( 'Wisewand\\Utils\\Plugin_Detector' ) ) {
			return \Wisewand\Utils\Plugin_Detector::post_type_supports_seo( $post_type );
		}

		// Fallback logic
		if ( ! $this->options->is_yoast_active() && ! $this->options->is_rankmath_active() && ! $this->options->is_seopress_active() ) {
			return false;
		}

		// Most SEO plugins support posts and pages
		return in_array( $post_type, array( 'post', 'page', 'product' ) );
	}

	public function process_taxonomy_seo_data( $term_id, $tt_id, $taxonomy ) {
		// Only process taxonomies with Wisewand SEO data
		$seo_data = get_term_meta( $term_id, '_wisewand_seo_data', true );
		if ( empty( $seo_data ) ) {
			return;
		}

		$this->logger->info(
			'Processing taxonomy SEO data',
			array(
				'term_id'    => $term_id,
				'taxonomy'   => $taxonomy,
				'seo_fields' => array_keys( $seo_data ),
			)
		);

		// Process SEO for taxonomies (categories, product categories, etc.)
		if ( $this->options->is_yoast_active() ) {
			$this->process_yoast_taxonomy_seo( $term_id, $taxonomy, $seo_data );
		} elseif ( $this->options->is_rankmath_active() ) {
			$this->process_rankmath_taxonomy_seo( $term_id, $taxonomy, $seo_data );
		} elseif ( $this->options->is_seopress_active() ) {
			$this->process_seopress_taxonomy_seo( $term_id, $taxonomy, $seo_data );
		} else {
			$this->process_fallback_taxonomy_seo( $term_id, $taxonomy, $seo_data );
		}

		// Clean up processed data
		delete_term_meta( $term_id, '_wisewand_seo_data' );
	}

	private function process_yoast_taxonomy_seo( $term_id, $taxonomy, $seo_data ) {
		// Yoast taxonomy meta keys (same for both category and product_cat)
		$yoast_tax_mapping = array(
			'title'          => 'wpseo_title',
			'description'    => 'wpseo_desc',
			'canonical_url'  => 'wpseo_canonical',
			'focus_keyword'  => 'wpseo_focuskw',
			'og_title'       => 'wpseo_opengraph-title',
			'og_description' => 'wpseo_opengraph-description',
		);

		$this->logger->debug(
			'Processing Yoast taxonomy SEO',
			array(
				'term_id'    => $term_id,
				'taxonomy'   => $taxonomy,
				'seo_fields' => array_keys( $seo_data ),
			)
		);

		foreach ( $seo_data as $field => $value ) {
			if ( empty( $value ) || ! isset( $yoast_tax_mapping[ $field ] ) ) {
				continue;
			}

			$meta_key = $yoast_tax_mapping[ $field ];
			update_term_meta( $term_id, $meta_key, $this->sanitize_seo_value( $value ) );

			$this->logger->debug(
				'Set Yoast taxonomy meta',
				array(
					'term_id'  => $term_id,
					'field'    => $field,
					'meta_key' => $meta_key, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- False positive: 'meta_key' is a logging context parameter, not a database query
				)
			);
		}
	}

	private function process_rankmath_taxonomy_seo( $term_id, $taxonomy, $seo_data ) {
		// Rank Math taxonomy meta keys
		$rankmath_tax_mapping = array(
			'title'          => 'rank_math_title',
			'description'    => 'rank_math_description',
			'canonical_url'  => 'rank_math_canonical_url',
			'focus_keyword'  => 'rank_math_focus_keyword',
			'og_title'       => 'rank_math_facebook_title',
			'og_description' => 'rank_math_facebook_description',
		);

		foreach ( $seo_data as $field => $value ) {
			if ( empty( $value ) || ! isset( $rankmath_tax_mapping[ $field ] ) ) {
				continue;
			}

			$meta_key = $rankmath_tax_mapping[ $field ];
			update_term_meta( $term_id, $meta_key, $this->sanitize_seo_value( $value ) );

			$this->logger->debug(
				'Set Rank Math taxonomy meta',
				array(
					'term_id'  => $term_id,
					'field'    => $field,
					'meta_key' => $meta_key, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- False positive: 'meta_key' is a logging context parameter, not a database query
				)
			);
		}
	}

	private function process_fallback_taxonomy_seo( $term_id, $taxonomy, $seo_data ) {
		// Store in Wisewand namespaced meta for taxonomies
		foreach ( $seo_data as $field => $value ) {
			if ( ! empty( $value ) ) {
				update_term_meta( $term_id, "_wisewand_seo_{$field}", $this->sanitize_seo_value( $value ) );
			}
		}
	}

	private function process_seopress_taxonomy_seo( $term_id, $taxonomy, $seo_data ) {
		// SEOPress taxonomy meta keys
		// Reference: https://www.seopress.org/support/guides/list-of-all-post-metas-generated-by-seopress/
		$seopress_tax_mapping = array(
			'title'               => '_seopress_titles_title',
			'description'         => '_seopress_titles_desc',
			'canonical_url'       => '_seopress_robots_canonical',
			'focus_keyword'       => '_seopress_analysis_target_kw',
			'og_title'            => '_seopress_social_fb_title',
			'og_description'      => '_seopress_social_fb_desc',
			'og_image'            => '_seopress_social_fb_img',
			'twitter_title'       => '_seopress_social_twitter_title',
			'twitter_description' => '_seopress_social_twitter_desc',
			'twitter_image'       => '_seopress_social_twitter_img',
		);

		$this->logger->debug(
			'Processing SEOPress taxonomy SEO',
			array(
				'term_id'    => $term_id,
				'taxonomy'   => $taxonomy,
				'seo_fields' => array_keys( $seo_data ),
			)
		);

		foreach ( $seo_data as $field => $value ) {
			if ( empty( $value ) || ! isset( $seopress_tax_mapping[ $field ] ) ) {
				continue;
			}

			$meta_key = $seopress_tax_mapping[ $field ];
			update_term_meta( $term_id, $meta_key, $this->sanitize_seo_value( $value ) );

			$this->logger->debug(
				'Set SEOPress taxonomy meta',
				array(
					'term_id'  => $term_id,
					'field'    => $field,
					'meta_key' => $meta_key, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- False positive: 'meta_key' is a logging context parameter, not a database query
				)
			);
		}
	}

	// FAQ Schema Processing Methods

	/**
	 * Process FAQ schema for RankMath
	 * Converts FAQ items to RankMath's schema format
	 *
	 * @param int   $post_id WordPress post ID
	 * @param array $faq_items Array of ['question' => '...', 'answer' => '...']
	 * @return bool True if schema was successfully set
	 */
	private function process_rankmath_faq( $post_id, $faq_items ) {
		if ( empty( $faq_items ) || ! is_array( $faq_items ) ) {
			return false;
		}

		// Build RankMath FAQ schema format
		// RankMath uses 'rank_math_schema_FAQPage' meta key
		$faq_schema = array();

		foreach ( $faq_items as $item ) {
			if ( empty( $item['question'] ) || empty( $item['answer'] ) ) {
				continue;
			}

			$faq_schema[] = array(
				'@type'          => 'Question',
				'name'           => wp_strip_all_tags( $item['question'] ),
				'acceptedAnswer' => array(
					'@type' => 'Answer',
					'text'  => wp_strip_all_tags( $item['answer'] ),
				),
			);
		}

		if ( empty( $faq_schema ) ) {
			return false;
		}

		// RankMath stores FAQ in their schema system
		// We need to add it to the post's schema metadata
		$schema_data = array(
			'@type'      => 'FAQPage',
			'@id'        => get_permalink( $post_id ) . '#faqpage',
			'mainEntity' => $faq_schema,
		);

		// Store in RankMath's format
		update_post_meta( $post_id, 'rank_math_schema_FAQPage', wp_json_encode( $schema_data ) );

		// Also enable FAQ page type in RankMath
		update_post_meta( $post_id, 'rank_math_rich_snippet', 'faq' );

		$this->logger->info(
			'RankMath FAQ schema created',
			array(
				'post_id'     => $post_id,
				'faq_count'   => count( $faq_schema ),
				'schema_data' => $schema_data,
			)
		);

		return true;
	}

	/**
	 * Process FAQ schema for Yoast SEO
	 * Converts FAQ items to Yoast's schema format
	 *
	 * @param int   $post_id WordPress post ID
	 * @param array $faq_items Array of ['question' => '...', 'answer' => '...']
	 * @return bool True if schema was successfully set
	 */
	private function process_yoast_faq( $post_id, $faq_items ) {
		if ( empty( $faq_items ) || ! is_array( $faq_items ) ) {
			return false;
		}

		// Build Yoast FAQ schema format
		$faq_blocks = array();

		foreach ( $faq_items as $index => $item ) {
			if ( empty( $item['question'] ) || empty( $item['answer'] ) ) {
				continue;
			}

			// Yoast uses FAQ blocks stored as JSON
			$faq_blocks[] = array(
				'id'           => 'faq-question-' . ( $index + 1 ),
				'jsonQuestion' => wp_strip_all_tags( $item['question'] ),
				'jsonAnswer'   => wp_strip_all_tags( $item['answer'] ),
			);
		}

		if ( empty( $faq_blocks ) ) {
			return false;
		}

		// Store FAQ blocks in Yoast format
		update_post_meta( $post_id, '_yoast_wpseo_schema_page_type', 'FAQPage' );
		update_post_meta( $post_id, '_yoast_wpseo_faq_blocks', wp_json_encode( $faq_blocks ) );

		$this->logger->info(
			'Yoast FAQ schema created',
			array(
				'post_id'   => $post_id,
				'faq_count' => count( $faq_blocks ),
			)
		);

		return true;
	}

	/**
	 * Remove FAQ section from post content
	 * Only called if FAQ schema was successfully added to RankMath/Yoast
	 *
	 * @param int $post_id WordPress post ID
	 * @return bool True if FAQ was removed
	 */
	private function remove_faq_from_content( $post_id ) {
		// Check if we have the FAQ HTML to remove
		$faq_html = get_post_meta( $post_id, '_wisewand_faq_html', true );
		if ( empty( $faq_html ) ) {
			$this->logger->debug( 'No FAQ HTML stored for removal', array( 'post_id' => $post_id ) );
			return false;
		}

		$post = get_post( $post_id );
		if ( ! $post ) {
			return false;
		}

		$content = $post->post_content;

		// Use regex to find and remove FAQ section
		// This is more reliable than exact HTML matching
		$patterns = array(
			// Pattern 1: <h2>FAQ</h2> section until next <h2> or end
			'/<h2[^>]*>.*?(?:FAQ|Frequently Asked Questions|Questions|Q&amp;A|Q &amp; A).*?<\/h2>.*?(?=<h2|$)/is',
			// Pattern 2: Simpler - just the FAQ heading and following h3/p pairs
			'/<h2[^>]*>.*?FAQ.*?<\/h2>\s*(?:<h3[^>]*>.*?<\/h3>\s*<p[^>]*>.*?<\/p>\s*)+/is',
		);

		$content_before = $content;
		foreach ( $patterns as $pattern ) {
			$content = preg_replace( $pattern, '', $content );

			// If pattern matched and removed something, break
			if ( $content !== $content_before ) {
				break;
			}
		}

		// Only update if FAQ was actually removed
		if ( $content !== $content_before ) {
			// Clean up extra whitespace
			$content = preg_replace( '/\n{3,}/', "\n\n", $content );
			$content = trim( $content );

			wp_update_post(
				array(
					'ID'           => $post_id,
					'post_content' => $content,
				)
			);

			$this->logger->info(
				'FAQ section removed from content',
				array(
					'post_id'               => $post_id,
					'content_length_before' => strlen( $content_before ),
					'content_length_after'  => strlen( $content ),
					'bytes_removed'         => strlen( $content_before ) - strlen( $content ),
				)
			);

			// Mark that FAQ was removed
			update_post_meta( $post_id, '_wisewand_faq_removed_from_content', true );

			return true;
		}

		$this->logger->debug(
			'FAQ section not found in content (already removed or pattern mismatch)',
			array(
				'post_id' => $post_id,
			)
		);

		return false;
	}

	// Helper method for PHP compatibility
	private function starts_with( $haystack, $needle ) {
		return strpos( $haystack, $needle ) === 0;
	}
}
