<?php
/** Mount verified OceanWP My Library templates on one post. */

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

function wpagent_ability_update_oceanwp_post_library_templates(): array {
	return array(
		'label'               => __( 'OceanWP-Library-Zuordnung aktualisieren', 'wp-agent-companion' ),
		'description'         => __( 'Bindet geprüfte statische OceanWP-Library-Templates als Beitragsheader oder Footer ein, mit Konfliktschutz, Laufzeitprüfung und fail-closed Recovery.', '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}$' ),
				'templates'     => array(
					'type'                 => 'object',
					'properties'           => array( 'header' => wpagent_ocean_extra_library_mount_schema(), 'footer' => wpagent_ocean_extra_library_mount_schema() ),
					'minProperties'        => 1,
					'maxProperties'        => 2,
					'additionalProperties' => false,
				),
			),
			'required'             => array( 'post_id', 'expected_hash', 'templates' ),
			'additionalProperties' => false,
		),
		'output_schema'       => wpagent_ocean_extra_library_state_schema( true ),
		'execute_callback'    => 'wpagent_exec_update_oceanwp_post_library_templates',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_update_oceanwp_post_library_templates( $input ) {
	$ready = wpagent_ocean_extra_library_require_runtime();
	if ( is_wp_error( $ready ) ) {
		return $ready;
	}
	$input    = is_array( $input ) ? $input : array();
	$settings = $input['templates'] ?? null;
	if ( ! is_array( $settings ) || ! wpagent_ocean_extra_library_settings_are_safe( $settings ) ) {
		return new WP_Error( 'wpagent_ocean_extra_library_invalid_settings', __( 'Die OceanWP-Library-Zuordnung ist ungültig.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$target = wpagent_oceanwp_extra_layout_post_target( absint( $input['post_id'] ?? 0 ) );
	if ( is_wp_error( $target ) ) {
		return $target;
	}
	$post_id = $target['post']->ID;
	$blog_id = $target['blog_id'];
	$lock    = wpagent_oceanwp_post_acquire_lock( $post_id );
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		$ready  = wpagent_ocean_extra_library_require_runtime();
		$target = wpagent_oceanwp_extra_layout_post_target( $post_id, $blog_id );
		if ( is_wp_error( $ready ) || is_wp_error( $target ) ) {
			return is_wp_error( $ready ) ? $ready : $target;
		}
		$before = wpagent_ocean_extra_library_snapshot( $target['post'], $blog_id );
		if ( is_wp_error( $before ) ) {
			return $before;
		}
		$before_hash   = wpagent_ocean_extra_library_state_hash( $before );
		$expected_hash = strtolower( (string) ( $input['expected_hash'] ?? '' ) );
		if ( ! preg_match( '/^[a-f0-9]{64}$/', $expected_hash ) || ! hash_equals( $before_hash, $expected_hash ) ) {
			return new WP_Error( 'wpagent_ocean_extra_library_conflict', __( 'Die OceanWP-Library-Zuordnung hat sich seit dem Lesen geändert. Lies sie neu und wiederhole den Vorgang.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $before_hash ) );
		}
		$expected = wpagent_ocean_extra_library_expected_snapshot( $before, $settings );
		if ( is_wp_error( $expected ) ) {
			return $expected;
		}
		$stable = wpagent_ocean_extra_library_snapshot( $target['post'], $blog_id );
		if ( is_wp_error( $stable ) || ! hash_equals( $before_hash, wpagent_ocean_extra_library_state_hash( $stable ) ) ) {
			$current_hash = is_array( $stable ) ? wpagent_ocean_extra_library_state_hash( $stable ) : $before_hash;
			return new WP_Error( 'wpagent_ocean_extra_library_conflict', __( 'Die OceanWP-Library-Zuordnung oder ein eingebundenes Template hat sich während der Prüfung geändert. Lies den Zustand neu.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $current_hash ) );
		}
		if ( ! wpagent_oceanwp_post_refresh_lock( $post_id, $lock ) ) {
			return new WP_Error( 'wpagent_ocean_extra_library_lock_lost', __( 'Die OceanWP-Library-Zuordnung hat ihre exklusive Sperre verloren.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$write_target = wpagent_oceanwp_extra_layout_post_target( $post_id, $blog_id );
		if ( is_wp_error( $write_target ) ) {
			return $write_target;
		}
		$persisted = wpagent_ocean_extra_library_persist( $write_target['post']->ID, $blog_id, $settings, $before, $lock );
		if ( is_wp_error( $persisted ) ) {
			$data = $persisted->get_error_data();
			if ( ! is_array( $data ) || empty( $data['write_started'] ) ) {
				return $persisted;
			}
			return wpagent_ocean_extra_library_recovery_required( $post_id, $blog_id );
		}
		$fresh = wpagent_ocean_extra_library_snapshot( $target['post'], $blog_id );
		if ( is_wp_error( $fresh ) || ! hash_equals( wpagent_ocean_extra_library_state_hash( $expected ), wpagent_ocean_extra_library_state_hash( $fresh ) ) ) {
			return wpagent_ocean_extra_library_recovery_required( $post_id, $blog_id );
		}
		if ( ! wpagent_oceanwp_post_refresh_lock( $post_id, $lock ) ) {
			return wpagent_ocean_extra_library_recovery_required( $post_id, $blog_id );
		}
		$runtime = wpagent_ocean_extra_library_runtime_state( $post_id );
		if ( is_wp_error( $runtime ) || ! wpagent_ocean_extra_library_runtime_matches( $settings, $runtime ) ) {
			return wpagent_ocean_extra_library_recovery_required( $post_id, $blog_id );
		}
		if ( ! wpagent_oceanwp_post_refresh_lock( $post_id, $lock ) ) {
			return wpagent_ocean_extra_library_recovery_required( $post_id, $blog_id );
		}
		$verified_target = wpagent_oceanwp_extra_layout_post_target( $post_id, $blog_id );
		if ( is_wp_error( $verified_target ) ) {
			return wpagent_ocean_extra_library_recovery_required( $post_id, $blog_id );
		}
		$state = wpagent_ocean_extra_library_normalize( $fresh );
		return array( 'post_id' => $post_id, 'post_type' => $verified_target['post']->post_type, 'header' => $state['header'], 'footer' => $state['footer'], 'state_hash' => wpagent_ocean_extra_library_state_hash( $fresh ), 'verified' => true );
	} finally {
		wpagent_oceanwp_post_release_lock( $post_id, $lock );
	}
}

function wpagent_ocean_extra_library_persist_lock_lost( bool $write_started ): WP_Error {
	return new WP_Error(
		$write_started ? 'wpagent_ocean_extra_library_lock_lost_after_write' : 'wpagent_ocean_extra_library_lock_lost',
		__( 'Die OceanWP-Library-Zuordnung hat ihre exklusive Sperre verloren.', 'wp-agent-companion' ),
		array( 'status' => $write_started ? 500 : 409, 'write_started' => $write_started )
	);
}

function wpagent_ocean_extra_library_persist_failed( bool $write_started ): WP_Error {
	return new WP_Error(
		'wpagent_ocean_extra_library_write_failed',
		__( 'OceanWP konnte die Library-Zuordnung nicht sicher speichern.', 'wp-agent-companion' ),
		array( 'status' => $write_started ? 500 : 502, 'write_started' => $write_started )
	);
}

function wpagent_ocean_extra_library_persist_target_lost(): WP_Error {
	return new WP_Error(
		'wpagent_ocean_extra_library_target_lost_after_write',
		__( 'Der OceanWP-Library-Zielbeitrag ist nach einer begonnenen Änderung nicht mehr sicher bearbeitbar.', 'wp-agent-companion' ),
		array( 'status' => 500, 'write_started' => true )
	);
}

/** @param array<string,mixed> $settings @param array<string,mixed> $before @return true|WP_Error */
function wpagent_ocean_extra_library_persist( int $post_id, int $blog_id, array $settings, array $before, string $lock ) {
	$write_started = false;
	$mutate = static function ( callable $callback ) use ( $post_id, $blog_id, $lock, &$write_started ) {
		if ( ! wpagent_oceanwp_post_refresh_lock( $post_id, $lock ) ) {
			return wpagent_ocean_extra_library_persist_lock_lost( $write_started );
		}
		$target = wpagent_oceanwp_extra_layout_post_target( $post_id, $blog_id );
		if ( is_wp_error( $target ) ) {
			return $write_started ? wpagent_ocean_extra_library_persist_target_lost() : $target;
		}
		$write_started = true;
		$callback( $target['post']->ID );
		if ( ! wpagent_oceanwp_post_refresh_lock( $post_id, $lock ) ) {
			return wpagent_ocean_extra_library_persist_lock_lost( true );
		}
		if ( is_wp_error( wpagent_oceanwp_extra_layout_post_target( $post_id, $blog_id ) ) ) {
			return wpagent_ocean_extra_library_persist_target_lost();
		}
		return true;
	};
	try {
		if ( isset( $settings['header'] ) ) {
			if ( 'set' === $settings['header']['mode'] ) {
				$result = $mutate( static fn( int $target_id ) => update_post_meta( $target_id, 'ocean_header_style', 'custom' ) );
				if ( is_wp_error( $result ) ) {
					return $result;
				}
				$result = $mutate( static fn( int $target_id ) => update_post_meta( $target_id, 'ocean_custom_header_template', $settings['header']['template_id'] ) );
				if ( is_wp_error( $result ) ) {
					return $result;
				}
			} else {
				$result = $mutate( static fn( int $target_id ) => delete_post_meta( $target_id, 'ocean_custom_header_template' ) );
				if ( is_wp_error( $result ) ) {
					return $result;
				}
				if ( 'custom' === $before['meta']['ocean_header_style']['value'] ) {
					$result = $mutate( static fn( int $target_id ) => delete_post_meta( $target_id, 'ocean_header_style' ) );
					if ( is_wp_error( $result ) ) {
						return $result;
					}
				}
			}
		}
		if ( isset( $settings['footer'] ) ) {
			$result = 'set' === $settings['footer']['mode']
				? $mutate( static fn( int $target_id ) => update_post_meta( $target_id, 'ocean_custom_footer_template', $settings['footer']['template_id'] ) )
				: $mutate( static fn( int $target_id ) => delete_post_meta( $target_id, 'ocean_custom_footer_template' ) );
			if ( is_wp_error( $result ) ) {
				return $result;
			}
		}
		return true;
	} catch ( Throwable $error ) {
		return wpagent_ocean_extra_library_persist_failed( $write_started );
	}
}
