<?php
/**
 * Elementor SEO metadata save handler.
 *
 * @package SEOvaultSEO
 */

namespace SEOvaultSEO\Integrations\Elementor;

use SEOvaultSEO\Core\PostMeta;
use SEOvaultSEO\Utils\Sanitizer;
use SEOvaultSEO\Utils\SeoAssessment;

/**
 * Persists the compact Elementor panel fields through a protected AJAX action.
 */
class SaveHandler {

	/**
	 * Whether init() has already run.
	 *
	 * @var bool
	 */
	private static $initialized = false;

	/**
	 * Register the AJAX write path.
	 *
	 * @return void
	 */
	public static function init() {
		if ( self::$initialized ) {
			return;
		}

		self::$initialized = true;
		add_action( 'wp_ajax_seovaultseo_elementor_save', array( __CLASS__, 'ajax_save' ) );
	}

	/**
	 * Save SEO fields sent by the Elementor editor.
	 *
	 * @return void
	 */
	public static function ajax_save() {
		check_ajax_referer( 'seovaultseo_elementor_save', 'nonce' );

		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified immediately above.
		$post_id = isset( $_POST['post_id'] ) ? absint( wp_unslash( $_POST['post_id'] ) ) : 0;

		if ( ! $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
			wp_send_json_error(
				array( 'message' => __( 'You are not allowed to edit this content.', 'seovault-ai' ) ),
				403
			);
		}

		$post = get_post( $post_id );
		if ( ! $post || 'attachment' === $post->post_type ) {
			wp_send_json_error(
				array( 'message' => __( 'The requested content could not be edited.', 'seovault-ai' ) ),
				400
			);
		}

		if ( is_multisite() && ms_is_switched() ) {
			wp_send_json_error(
				array( 'message' => __( 'SEO settings cannot be saved while the site is switched.', 'seovault-ai' ) ),
				409
			);
		}

		// phpcs:disable WordPress.Security.NonceVerification.Missing -- Nonce verified above.
		$data = array(
			'seo_title'       => isset( $_POST['seo_title'] ) ? Sanitizer::sanitize_title( sanitize_text_field( wp_unslash( $_POST['seo_title'] ) ) ) : null,
			'seo_description' => isset( $_POST['seo_description'] ) ? Sanitizer::sanitize_description( sanitize_textarea_field( wp_unslash( $_POST['seo_description'] ) ) ) : null,
			'focus_keyword'   => isset( $_POST['focus_keyword'] ) ? Sanitizer::sanitize_keyword( sanitize_text_field( wp_unslash( $_POST['focus_keyword'] ) ) ) : null,
			'canonical_url'   => isset( $_POST['canonical_url'] ) ? Sanitizer::sanitize_canonical_url( esc_url_raw( wp_unslash( $_POST['canonical_url'] ) ) ) : null,
			'noindex'         => isset( $_POST['noindex'] ) ? (bool) absint( wp_unslash( $_POST['noindex'] ) ) : null,
			'nofollow'        => isset( $_POST['nofollow'] ) ? (bool) absint( wp_unslash( $_POST['nofollow'] ) ) : null,
			'og_title'        => isset( $_POST['og_title'] ) ? Sanitizer::sanitize_og_title( sanitize_text_field( wp_unslash( $_POST['og_title'] ) ) ) : null,
			'og_description'  => isset( $_POST['og_description'] ) ? Sanitizer::sanitize_og_description( sanitize_textarea_field( wp_unslash( $_POST['og_description'] ) ) ) : null,
			'og_image'        => isset( $_POST['og_image'] ) ? Sanitizer::sanitize_og_image( esc_url_raw( wp_unslash( $_POST['og_image'] ) ) ) : null,
		);
		// phpcs:enable WordPress.Security.NonceVerification.Missing

		$saved = self::save_fields( $post_id, $data );

		wp_send_json_success(
			array(
				'message' => __( 'SEO settings saved.', 'seovault-ai' ),
				'fields'  => $saved,
			)
		);
	}

	/**
	 * Persist a sanitized field collection.
	 *
	 * Null values are omitted so partial requests do not erase stored metadata.
	 *
	 * @param int   $post_id Post ID.
	 * @param array $data    Sanitized Elementor field values.
	 * @return array Saved field values.
	 */
	public static function save_fields( $post_id, $data ) {
		$setters = array(
			'seo_title'       => 'set_seo_title',
			'seo_description' => 'set_seo_description',
			'focus_keyword'   => 'set_focus_keyword',
			'canonical_url'   => 'set_canonical_url',
			'noindex'         => 'set_noindex',
			'nofollow'        => 'set_nofollow',
			'og_title'        => 'set_og_title',
			'og_description'  => 'set_og_description',
			'og_image'        => 'set_og_image',
		);

		$saved = array();
		foreach ( $setters as $field => $setter ) {
			if ( ! array_key_exists( $field, $data ) || null === $data[ $field ] ) {
				continue;
			}

			PostMeta::$setter( $post_id, $data[ $field ] );
			$saved[ $field ] = $data[ $field ];
		}

		SeoAssessment::clear_cache();
		do_action( 'seovaultseo_elementor_meta_saved', $post_id, $saved );

		return $saved;
	}
}
