<?php
/**
 * Provider-side post SEO writers kept separate from the public safety gate.
 *
 * @package WPAgentCompanion
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Führt den Provider-Write aus, während der aufrufende Wrapper den Post-Lock hält.
 *
 * @param 'rankmath'|'yoast'|'aioseo'|'seopress' $plugin
 * @param array<string,string|bool|null>           $fields
 * @return array|WP_Error
 */
function wpagent_exec_set_seo_meta_locked( int $post_id, string $plugin, array $fields, string $lock, string $previous_hash ) {
	if ( ! wpagent_seo_lock_checkpoint( $post_id, $lock ) ) {
		return wpagent_seo_recovery_required( $post_id, $previous_hash, 'lock_lost_before_provider_write' );
	}
	if ( 'aioseo' === $plugin ) {
		return wpagent_set_aioseo_meta( $post_id, $fields );
	}
	if ( 'seopress' === $plugin ) {
		return wpagent_set_seopress_meta( $post_id, $fields );
	}
	$map    = array(
		'rankmath' => array(
			'title'                   => 'rank_math_title',
			'description'             => 'rank_math_description',
			'focus_keyword'           => 'rank_math_focus_keyword',
			'canonical_url'           => 'rank_math_canonical_url',
			'open_graph_title'        => 'rank_math_facebook_title',
			'open_graph_description'  => 'rank_math_facebook_description',
			'twitter_title'           => 'rank_math_twitter_title',
			'twitter_description'     => 'rank_math_twitter_description',
		),
		'yoast'    => array(
			'title'                   => '_yoast_wpseo_title',
			'description'             => '_yoast_wpseo_metadesc',
			'focus_keyword'           => '_yoast_wpseo_focuskw',
			'canonical_url'           => '_yoast_wpseo_canonical',
			'open_graph_title'        => '_yoast_wpseo_opengraph-title',
			'open_graph_description'  => '_yoast_wpseo_opengraph-description',
			'twitter_title'           => '_yoast_wpseo_twitter-title',
			'twitter_description'     => '_yoast_wpseo_twitter-description',
		),
	);
	$keys   = $map[ $plugin ];
	$touched_meta_keys = array();
	foreach ( $keys as $field => $meta_key ) {
		if ( null !== $fields[ $field ] ) {
			$touched_meta_keys[] = $meta_key;
		}
	}
	if ( 'rankmath' === $plugin && ( null !== $fields['robots_noindex'] || null !== $fields['robots_nofollow'] ) ) {
		$touched_meta_keys[] = 'rank_math_robots';
	}
	if ( 'rankmath' === $plugin && null !== $fields['cornerstone'] ) {
		$touched_meta_keys[] = 'rank_math_pillar_content';
	}
	if ( 'yoast' === $plugin ) {
		if ( null !== $fields['robots_noindex'] ) {
			$touched_meta_keys[] = '_yoast_wpseo_meta-robots-noindex';
		}
		if ( null !== $fields['robots_nofollow'] ) {
			$touched_meta_keys[] = '_yoast_wpseo_meta-robots-nofollow';
		}
		if ( null !== $fields['cornerstone'] ) {
			$touched_meta_keys[] = '_yoast_wpseo_is_cornerstone';
		}
	}
	$before    = wpagent_capture_seo_postmeta( $post_id, $touched_meta_keys );
	$candidate = $before;

	foreach ( $keys as $field => $key ) {
		$value = $fields[ $field ];
		if ( null === $value ) {
			continue;
		}
		$expected_rows = '' === $value ? array() : array( $value );
		if ( '' === $value ) {
			delete_post_meta( $post_id, $key );
		} else {
			update_post_meta( $post_id, $key, $value );
		}
		if ( get_post_meta( $post_id, $key, false ) === $expected_rows ) {
			$candidate[ $key ] = $expected_rows;
		}
	}
	if ( 'rankmath' === $plugin && ( null !== $fields['robots_noindex'] || null !== $fields['robots_nofollow'] ) ) {
		$current = $before['rank_math_robots'][0] ?? array();
		$current = is_array( $current ) ? array_values( array_unique( array_map( 'sanitize_key', $current ) ) ) : array();
		$index   = null;
		$follow  = null;
		foreach ( $current as $directive ) {
			if ( in_array( $directive, array( 'index', 'noindex' ), true ) ) {
				$index = $directive;
			} elseif ( in_array( $directive, array( 'follow', 'nofollow' ), true ) ) {
				$follow = $directive;
			}
		}
		if ( null !== $fields['robots_noindex'] ) {
			$index = $fields['robots_noindex'] ? 'noindex' : 'index';
		}
		if ( null !== $fields['robots_nofollow'] ) {
			$follow = $fields['robots_nofollow'] ? 'nofollow' : 'follow';
		}
		$other  = array_values( array_diff( $current, array( 'index', 'noindex', 'follow', 'nofollow' ) ) );
		$robots = array_values( array_filter( array_merge( array( $index, $follow ), $other ) ) );
		$expected_rows = array( $robots );
		update_post_meta( $post_id, 'rank_math_robots', $robots );
		if ( get_post_meta( $post_id, 'rank_math_robots', false ) === $expected_rows ) {
			$candidate['rank_math_robots'] = $expected_rows;
		}
	}
	if ( 'rankmath' === $plugin && null !== $fields['cornerstone'] ) {
		$expected_rows = $fields['cornerstone'] ? array( 'on' ) : array();
		if ( $fields['cornerstone'] ) {
			update_post_meta( $post_id, 'rank_math_pillar_content', 'on' );
		} else {
			delete_post_meta( $post_id, 'rank_math_pillar_content' );
		}
		if ( get_post_meta( $post_id, 'rank_math_pillar_content', false ) === $expected_rows ) {
			$candidate['rank_math_pillar_content'] = $expected_rows;
		}
	}
	if ( 'yoast' === $plugin ) {
		if ( null !== $fields['robots_noindex'] ) {
			$expected_rows = array( $fields['robots_noindex'] ? '1' : '2' );
			update_post_meta( $post_id, '_yoast_wpseo_meta-robots-noindex', $expected_rows[0] );
			if ( get_post_meta( $post_id, '_yoast_wpseo_meta-robots-noindex', false ) === $expected_rows ) {
				$candidate['_yoast_wpseo_meta-robots-noindex'] = $expected_rows;
			}
		}
		if ( null !== $fields['robots_nofollow'] ) {
			$expected_rows = array( $fields['robots_nofollow'] ? '1' : '0' );
			update_post_meta( $post_id, '_yoast_wpseo_meta-robots-nofollow', $expected_rows[0] );
			if ( get_post_meta( $post_id, '_yoast_wpseo_meta-robots-nofollow', false ) === $expected_rows ) {
				$candidate['_yoast_wpseo_meta-robots-nofollow'] = $expected_rows;
			}
		}
		if ( null !== $fields['cornerstone'] ) {
			$expected_rows = $fields['cornerstone'] ? array( '1' ) : array();
			if ( $fields['cornerstone'] ) {
				update_post_meta( $post_id, '_yoast_wpseo_is_cornerstone', '1' );
			} else {
				delete_post_meta( $post_id, '_yoast_wpseo_is_cornerstone' );
			}
			if ( get_post_meta( $post_id, '_yoast_wpseo_is_cornerstone', false ) === $expected_rows ) {
				$candidate['_yoast_wpseo_is_cornerstone'] = $expected_rows;
			}
		}
	}
	if ( ! wpagent_seo_lock_checkpoint( $post_id, $lock ) ) {
		return wpagent_seo_recovery_required( $post_id, $previous_hash, 'lock_lost_after_provider_write' );
	}

	$indexable_verified = null;
	$yoast_output_fields = array_diff_key( $fields, array( 'focus_keyword' => true, 'cornerstone' => true ) );
	$yoast_output_fields = array_filter( $yoast_output_fields, static fn ( $value ): bool => null !== $value );
	$yoast_cornerstone   = null !== $fields['cornerstone'] ? (bool) $fields['cornerstone'] : null;
	$refresh_yoast       = 'yoast' === $plugin && ( ! empty( $yoast_output_fields ) || null !== $yoast_cornerstone );
	if ( $refresh_yoast ) {
		// A regular post update runs Yoast's supported save_post watcher after
		// the new meta values exist. The independent verifier then reads Yoast's
		// effective Meta Surface and prevents a postmeta-only false positive.
		$refresh = wp_update_post( array( 'ID' => $post_id ), true );
		if ( is_wp_error( $refresh ) ) {
			$indexable_verified = false;
		} elseif ( function_exists( 'wpagent_render_verify_check_seo_yoast' ) ) {
			// Vor dem ersten Zugriff auf die Meta Surface neu aufbauen. Die Surface
			// memoisiert ihre Presentation request-lokal; ein vorheriger Lesezugriff
			// würde deshalb auch nach einem späteren Rebuild veraltete Werte liefern.
			$indexable_verified = wpagent_refresh_yoast_indexable( $post_id, $yoast_cornerstone );
			if ( $indexable_verified && ! empty( $yoast_output_fields ) ) {
				$indexable = wpagent_render_verify_check_seo_yoast( $post_id, $yoast_output_fields );
				$indexable_verified = true === ( $indexable['agrees'] ?? false );
			}
		} else {
			$indexable_verified = false;
		}
	}
	$fresh = wpagent_read_seo_meta( $post_id, $plugin );
	if ( is_wp_error( $fresh ) ) {
		return wpagent_seo_recovery_required( $post_id, $previous_hash, 'readback_unavailable' );
	}
	$verification = wpagent_verify_seo_snapshot( $fields, $fresh );
	foreach ( $verification['written'] as $field => &$field_result ) {
		if ( isset( $keys[ $field ] ) ) {
			$field_result['meta_key'] = $keys[ $field ];
		}
		if ( 'cornerstone' === $field ) {
			$field_result['meta_key'] = 'rankmath' === $plugin ? 'rank_math_pillar_content' : '_yoast_wpseo_is_cornerstone';
		}
	}
	unset( $field_result );
	$verified = $verification['verified'] && ( false !== $indexable_verified );
	$rolled_back       = false;
	$rollback_verified = null;
	if ( ! $verified ) {
		$rolled_back       = true;
		$rollback_verified = wpagent_seo_lock_checkpoint( $post_id, $lock ) && wpagent_restore_seo_postmeta( $post_id, $before, $candidate );
		if ( ! $rollback_verified ) {
			return wpagent_seo_recovery_required( $post_id, $previous_hash, 'candidate_drift_before_rollback' );
		}
		if ( $refresh_yoast ) {
			$rollback_post = wp_update_post( array( 'ID' => $post_id ), true );
			$rollback_cornerstone = null;
			if ( null !== $yoast_cornerstone ) {
				$rollback_cornerstone = in_array( '1', $before['_yoast_wpseo_is_cornerstone'] ?? array(), true );
			}
			$rollback_verified = $rollback_verified
				&& ! is_wp_error( $rollback_post )
				&& wpagent_refresh_yoast_indexable( $post_id, $rollback_cornerstone );
		}
	}

	return array(
		'post_id'            => $post_id,
		'plugin'             => $plugin,
		'written'            => $verification['written'],
		'verified'           => $verified,
		'indexable_verified' => $indexable_verified,
		'rolled_back'        => $rolled_back,
		'rollback_verified'  => $rollback_verified,
	);
}
