<?php
/** Strict read-only projections for OceanWP 4.2.2 free settings. */

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

define( 'WPAGENT_OCEANWP_FREE_SURFACE_THEME_VERSION', '4.2.2' );
define( 'WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOKS', 10 );
define( 'WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOK_BYTES', 2048 );
define( 'WPAGENT_OCEANWP_FREE_SURFACE_MAX_POST_FORMAT_BYTES', 2048 );

/** @return true|WP_Error */
function wpagent_oceanwp_free_surface_require_theme() {
	if ( ! wpagent_oceanwp_is_active() ) {
		return new WP_Error( 'wpagent_oceanwp_inactive', __( 'OceanWP oder ein OceanWP-Child-Theme ist nicht aktiv.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( WPAGENT_OCEANWP_FREE_SURFACE_THEME_VERSION !== wpagent_oceanwp_version() || ! wpagent_oceanwp_runtime_ready() ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_runtime_missing', __( 'Diese OceanWP-Leseoberfläche erfordert genau OceanWP 4.2.2.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return true;
}

/** @return true|WP_Error */
function wpagent_oceanwp_free_surface_require_extra() {
	$theme = wpagent_oceanwp_free_surface_require_theme();
	if ( is_wp_error( $theme ) ) {
		return $theme;
	}
	if ( ! class_exists( 'Ocean_Extra' ) || WPAGENT_OCEAN_EXTRA_MIN_VERSION !== wpagent_oceanwp_extra_version() ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_extra_runtime_missing', __( 'Die OceanWP-Hook- und Beitragsoberfläche erfordert genau Ocean Extra 2.5.8.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return true;
}

/** @return array{blog_id:int,version:string,mods:array<string,mixed>}|WP_Error */
function wpagent_oceanwp_free_surface_theme_snapshot() {
	$ready = wpagent_oceanwp_free_surface_require_theme();
	if ( is_wp_error( $ready ) ) {
		return $ready;
	}
	$blog_id = (int) get_current_blog_id();
	if ( $blog_id < 1 ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_invalid_site', __( 'Die OceanWP-Websitezuordnung ist ungültig.', 'wp-agent-companion' ), array( 'status' => 502 ) );
	}
	$snapshot = wpagent_oceanwp_snapshot();
	if ( is_wp_error( $snapshot ) ) {
		return $snapshot;
	}
	return array( 'blog_id' => $blog_id, 'version' => wpagent_oceanwp_version(), 'mods' => $snapshot['mods']['value'] );
}

/** @param array<string,mixed> $state */
function wpagent_oceanwp_free_surface_hash( string $scope, int $blog_id, array $state ): string {
	return hash( 'sha256', $blog_id . "\0" . WPAGENT_OCEANWP_FREE_SURFACE_THEME_VERSION . "\0" . $scope . "\0" . maybe_serialize( $state ) );
}

/** @return mixed */
function wpagent_oceanwp_free_surface_mod( array $mods, string $key, $default ) {
	return array_key_exists( $key, $mods ) ? $mods[ $key ] : $default;
}

/** @return bool|WP_Error */
function wpagent_oceanwp_free_surface_bool( $value ) {
	if ( is_bool( $value ) ) {
		return $value;
	}
	if ( is_int( $value ) && ( 0 === $value || 1 === $value ) ) {
		return 1 === $value;
	}
	if ( is_string( $value ) && ( '0' === $value || '1' === $value ) ) {
		return '1' === $value;
	}
	return wpagent_oceanwp_free_surface_invalid_state();
}

/** @param string[] $allowed @return string|WP_Error */
function wpagent_oceanwp_free_surface_enum( $value, array $allowed ) {
	if ( ! is_string( $value ) || ! in_array( $value, $allowed, true ) ) {
		return wpagent_oceanwp_free_surface_invalid_state();
	}
	return $value;
}

/** @return int|WP_Error */
function wpagent_oceanwp_free_surface_int( $value, int $minimum, int $maximum ) {
	if ( is_int( $value ) ) {
		$number = $value;
	} elseif ( is_string( $value ) && ctype_digit( $value ) ) {
		$number = (int) $value;
	} else {
		return wpagent_oceanwp_free_surface_invalid_state();
	}
	return $number >= $minimum && $number <= $maximum ? $number : wpagent_oceanwp_free_surface_invalid_state();
}

/** @return string|WP_Error */
function wpagent_oceanwp_free_surface_text( $value, int $maximum ) {
	if ( ! is_string( $value ) || strlen( $value ) > $maximum || wp_check_invalid_utf8( $value ) !== $value || preg_match( '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', $value ) ) {
		return wpagent_oceanwp_free_surface_invalid_state();
	}
	return $value;
}

function wpagent_oceanwp_free_surface_invalid_state(): WP_Error {
	return new WP_Error( 'wpagent_oceanwp_free_surface_invalid_state', __( 'OceanWP enthält einen nicht sicher auswertbaren freien Einstellungsstand.', 'wp-agent-companion' ), array( 'status' => 502 ) );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_oceanwp_free_surface_footer( array $mods ) {
	$settings = array(
		'widgets_enabled'    => wpagent_oceanwp_free_surface_bool( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_footer_widgets', true ) ),
		'widgets_visibility' => wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_footer_widgets_visibility', 'all-devices' ), array( 'all-devices', 'hide-tablet', 'hide-mobile', 'hide-tablet-mobile' ) ),
		'widgets_columns'    => array(
			'desktop' => wpagent_oceanwp_free_surface_int( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_footer_widgets_columns', 4 ), 1, 4 ),
			'tablet'  => wpagent_oceanwp_free_surface_int( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_footer_widgets_tablet_columns', 2 ), 1, 4 ),
			'mobile'  => wpagent_oceanwp_free_surface_int( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_footer_widgets_mobile_columns', 1 ), 1, 4 ),
		),
		'bottom_enabled'     => wpagent_oceanwp_free_surface_bool( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_footer_bottom', true ) ),
		'bottom_visibility'  => wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_bottom_footer_visibility', 'all-devices' ), array( 'all-devices', 'hide-tablet', 'hide-mobile', 'hide-tablet-mobile' ) ),
		'copyright_text'     => wpagent_oceanwp_free_surface_text( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_footer_copyright_text', 'Copyright [oceanwp_date] - WordPress Theme by OceanWP' ), WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOK_BYTES ),
	);
	foreach ( $settings as $value ) {
		if ( is_wp_error( $value ) || ( is_array( $value ) && array_filter( $value, 'is_wp_error' ) ) ) {
			return wpagent_oceanwp_free_surface_invalid_state();
		}
	}
	return $settings;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_oceanwp_free_surface_blog( array $mods ) {
	$layouts  = array( 'right-sidebar', 'left-sidebar', 'full-width', 'full-screen', 'both-sidebars' );
	$settings = array(
		'archive_layout'       => wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_blog_archives_layout', 'right-sidebar' ), $layouts ),
		'archive_style'        => wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_blog_style', 'large-entry' ), array( 'large-entry', 'grid-entry', 'thumbnail-entry' ) ),
		'grid_columns'         => array(
			'desktop' => wpagent_oceanwp_free_surface_int( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_blog_grid_columns', 2 ), 1, 6 ),
			'tablet'  => wpagent_oceanwp_free_surface_int( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_blog_grid_columns_tablet', 2 ), 1, 6 ),
			'mobile'  => wpagent_oceanwp_free_surface_int( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_blog_grid_columns_mobile', 1 ), 1, 6 ),
		),
		'excerpt_length'       => wpagent_oceanwp_free_surface_int( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_blog_entry_excerpt_length', 30 ), 1, 500 ),
		'pagination_style'     => wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_blog_pagination_style', 'standard' ), array( 'standard', 'infinite_scroll', 'load_more', 'next_prev' ) ),
		'single_layout'        => wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_blog_single_layout', 'right-sidebar' ), $layouts ),
		'single_content_width' => wpagent_oceanwp_free_surface_int( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_blog_single_content_width', 700 ), 0, 2000 ),
	);
	foreach ( $settings as $value ) {
		if ( is_wp_error( $value ) || ( is_array( $value ) && array_filter( $value, 'is_wp_error' ) ) ) {
			return wpagent_oceanwp_free_surface_invalid_state();
		}
	}
	return $settings;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_oceanwp_free_surface_woocommerce( array $mods ) {
	if ( ! class_exists( 'WooCommerce' ) ) {
		return array( 'available' => false, 'settings' => (object) array() );
	}
	$layouts  = array( 'right-sidebar', 'left-sidebar', 'full-width', 'full-screen', 'both-sidebars' );
	$settings = array(
		'shop_layout'          => wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_woo_shop_layout', 'left-sidebar' ), $layouts ),
		'product_style'        => wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_woo_products_style', 'default' ), array( 'default', 'hover' ) ),
		'grid_list_enabled'    => wpagent_oceanwp_free_surface_bool( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_woo_grid_list', true ) ),
		'result_count_enabled' => wpagent_oceanwp_free_surface_bool( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_woo_shop_result_count', true ) ),
		'pagination_style'     => wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_woo_pagination_style', 'standard' ), array( 'standard', 'infinite_scroll', 'load_more' ) ),
		'product_layout'       => wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_woo_product_layout', 'left-sidebar' ), $layouts ),
	);
	foreach ( $settings as $value ) {
		if ( is_wp_error( $value ) ) {
			return $value;
		}
	}
	return array( 'available' => true, 'settings' => $settings );
}

/** @return true|WP_Error */
function wpagent_oceanwp_free_surface_require_breadcrumbs() {
	$theme = wpagent_oceanwp_free_surface_require_theme();
	if ( is_wp_error( $theme ) ) {
		return $theme;
	}
	if ( ! function_exists( 'oceanwp_has_breadcrumbs' )
		|| ! function_exists( 'oceanwp_breadcrumb_trail' )
		|| ! function_exists( 'ocean_breadcrumbs_view' )
		|| ! function_exists( 'oceanwp_breadcrumbs_source_choices' ) ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_breadcrumbs_runtime_missing', __( 'Die geprüfte OceanWP-Breadcrumb-Oberfläche erfordert die native Breadcrumb-Laufzeit von OceanWP 4.2.2.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	try {
		$sources = oceanwp_breadcrumbs_source_choices();
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_breadcrumbs_runtime_missing', __( 'Die geprüfte OceanWP-Breadcrumb-Oberfläche konnte ihre Standardquelle nicht sicher bereitstellen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( ! is_array( $sources ) || ! array_key_exists( 'default', $sources ) ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_breadcrumbs_runtime_missing', __( 'Die geprüfte OceanWP-Breadcrumb-Oberfläche stellt ihre Standardquelle nicht bereit.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return true;
}

/** @return array{enabled:bool,source:string,position:string}|WP_Error */
function wpagent_oceanwp_free_surface_breadcrumbs( array $mods ) {
	$enabled = wpagent_oceanwp_free_surface_bool( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_breadcrumbs', true ) );
	$source  = wpagent_oceanwp_free_surface_enum( wpagent_oceanwp_free_surface_mod( $mods, 'ocean_breadcrumbs_source', 'default' ), array( 'default' ) );
	$raw_position = wpagent_oceanwp_free_surface_mod( $mods, 'ocean_breadcrumbs_position', '' );
	if ( ! is_string( $raw_position ) || ! in_array( $raw_position, array( '', 'under-title' ), true ) ) {
		return wpagent_oceanwp_free_surface_invalid_state();
	}
	if ( is_wp_error( $enabled ) || is_wp_error( $source ) ) {
		return wpagent_oceanwp_free_surface_invalid_state();
	}
	return array(
		'enabled'  => $enabled,
		'source'   => $source,
		'position' => '' === $raw_position ? 'absolute-right' : 'under-title',
	);
}

/** @return bool|WP_Error */
function wpagent_oceanwp_free_surface_breadcrumbs_runtime_state() {
	$ready = wpagent_oceanwp_free_surface_require_breadcrumbs();
	if ( is_wp_error( $ready ) ) {
		return $ready;
	}
	try {
		$enabled = oceanwp_has_breadcrumbs();
		if ( ! is_bool( $enabled ) ) {
			throw new UnexpectedValueException( 'OceanWP returned an invalid breadcrumbs visibility state.' );
		}
		return $enabled;
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_breadcrumbs_runtime_failed', __( 'OceanWP konnte die Breadcrumb-Laufzeit nicht sicher auswerten.', 'wp-agent-companion' ), array( 'status' => 502 ) );
	}
}

/** @return list<array{id:string,action:string,area:string,meta:string}> */
function wpagent_oceanwp_free_surface_hooks(): array {
	return array(
		array( 'id' => 'before_top_bar', 'action' => 'ocean_before_top_bar', 'area' => 'top_bar', 'meta' => 'ocean_shortcode_before_top_bar' ),
		array( 'id' => 'after_top_bar', 'action' => 'ocean_after_top_bar', 'area' => 'top_bar', 'meta' => 'ocean_shortcode_after_top_bar' ),
		array( 'id' => 'before_header', 'action' => 'ocean_before_header', 'area' => 'header', 'meta' => 'ocean_shortcode_before_header' ),
		array( 'id' => 'after_header', 'action' => 'ocean_after_header', 'area' => 'header', 'meta' => 'ocean_shortcode_after_header' ),
		array( 'id' => 'before_title', 'action' => 'ocean_before_page_header', 'area' => 'page_header', 'meta' => 'ocean_has_shortcode' ),
		array( 'id' => 'after_title', 'action' => 'ocean_after_page_header', 'area' => 'page_header', 'meta' => 'ocean_shortcode_after_title' ),
		array( 'id' => 'before_footer_widgets', 'action' => 'ocean_before_footer_widgets', 'area' => 'footer_widgets', 'meta' => 'ocean_shortcode_before_footer_widgets' ),
		array( 'id' => 'after_footer_widgets', 'action' => 'ocean_after_footer_widgets', 'area' => 'footer_widgets', 'meta' => 'ocean_shortcode_after_footer_widgets' ),
		array( 'id' => 'before_footer_bottom', 'action' => 'ocean_before_footer_bottom', 'area' => 'footer_bottom', 'meta' => 'ocean_shortcode_before_footer_bottom' ),
		array( 'id' => 'after_footer_bottom', 'action' => 'ocean_after_footer_bottom', 'area' => 'footer_bottom', 'meta' => 'ocean_shortcode_after_footer_bottom' ),
	);
}

/** @return array{post:WP_Post,blog_id:int}|WP_Error */
function wpagent_oceanwp_free_surface_post_target( int $post_id ) {
	$ready = wpagent_oceanwp_free_surface_require_extra();
	if ( is_wp_error( $ready ) ) {
		return $ready;
	}
	return wpagent_oceanwp_extra_layout_post_target( $post_id );
}

/** @return array{exists:bool,value:string}|WP_Error */
function wpagent_oceanwp_free_surface_post_meta( int $post_id, string $key ) {
	$raw  = get_metadata_raw( 'post', $post_id, $key, false );
	$rows = null === $raw ? array() : ( is_array( $raw ) ? $raw : array( $raw ) );
	if ( count( $rows ) > 1 || ( 1 === count( $rows ) && ! is_string( $rows[0] ) ) ) {
		return wpagent_oceanwp_free_surface_invalid_state();
	}
	$value = 1 === count( $rows ) ? $rows[0] : '';
	$text  = wpagent_oceanwp_free_surface_text( $value, WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOK_BYTES );
	return is_wp_error( $text ) ? $text : array( 'exists' => 1 === count( $rows ), 'value' => $text );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_oceanwp_free_surface_post_snapshot( WP_Post $post, int $blog_id ) {
	if ( $blog_id < 1 || $blog_id !== (int) get_current_blog_id() || ! current_user_can( 'edit_post', $post->ID ) ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_post_changed', __( 'Der OceanWP-Beitrag kann nicht mehr sicher gelesen werden.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$meta = array();
	foreach ( array( 'ocean_second_sidebar', 'ocean_both_sidebars_sidebars_width', 'ocean_disable_margins', 'ocean_display_top_bar' ) as $key ) {
		$value = wpagent_oceanwp_free_surface_post_meta( $post->ID, $key );
		if ( is_wp_error( $value ) ) {
			return $value;
		}
		$meta[ $key ] = $value;
	}
	foreach ( wpagent_oceanwp_free_surface_hooks() as $hook ) {
		$value = wpagent_oceanwp_free_surface_post_meta( $post->ID, $hook['meta'] );
		if ( is_wp_error( $value ) ) {
			return $value;
		}
		$meta[ $hook['meta'] ] = $value;
	}
	$sidebar = $meta['ocean_second_sidebar']['value'];
	if ( '' !== $sidebar && ! wpagent_oceanwp_extra_layout_sidebar_is_safe( $sidebar ) ) {
		return wpagent_oceanwp_free_surface_invalid_state();
	}
	$width = $meta['ocean_both_sidebars_sidebars_width']['value'];
	if ( '' !== $width && is_wp_error( wpagent_oceanwp_free_surface_int( $width, 0, 100 ) ) ) {
		return wpagent_oceanwp_free_surface_invalid_state();
	}
	if ( ! in_array( $meta['ocean_disable_margins']['value'], array( '', 'enable', 'on' ), true ) || ! in_array( $meta['ocean_display_top_bar']['value'], array( '', 'default', 'on', 'off' ), true ) ) {
		return wpagent_oceanwp_free_surface_invalid_state();
	}
	return array( 'blog_id' => $blog_id, 'post_id' => $post->ID, 'post_type' => $post->post_type, 'meta' => $meta );
}

/** @param array<string,mixed> $snapshot */
function wpagent_oceanwp_free_surface_post_hash( array $snapshot ): string {
	return hash( 'sha256', $snapshot['blog_id'] . "\0" . WPAGENT_OCEANWP_FREE_SURFACE_THEME_VERSION . "\0" . WPAGENT_OCEAN_EXTRA_MIN_VERSION . "\0" . $snapshot['post_id'] . "\0" . $snapshot['post_type'] . "\0" . maybe_serialize( $snapshot['meta'] ) );
}

/** @param array<string,mixed> $snapshot @return array<string,mixed> */
function wpagent_oceanwp_free_surface_post_normalize( array $snapshot ): array {
	$meta    = $snapshot['meta'];
	$sidebar = $meta['ocean_second_sidebar']['value'];
	$width   = $meta['ocean_both_sidebars_sidebars_width']['value'];
	$hooks   = array();
	foreach ( wpagent_oceanwp_free_surface_hooks() as $hook ) {
		$hooks[ $hook['id'] ] = '' !== $meta[ $hook['meta'] ]['value'];
	}
	return array(
		'layout' => array(
			'second_sidebar' => '' === $sidebar ? array( 'mode' => 'inherit' ) : array( 'mode' => 'set', 'sidebar_id' => $sidebar ),
			'sidebars_width' => '' === $width || 0 === (int) $width ? array( 'mode' => 'inherit' ) : array( 'mode' => 'set', 'value' => (int) $width ),
		),
		'visibility' => array(
			'margins' => 'on' === $meta['ocean_disable_margins']['value'] ? 'removed' : ( '' === $meta['ocean_disable_margins']['value'] ? 'inherit' : 'normal' ),
			'top_bar' => 'on' === $meta['ocean_display_top_bar']['value'] ? 'show' : ( 'off' === $meta['ocean_display_top_bar']['value'] ? 'hide' : 'inherit' ),
		),
		'configured_hooks' => $hooks,
	);
}

/** @return true|WP_Error */
function wpagent_oceanwp_free_surface_post_format_require_runtime() {
	$extra = wpagent_oceanwp_free_surface_require_extra();
	if ( is_wp_error( $extra ) ) {
		return $extra;
	}
	$formats = get_theme_support( 'post-formats' );
	if ( ! is_array( $formats )
		|| ! isset( $formats[0] )
		|| ! is_array( $formats[0] )
		|| ! in_array( 'link', $formats[0], true )
		|| ! in_array( 'quote', $formats[0], true )
		|| ! function_exists( 'ocean_link_post_url' )
		|| ! function_exists( 'ocean_link_post_url_target' ) ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_post_format_runtime_missing', __( 'Die geprüfte Ocean-Extra-Beitragsformatoberfläche erfordert die Link- und Quote-Laufzeit von OceanWP 4.2.2.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return true;
}

/** @return array<string,array{meta:string,kind:string,values?:string[]}> */
function wpagent_oceanwp_free_surface_post_format_catalog( string $format ): array {
	if ( 'link' === $format ) {
		return array(
			'url'    => array( 'meta' => 'ocean_link_format', 'kind' => 'url' ),
			'target' => array( 'meta' => 'ocean_link_format_target', 'kind' => 'enum', 'values' => array( 'self', 'blank' ) ),
		);
	}
	return array(
		'quote' => array( 'meta' => 'ocean_quote_format', 'kind' => 'text' ),
		'link'  => array( 'meta' => 'ocean_quote_format_link', 'kind' => 'enum', 'values' => array( 'post', 'none' ) ),
	);
}

/** @return array{post:WP_Post,blog_id:int,format:string}|WP_Error */
function wpagent_oceanwp_free_surface_post_format_target( int $post_id, ?int $expected_blog_id = null ) {
	$ready = wpagent_oceanwp_free_surface_post_format_require_runtime();
	if ( is_wp_error( $ready ) ) {
		return $ready;
	}
	$target = wpagent_oceanwp_free_surface_post_target( $post_id );
	if ( is_wp_error( $target ) ) {
		return $target;
	}
	if ( null !== $expected_blog_id && $expected_blog_id !== $target['blog_id'] ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_post_format_site_changed', __( 'Die Websitezuordnung hat sich während der Ocean-Extra-Beitragsformatänderung geändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( 'post' !== $target['post']->post_type ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_post_format_unsupported', __( 'Ocean-Extra-Beitragsformatvorgaben sind nur für reguläre Beiträge verfügbar.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$format = get_post_format( $target['post']->ID );
	if ( ! is_string( $format ) || ! in_array( $format, array( 'link', 'quote' ), true ) ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_post_format_unsupported', __( 'Der Beitrag verwendet kein unterstütztes OceanWP-Link- oder Quote-Format.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return array( 'post' => $target['post'], 'blog_id' => $target['blog_id'], 'format' => $format );
}

function wpagent_oceanwp_free_surface_post_format_plain_text_is_safe( $value, int $maximum ): bool {
	if ( ! is_string( $value ) || '' === $value || trim( $value ) !== $value || wp_check_invalid_utf8( $value, true ) !== $value || preg_match( '/[\[\]\x00-\x1F\x7F\x{202A}-\x{202E}\x{2066}-\x{2069}]/u', $value ) ) {
		return false;
	}
	if ( wp_strip_all_tags( $value ) !== $value || html_entity_decode( $value, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) !== $value || sanitize_text_field( $value ) !== $value ) {
		return false;
	}
	$length = function_exists( 'mb_strlen' ) ? mb_strlen( $value, 'UTF-8' ) : strlen( $value );
	return $length <= $maximum;
}

function wpagent_oceanwp_free_surface_post_format_url_is_safe( $value ): bool {
	if ( ! is_string( $value ) || '' === $value || strlen( $value ) > WPAGENT_OCEANWP_FREE_SURFACE_MAX_POST_FORMAT_BYTES || trim( $value ) !== $value || wp_check_invalid_utf8( $value, true ) !== $value || preg_match( '/[\x00-\x1F\x7F\x{202A}-\x{202E}\x{2066}-\x{2069}]/u', $value ) ) {
		return false;
	}
	$parts = wp_parse_url( $value );
	if ( ! is_array( $parts ) || isset( $parts['user'] ) || isset( $parts['pass'] ) || ! isset( $parts['scheme'], $parts['host'] ) || ! in_array( strtolower( (string) $parts['scheme'] ), array( 'http', 'https' ), true ) || esc_url_raw( $value, array( 'http', 'https' ) ) !== $value ) {
		return false;
	}
	if ( 'https' === strtolower( (string) $parts['scheme'] ) ) {
		return true;
	}
	$home = wp_parse_url( home_url( '/' ) );
	if ( ! is_array( $home ) || ! isset( $home['scheme'], $home['host'] ) || 'http' !== strtolower( (string) $home['scheme'] ) || strtolower( (string) $home['host'] ) !== strtolower( (string) $parts['host'] ) ) {
		return false;
	}
	$effective_port = static function ( array $url ): int {
		if ( isset( $url['port'] ) ) {
			return (int) $url['port'];
		}
		return 'https' === strtolower( (string) $url['scheme'] ) ? 443 : 80;
	};
	return $effective_port( $home ) === $effective_port( $parts );
}

/**
 * @param int    $post_id
 * @param string $meta_key
 * @return array{exists:bool,id:int,value:string}|WP_Error
 */
function wpagent_oceanwp_free_surface_post_format_meta_row( int $post_id, string $meta_key ) {
	global $wpdb;
	$rows = $wpdb->get_results(
		$wpdb->prepare(
			"SELECT meta_id, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = %s ORDER BY meta_id ASC",
			$post_id,
			$meta_key
		),
		ARRAY_A
	);
	if ( '' !== $wpdb->last_error ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_storage', __( 'Die Ocean-Extra-Beitragsformatmetadaten konnten nicht direkt gelesen werden.', 'wp-agent-companion' ), array( 'status' => 502 ) );
	}
	if ( ! is_array( $rows ) || count( $rows ) > 1 || ( 1 === count( $rows ) && ( ! isset( $rows[0]['meta_id'], $rows[0]['meta_value'] ) || ! is_scalar( $rows[0]['meta_value'] ) ) ) ) {
		return wpagent_oceanwp_free_surface_invalid_state();
	}
	if ( ! $rows ) {
		return array( 'exists' => false, 'id' => 0, 'value' => '' );
	}
	return array( 'exists' => true, 'id' => (int) $rows[0]['meta_id'], 'value' => (string) $rows[0]['meta_value'] );
}

/**
 * @param array{post:WP_Post,blog_id:int,format:string} $target
 * @return array{blog_id:int,post_id:int,post_type:string,format:string,meta:array<string,array{exists:bool,id:int,value:string}>}|WP_Error
 */
function wpagent_oceanwp_free_surface_post_format_snapshot( array $target ) {
	if ( $target['blog_id'] < 1 || $target['blog_id'] !== (int) get_current_blog_id() || ! current_user_can( 'edit_post', $target['post']->ID ) ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_post_format_changed', __( 'Der Ocean-Extra-Beitrag kann nicht mehr sicher gelesen werden.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$fresh = wpagent_oceanwp_free_surface_post_format_target( $target['post']->ID, $target['blog_id'] );
	if ( is_wp_error( $fresh ) || $fresh['post']->post_type !== $target['post']->post_type || $fresh['format'] !== $target['format'] ) {
		return is_wp_error( $fresh ) ? $fresh : new WP_Error( 'wpagent_oceanwp_free_surface_post_format_changed', __( 'Der Ocean-Extra-Beitrag hat sein Format geändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$meta = array();
	foreach ( wpagent_oceanwp_free_surface_post_format_catalog( $target['format'] ) as $field => $definition ) {
		$entry = wpagent_oceanwp_free_surface_post_format_meta_row( $target['post']->ID, $definition['meta'] );
		if ( is_wp_error( $entry ) ) {
			return $entry;
		}
		$value = $entry['value'];
		if ( '' !== $value ) {
			$valid = 'url' === $definition['kind']
				? wpagent_oceanwp_free_surface_post_format_url_is_safe( $value )
				: ( 'text' === $definition['kind'] ? wpagent_oceanwp_free_surface_post_format_plain_text_is_safe( $value, WPAGENT_OCEANWP_FREE_SURFACE_MAX_POST_FORMAT_BYTES ) : in_array( $value, $definition['values'], true ) );
			if ( ! $valid ) {
				return wpagent_oceanwp_free_surface_invalid_state();
			}
		}
		$meta[ $field ] = $entry;
	}
	return array(
		'blog_id'   => $target['blog_id'],
		'post_id'   => $target['post']->ID,
		'post_type' => $target['post']->post_type,
		'format'    => $target['format'],
		'meta'      => $meta,
	);
}

/** @param array<string,mixed> $snapshot */
function wpagent_oceanwp_free_surface_post_format_hash( array $snapshot ): string {
	return hash( 'sha256', $snapshot['blog_id'] . "\0" . WPAGENT_OCEANWP_FREE_SURFACE_THEME_VERSION . "\0" . WPAGENT_OCEAN_EXTRA_MIN_VERSION . "\0" . $snapshot['post_id'] . "\0" . $snapshot['post_type'] . "\0" . $snapshot['format'] . "\0" . maybe_serialize( $snapshot['meta'] ) );
}

/** @param array<string,mixed> $snapshot @return array<string,mixed> */
function wpagent_oceanwp_free_surface_post_format_normalize( array $snapshot ): array {
	$overrides = array();
	foreach ( wpagent_oceanwp_free_surface_post_format_catalog( $snapshot['format'] ) as $field => $definition ) {
		$entry = $snapshot['meta'][ $field ];
		$overrides[ $field ] = ! $entry['exists'] || '' === $entry['value']
			? array( 'mode' => 'inherit' )
			: array( 'mode' => 'set', 'value' => $entry['value'] );
	}
	return $overrides;
}

/** @param array<string,mixed> $snapshot @param array<string,mixed> $settings @return array<string,mixed> */
function wpagent_oceanwp_free_surface_post_format_expected_snapshot( array $snapshot, array $settings ): array {
	$expected = $snapshot;
	foreach ( $settings as $field => $override ) {
		$expected['meta'][ $field ] = 'inherit' === $override['mode']
			? array( 'exists' => false, 'id' => 0, 'value' => '' )
			: array( 'exists' => true, 'id' => (int) $snapshot['meta'][ $field ]['id'], 'value' => $override['value'] );
	}
	return $expected;
}

/** @return WP_Error */
function wpagent_oceanwp_free_surface_post_format_recovery_required( int $post_id, int $blog_id ) {
	$data     = array( 'status' => 500, 'rollback_verified' => false, 'recovery_required' => true );
	$target   = wpagent_oceanwp_free_surface_post_format_target( $post_id, $blog_id );
	$snapshot = is_array( $target ) ? wpagent_oceanwp_free_surface_post_format_snapshot( $target ) : null;
	if ( is_array( $snapshot ) ) {
		$data['current_hash']      = wpagent_oceanwp_free_surface_post_format_hash( $snapshot );
		$data['current_overrides'] = wpagent_oceanwp_free_surface_post_format_normalize( $snapshot );
		$data['format']            = $snapshot['format'];
	}
	return new WP_Error( 'wpagent_oceanwp_free_surface_post_format_recovery_required', __( 'Die Ocean-Extra-Beitragsformatänderung wurde nicht vollständig verifiziert. Wiederhole den Vorgang nicht automatisch und prüfe den aktuellen Zustand manuell.', 'wp-agent-companion' ), $data );
}

/** @return array{url:string,target:string,rendered:string,has_thumbnail:bool}|array{quote:string,link:string,rendered:string}|WP_Error */
function wpagent_oceanwp_free_surface_post_format_runtime_state( array $snapshot ) {
	$target = wpagent_oceanwp_free_surface_post_format_target( (int) $snapshot['post_id'], (int) $snapshot['blog_id'] );
	if ( is_wp_error( $target ) || $target['format'] !== $snapshot['format'] ) {
		return is_wp_error( $target ) ? $target : new WP_Error( 'wpagent_oceanwp_free_surface_post_format_changed', __( 'Das Ocean-Extra-Beitragsformat hat sich während der Prüfung geändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$template = 'link' === $snapshot['format']
		? get_template_directory() . '/partials/single/media/blog-single-link.php'
		: get_template_directory() . '/partials/entry/quote.php';
	if ( ! is_readable( $template ) ) {
		return new WP_Error( 'wpagent_oceanwp_free_surface_post_format_runtime_missing', __( 'Das geprüfte OceanWP-Beitragsformattemplate ist nicht verfügbar.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	global $post;
	$previous_post = $post;
	$post          = $target['post'];
	setup_postdata( $post );
	$buffer_level = ob_get_level();
	try {
		if ( ! ob_start() ) {
			throw new RuntimeException( 'OceanWP post-format rendering could not start an output buffer.' );
		}
		include $template;
		$rendered = ob_get_clean();
		if ( ! is_string( $rendered ) ) {
			throw new RuntimeException( 'OceanWP post-format rendering did not return output safely.' );
		}
		if ( 'link' === $snapshot['format'] ) {
			return array(
				'url'      => (string) ocean_link_post_url( $post->ID ),
				'target'   => (string) ocean_link_post_url_target( $post->ID ),
				'rendered' => $rendered,
				'has_thumbnail' => has_post_thumbnail( $post->ID ),
			);
		}
		return array(
			'quote'    => (string) get_post_meta( $post->ID, 'ocean_quote_format', true ),
			'link'     => (string) get_post_meta( $post->ID, 'ocean_quote_format_link', true ),
			'rendered' => $rendered,
		);
	} catch ( Throwable $error ) {
		while ( ob_get_level() > $buffer_level ) {
			ob_end_clean();
		}
		return new WP_Error( 'wpagent_oceanwp_free_surface_post_format_runtime_failed', __( 'OceanWP konnte die Beitragsformat-Laufzeit nicht sicher auswerten.', 'wp-agent-companion' ), array( 'status' => 502 ) );
	} finally {
		wp_reset_postdata();
		$post = $previous_post;
	}
}

/** @param array<string,mixed> $settings @param array<string,mixed> $runtime */
function wpagent_oceanwp_free_surface_post_format_runtime_matches( string $format, array $settings, array $runtime ): bool {
	if ( 'link' === $format ) {
		if ( isset( $settings['url'] ) && 'set' === $settings['url']['mode'] && ( $runtime['url'] ?? null ) !== $settings['url']['value'] ) {
			return false;
		}
		if ( isset( $settings['target'] ) && 'set' === $settings['target']['mode'] && ( $runtime['target'] ?? null ) !== ( 'blank' === $settings['target']['value'] ? '_blank' : '' ) ) {
			return false;
		}
		return ! isset( $settings['url'] )
			|| 'set' !== $settings['url']['mode']
			|| empty( $runtime['has_thumbnail'] )
			|| str_contains( (string) ( $runtime['rendered'] ?? '' ), esc_url( $settings['url']['value'] ) );
	}
	if ( isset( $settings['quote'] ) && 'set' === $settings['quote']['mode'] && ( ( $runtime['quote'] ?? null ) !== $settings['quote']['value'] || ! str_contains( (string) ( $runtime['rendered'] ?? '' ), $settings['quote']['value'] ) ) ) {
		return false;
	}
	if ( isset( $settings['link'] ) && 'set' === $settings['link']['mode'] ) {
		$has_link = str_contains( (string) ( $runtime['rendered'] ?? '' ), 'thumbnail-link' );
		return ( 'post' === $settings['link']['value'] ) === $has_link;
	}
	return true;
}
