<?php
/** Update verified Ocean Extra per-post page-title overrides. */

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

function wpagent_ability_update_oceanwp_post_title(): array {
	return array(
		'label'               => __( 'Ocean-Extra-Beitragstitel aktualisieren', 'wp-agent-companion' ),
		'description'         => __( 'Ändert sichere Ocean-Extra-Seitentitelvorgaben mit Konfliktschutz, Laufzeitprüfung, Read-back und fail-closed Recovery bei nicht verifizierter Persistierung.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'post_id'       => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'settings'      => wpagent_oceanwp_extra_title_settings_schema(),
			),
			'required'             => array( 'post_id', 'expected_hash', 'settings' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'post_id'    => array( 'type' => 'integer' ),
				'post_type'  => array( 'type' => 'string' ),
				'title'      => wpagent_oceanwp_extra_title_state_schema(),
				'state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'verified'   => array( 'type' => 'boolean' ),
			),
			'required'             => array( 'post_id', 'post_type', 'title', 'state_hash', 'verified' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_update_oceanwp_post_title',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_update_oceanwp_post_title( $input ) {
	$ready = wpagent_oceanwp_extra_title_require_runtime();
	if ( is_wp_error( $ready ) ) {
		return $ready;
	}
	$input = is_array( $input ) ? $input : array();
	$post  = wpagent_oceanwp_post_target( absint( $input['post_id'] ?? 0 ) );
	if ( is_wp_error( $post ) ) {
		return $post;
	}
	$schema = wpagent_oceanwp_extra_title_settings_schema();
	$valid  = rest_validate_value_from_schema( $input['settings'] ?? null, $schema, 'settings' );
	if ( is_wp_error( $valid ) || ! is_array( $input['settings'] ?? null ) || ! wpagent_oceanwp_extra_title_settings_are_safe( $input['settings'] ) ) {
		return new WP_Error( 'wpagent_ocean_extra_title_invalid_settings', __( 'Die Ocean-Extra-Seitentiteleinstellungen sind ungültig.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$settings = rest_sanitize_value_from_schema( $input['settings'], $schema, 'settings' );
	if ( is_wp_error( $settings ) || ! is_array( $settings ) || ! $settings || ! wpagent_oceanwp_extra_title_settings_are_safe( $settings ) ) {
		return new WP_Error( 'wpagent_ocean_extra_title_invalid_settings', __( 'Die Ocean-Extra-Seitentiteleinstellungen sind ungültig.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}

	$post_id = $post->ID;
	$lock    = wpagent_oceanwp_post_acquire_lock( $post_id );
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		$post = wpagent_oceanwp_post_target( $post_id );
		if ( is_wp_error( $post ) ) {
			return $post;
		}
		$ready = wpagent_oceanwp_extra_title_require_runtime();
		if ( is_wp_error( $ready ) ) {
			return $ready;
		}
		$previous = wpagent_oceanwp_extra_title_snapshot( $post );
		if ( is_wp_error( $previous ) ) {
			return $previous;
		}
		$previous_hash = wpagent_oceanwp_extra_title_state_hash( $previous );
		$expected_hash = strtolower( (string) ( $input['expected_hash'] ?? '' ) );
		if ( ! preg_match( '/^[a-f0-9]{64}$/', $expected_hash ) || ! hash_equals( $previous_hash, $expected_hash ) ) {
			return new WP_Error( 'wpagent_ocean_extra_title_conflict', __( 'Die Ocean-Extra-Seitentiteleinstellungen haben sich seit dem Lesen geändert. Lies sie neu und wiederhole den Vorgang.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $previous_hash ) );
		}
		$expected = wpagent_oceanwp_extra_title_expected_snapshot( $previous, $settings );
		$expected_write_hash = wpagent_oceanwp_extra_title_state_hash( $expected );
		if ( ! wpagent_oceanwp_post_refresh_lock( $post_id, $lock ) ) {
			return new WP_Error( 'wpagent_ocean_extra_title_lock_lost', __( 'Die Ocean-Extra-Seitentiteländerung hat ihre exklusive Sperre verloren.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		if ( (int) get_current_blog_id() !== $previous['blog_id'] ) {
			return new WP_Error( 'wpagent_ocean_extra_title_site_changed', __( 'Die Websitezuordnung hat sich während des Ocean-Extra-Titelvorgangs geändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$write_post = wpagent_oceanwp_post_target( $post_id );
		if ( is_wp_error( $write_post ) ) {
			return $write_post;
		}
		try {
			wpagent_oceanwp_extra_title_persist_settings( $write_post->ID, $previous['blog_id'], $settings, $lock );
		} catch ( Throwable $error ) {
			return wpagent_oceanwp_extra_title_recovery_required( $post_id );
		}
		$fresh = wpagent_oceanwp_extra_title_snapshot( $post );
		if ( is_wp_error( $fresh ) || ! hash_equals( $expected_write_hash, wpagent_oceanwp_extra_title_state_hash( $fresh ) ) ) {
			return wpagent_oceanwp_extra_title_recovery_required( $post_id );
		}
		if ( ! wpagent_oceanwp_post_refresh_lock( $post_id, $lock ) ) {
			return wpagent_oceanwp_extra_title_recovery_required( $post_id );
		}
		$runtime = wpagent_oceanwp_extra_title_runtime_state( $post_id );
		if ( is_wp_error( $runtime ) || ! wpagent_oceanwp_extra_title_runtime_matches( $settings, $runtime ) ) {
			return wpagent_oceanwp_extra_title_recovery_required( $post_id );
		}
		if ( ! wpagent_oceanwp_post_refresh_lock( $post_id, $lock ) ) {
			return wpagent_oceanwp_extra_title_recovery_required( $post_id );
		}
		if ( (int) get_current_blog_id() !== $previous['blog_id'] ) {
			return wpagent_oceanwp_extra_title_recovery_required( $post_id );
		}
		$verified_post = wpagent_oceanwp_post_target( $post_id );
		if ( is_wp_error( $verified_post ) ) {
			return wpagent_oceanwp_extra_title_recovery_required( $post_id );
		}
		return array(
			'post_id'    => (int) $verified_post->ID,
			'post_type'  => $verified_post->post_type,
			'title'      => wpagent_oceanwp_extra_title_normalize( $fresh ),
			'state_hash' => wpagent_oceanwp_extra_title_state_hash( $fresh ),
			'verified'   => true,
		);
	} finally {
		wpagent_oceanwp_post_release_lock( $post_id, $lock );
	}
}

/** @param array<string,mixed> $settings */
function wpagent_oceanwp_extra_title_persist_settings( int $post_id, int $blog_id, array $settings, string $lock ): void {
	$mutate = static function ( callable $callback ) use ( $post_id, $blog_id, $lock ): void {
		if ( ! wpagent_oceanwp_post_refresh_lock( $post_id, $lock ) ) {
			throw new RuntimeException( 'Ocean Extra title lock lost before provider write.' );
		}
		if ( (int) get_current_blog_id() !== $blog_id ) {
			throw new RuntimeException( 'Ocean Extra title site changed before provider write.' );
		}
		$target = wpagent_oceanwp_post_target( $post_id );
		if ( is_wp_error( $target ) ) {
			throw new RuntimeException( 'Ocean Extra title target changed before provider write.' );
		}
		$callback( $target->ID );
		if ( ! wpagent_oceanwp_post_refresh_lock( $post_id, $lock ) ) {
			throw new RuntimeException( 'Ocean Extra title lock lost after provider write.' );
		}
		if ( (int) get_current_blog_id() !== $blog_id || is_wp_error( wpagent_oceanwp_post_target( $post_id ) ) ) {
			throw new RuntimeException( 'Ocean Extra title target changed after provider write.' );
		}
	};
	foreach ( wpagent_oceanwp_extra_title_select_catalog() as $field => $definition ) {
		if ( ! array_key_exists( $field, $settings ) ) {
			continue;
		}
		$mutate(
			static function ( int $target_id ) use ( $settings, $field, $definition ): void {
				if ( 'inherit' === $settings[ $field ] ) {
					delete_post_meta( $target_id, $definition['meta'] );
				} else {
					update_post_meta( $target_id, $definition['meta'], $definition['values'][ $settings[ $field ] ] );
				}
			}
		);
	}
	foreach ( wpagent_oceanwp_extra_title_text_catalog() as $field => $definition ) {
		if ( ! array_key_exists( $field, $settings ) ) {
			continue;
		}
		$mutate(
			static function ( int $target_id ) use ( $settings, $field, $definition ): void {
				if ( 'inherit' === $settings[ $field ]['mode'] ) {
					delete_post_meta( $target_id, $definition['meta'] );
				} else {
					update_post_meta( $target_id, $definition['meta'], $settings[ $field ]['value'] );
				}
			}
		);
	}
}
