<?php
/** Read-only abilities for the bounded OceanWP free surface. */

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

/** @return array<string,mixed> */
function wpagent_oceanwp_free_surface_columns_schema( int $maximum ): array {
	$column = array( 'type' => 'integer', 'minimum' => 1, 'maximum' => $maximum );
	return array(
		'type'                 => 'object',
		'properties'           => array( 'desktop' => $column, 'tablet' => $column, 'mobile' => $column ),
		'required'             => array( 'desktop', 'tablet', 'mobile' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_oceanwp_free_surface_footer_schema(): array {
	return array(
		'type'                 => 'object',
		'properties'           => array(
			'widgets_enabled'    => array( 'type' => 'boolean' ),
			'widgets_visibility' => array( 'type' => 'string', 'enum' => array( 'all-devices', 'hide-tablet', 'hide-mobile', 'hide-tablet-mobile' ) ),
			'widgets_columns'    => wpagent_oceanwp_free_surface_columns_schema( 4 ),
			'bottom_enabled'     => array( 'type' => 'boolean' ),
			'bottom_visibility'  => array( 'type' => 'string', 'enum' => array( 'all-devices', 'hide-tablet', 'hide-mobile', 'hide-tablet-mobile' ) ),
			'copyright_text'     => array( 'type' => 'string', 'maxLength' => WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOK_BYTES ),
		),
		'required'             => array( 'widgets_enabled', 'widgets_visibility', 'widgets_columns', 'bottom_enabled', 'bottom_visibility', 'copyright_text' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_oceanwp_free_surface_blog_schema(): array {
	$layouts = array( 'right-sidebar', 'left-sidebar', 'full-width', 'full-screen', 'both-sidebars' );
	return array(
		'type'                 => 'object',
		'properties'           => array(
			'archive_layout'       => array( 'type' => 'string', 'enum' => $layouts ),
			'archive_style'        => array( 'type' => 'string', 'enum' => array( 'large-entry', 'grid-entry', 'thumbnail-entry' ) ),
			'grid_columns'         => wpagent_oceanwp_free_surface_columns_schema( 6 ),
			'excerpt_length'       => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 500 ),
			'pagination_style'     => array( 'type' => 'string', 'enum' => array( 'standard', 'infinite_scroll', 'load_more', 'next_prev' ) ),
			'single_layout'        => array( 'type' => 'string', 'enum' => $layouts ),
			'single_content_width' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => 2000 ),
		),
		'required'             => array( 'archive_layout', 'archive_style', 'grid_columns', 'excerpt_length', 'pagination_style', 'single_layout', 'single_content_width' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_oceanwp_free_surface_woocommerce_schema(): array {
	$layouts = array( 'right-sidebar', 'left-sidebar', 'full-width', 'full-screen', 'both-sidebars' );
	return array(
		'type'                 => 'object',
		'properties'           => array(
			'shop_layout'          => array( 'type' => 'string', 'enum' => $layouts ),
			'product_style'        => array( 'type' => 'string', 'enum' => array( 'default', 'hover' ) ),
			'grid_list_enabled'    => array( 'type' => 'boolean' ),
			'result_count_enabled' => array( 'type' => 'boolean' ),
			'pagination_style'     => array( 'type' => 'string', 'enum' => array( 'standard', 'infinite_scroll', 'load_more' ) ),
			'product_layout'       => array( 'type' => 'string', 'enum' => $layouts ),
		),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_oceanwp_free_surface_breadcrumbs_schema(): array {
	return array(
		'type'                 => 'object',
		'properties'           => array(
			'enabled'  => array( 'type' => 'boolean' ),
			'source'   => array( 'type' => 'string', 'enum' => array( 'default' ) ),
			'position' => array( 'type' => 'string', 'enum' => array( 'absolute-right', 'under-title' ) ),
		),
		'required'             => array( 'enabled', 'source', 'position' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_oceanwp_free_surface_customizer_ability( string $label, string $description, array $settings_schema, string $callback ): array {
	return array(
		'label'               => $label,
		'description'         => $description,
		'category'            => 'wp-agent',
		'input_schema'        => array( 'type' => 'object', 'properties' => array(), 'additionalProperties' => false, 'default' => array() ),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'version'    => array( 'type' => 'string', 'enum' => array( WPAGENT_OCEANWP_FREE_SURFACE_THEME_VERSION ) ),
				'settings'   => $settings_schema,
				'state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'version', 'settings', 'state_hash' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => $callback,
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

function wpagent_ability_get_oceanwp_footer_customizer(): array {
	return wpagent_oceanwp_free_surface_customizer_ability(
		__( 'OceanWP-Footer lesen', 'wp-agent-companion' ),
		__( 'Liest begrenzte freie Footer-Widgets- und Copyright-Einstellungen von OceanWP 4.2.2.', 'wp-agent-companion' ),
		wpagent_oceanwp_free_surface_footer_schema(),
		'wpagent_exec_get_oceanwp_footer_customizer'
	);
}

function wpagent_ability_get_oceanwp_blog_customizer(): array {
	return wpagent_oceanwp_free_surface_customizer_ability(
		__( 'OceanWP-Blog lesen', 'wp-agent-companion' ),
		__( 'Liest begrenzte freie Blog-Archiv- und Einzelbeitragseinstellungen von OceanWP 4.2.2.', 'wp-agent-companion' ),
		wpagent_oceanwp_free_surface_blog_schema(),
		'wpagent_exec_get_oceanwp_blog_customizer'
	);
}

function wpagent_ability_get_oceanwp_woocommerce_customizer(): array {
	return array(
		'label'               => __( 'OceanWP-WooCommerce lesen', 'wp-agent-companion' ),
		'description'         => __( 'Liest begrenzte freie Shop- und Produktansichtseinstellungen von OceanWP 4.2.2.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array( 'type' => 'object', 'properties' => array(), 'additionalProperties' => false, 'default' => array() ),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'version'    => array( 'type' => 'string', 'enum' => array( WPAGENT_OCEANWP_FREE_SURFACE_THEME_VERSION ) ),
				'available'  => array( 'type' => 'boolean' ),
				'settings'   => wpagent_oceanwp_free_surface_woocommerce_schema(),
				'state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'version', 'available', 'settings', 'state_hash' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_get_oceanwp_woocommerce_customizer',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

function wpagent_ability_get_oceanwp_breadcrumbs_customizer(): array {
	return wpagent_oceanwp_free_surface_customizer_ability(
		__( 'OceanWP-Breadcrumbs lesen', 'wp-agent-companion' ),
		__( 'Liest die native, eng begrenzte OceanWP-4.2.2-Breadcrumb-Sichtbarkeit, Standardquelle und Position.', 'wp-agent-companion' ),
		wpagent_oceanwp_free_surface_breadcrumbs_schema(),
		'wpagent_exec_get_oceanwp_breadcrumbs_customizer'
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_oceanwp_free_surface_customizer_result( string $scope, callable $reader ) {
	$snapshot = wpagent_oceanwp_free_surface_theme_snapshot();
	if ( is_wp_error( $snapshot ) ) {
		return $snapshot;
	}
	$settings = $reader( $snapshot['mods'] );
	if ( is_wp_error( $settings ) ) {
		return $settings;
	}
	return array(
		'version'    => $snapshot['version'],
		'settings'   => $settings,
		'state_hash' => wpagent_oceanwp_free_surface_hash( $scope, $snapshot['blog_id'], $settings ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_oceanwp_footer_customizer() {
	return wpagent_oceanwp_free_surface_customizer_result( 'footer', 'wpagent_oceanwp_free_surface_footer' );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_oceanwp_blog_customizer() {
	return wpagent_oceanwp_free_surface_customizer_result( 'blog', 'wpagent_oceanwp_free_surface_blog' );
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_oceanwp_woocommerce_customizer() {
	$snapshot = wpagent_oceanwp_free_surface_theme_snapshot();
	if ( is_wp_error( $snapshot ) ) {
		return $snapshot;
	}
	$state = wpagent_oceanwp_free_surface_woocommerce( $snapshot['mods'] );
	if ( is_wp_error( $state ) ) {
		return $state;
	}
	return array(
		'version'    => $snapshot['version'],
		'available'  => $state['available'],
		'settings'   => $state['settings'],
		'state_hash' => wpagent_oceanwp_free_surface_hash( 'woocommerce', $snapshot['blog_id'], $state ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_oceanwp_breadcrumbs_customizer() {
	$ready = wpagent_oceanwp_free_surface_require_breadcrumbs();
	if ( is_wp_error( $ready ) ) {
		return $ready;
	}
	return wpagent_oceanwp_free_surface_customizer_result( 'breadcrumbs', 'wpagent_oceanwp_free_surface_breadcrumbs' );
}

function wpagent_ability_list_oceanwp_free_hooks(): array {
	$hook_schema = array(
		'type'                 => 'object',
		'properties'           => array(
			'id'     => array( 'type' => 'string', 'pattern' => '^[a-z_]+$' ),
			'action' => array( 'type' => 'string', 'pattern' => '^ocean_[a-z_]+$' ),
			'area'   => array( 'type' => 'string', 'enum' => array( 'top_bar', 'header', 'page_header', 'footer_widgets', 'footer_bottom' ) ),
		),
		'required'             => array( 'id', 'action', 'area' ),
		'additionalProperties' => false,
	);
	return array(
		'label'               => __( 'OceanWP-Free-Hooks auflisten', 'wp-agent-companion' ),
		'description'         => __( 'Listet die zehn überprüften positionsgebundenen Ocean-Extra-Shortcode-Hooks, ohne sie auszuführen oder ihren Inhalt preiszugeben.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'page'     => array( 'type' => 'integer', 'minimum' => 1 ),
				'per_page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOKS ),
			),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'hooks'        => array( 'type' => 'array', 'items' => $hook_schema, 'maxItems' => WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOKS ),
				'total'        => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOKS ),
				'page'         => array( 'type' => 'integer', 'minimum' => 1 ),
				'per_page'     => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOKS ),
				'catalog_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'hooks', 'total', 'page', 'per_page', 'catalog_hash' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_list_oceanwp_free_hooks',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_list_oceanwp_free_hooks( $input ) {
	$ready = wpagent_oceanwp_free_surface_require_extra();
	if ( is_wp_error( $ready ) ) {
		return $ready;
	}
	$input    = is_array( $input ) ? $input : array();
	$page     = max( 1, absint( $input['page'] ?? 1 ) );
	$per_page = min( WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOKS, max( 1, absint( $input['per_page'] ?? WPAGENT_OCEANWP_FREE_SURFACE_MAX_HOOKS ) ) );
	$catalog  = wpagent_oceanwp_free_surface_hooks();
	$offset   = ( $page - 1 ) * $per_page;
	$hooks    = array_map(
		static fn( array $hook ): array => array( 'id' => $hook['id'], 'action' => $hook['action'], 'area' => $hook['area'] ),
		array_slice( $catalog, $offset, $per_page )
	);
	return array(
		'hooks'        => $hooks,
		'total'        => count( $catalog ),
		'page'         => $page,
		'per_page'     => $per_page,
		'catalog_hash' => wpagent_oceanwp_free_surface_hash( 'hooks', (int) get_current_blog_id(), $catalog ),
	);
}

/** @return array<string,mixed> */
function wpagent_oceanwp_free_surface_post_state_schema(): array {
	$hook_properties = array();
	foreach ( wpagent_oceanwp_free_surface_hooks() as $hook ) {
		$hook_properties[ $hook['id'] ] = array( 'type' => 'boolean' );
	}
	return array(
		'type'                 => 'object',
		'properties'           => array(
			'post_id' => array( 'type' => 'integer', 'minimum' => 1 ),
			'post_type' => array( 'type' => 'string' ),
			'layout' => array(
				'type'                 => 'object',
				'properties'           => array(
					'second_sidebar' => array(
						'type'                 => 'object',
						'properties'           => array( 'mode' => array( 'type' => 'string', 'enum' => array( 'inherit', 'set' ) ), 'sidebar_id' => array( 'type' => 'string', 'pattern' => '^[a-z0-9_-]+$' ) ),
						'required'             => array( 'mode' ),
						'additionalProperties' => false,
					),
					'sidebars_width' => array(
						'type'                 => 'object',
						'properties'           => array( 'mode' => array( 'type' => 'string', 'enum' => array( 'inherit', 'set' ) ), 'value' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 100 ) ),
						'required'             => array( 'mode' ),
						'additionalProperties' => false,
					),
				),
				'required'             => array( 'second_sidebar', 'sidebars_width' ),
				'additionalProperties' => false,
			),
			'visibility' => array(
				'type'                 => 'object',
				'properties'           => array( 'margins' => array( 'type' => 'string', 'enum' => array( 'inherit', 'normal', 'removed' ) ), 'top_bar' => array( 'type' => 'string', 'enum' => array( 'inherit', 'show', 'hide' ) ) ),
				'required'             => array( 'margins', 'top_bar' ),
				'additionalProperties' => false,
			),
			'configured_hooks' => array( 'type' => 'object', 'properties' => $hook_properties, 'required' => array_keys( $hook_properties ), 'additionalProperties' => false ),
			'state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
		),
		'required'             => array( 'post_id', 'post_type', 'layout', 'visibility', 'configured_hooks', 'state_hash' ),
		'additionalProperties' => false,
	);
}

function wpagent_ability_get_oceanwp_post_free_overrides(): array {
	return array(
		'label'               => __( 'OceanWP-Free-Beitragsvorgaben lesen', 'wp-agent-companion' ),
		'description'         => __( 'Liest weitere sichere Ocean-Extra-Layout-, Sichtbarkeits- und Hook-Belegungen eines einzelnen Beitrags, ohne Shortcodes auszuführen oder ihren Inhalt auszugeben.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array( 'type' => 'object', 'properties' => array( 'post_id' => array( 'type' => 'integer', 'minimum' => 1 ) ), 'required' => array( 'post_id' ), 'additionalProperties' => false ),
		'output_schema'       => wpagent_oceanwp_free_surface_post_state_schema(),
		'execute_callback'    => 'wpagent_exec_get_oceanwp_post_free_overrides',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_oceanwp_post_free_overrides( $input ) {
	$target = wpagent_oceanwp_free_surface_post_target( absint( is_array( $input ) ? ( $input['post_id'] ?? 0 ) : 0 ) );
	if ( is_wp_error( $target ) ) {
		return $target;
	}
	$snapshot = wpagent_oceanwp_free_surface_post_snapshot( $target['post'], $target['blog_id'] );
	if ( is_wp_error( $snapshot ) ) {
		return $snapshot;
	}
	$state = wpagent_oceanwp_free_surface_post_normalize( $snapshot );
	return array(
		'post_id'          => (int) $snapshot['post_id'],
		'post_type'        => $snapshot['post_type'],
		'layout'           => $state['layout'],
		'visibility'       => $state['visibility'],
		'configured_hooks' => $state['configured_hooks'],
		'state_hash'       => wpagent_oceanwp_free_surface_post_hash( $snapshot ),
	);
}

/** @return array<string,mixed> */
function wpagent_oceanwp_free_surface_post_format_text_override_schema(): array {
	return array(
		'type'                 => 'object',
		'properties'           => array(
			'mode'  => array( 'type' => 'string', 'enum' => array( 'inherit', 'set' ) ),
			'value' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => WPAGENT_OCEANWP_FREE_SURFACE_MAX_POST_FORMAT_BYTES ),
		),
		'required'             => array( 'mode' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_oceanwp_free_surface_post_format_enum_override_schema( array $values ): array {
	return array(
		'type'                 => 'object',
		'properties'           => array(
			'mode'  => array( 'type' => 'string', 'enum' => array( 'inherit', 'set' ) ),
			'value' => array( 'type' => 'string', 'enum' => $values ),
		),
		'required'             => array( 'mode' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_oceanwp_free_surface_post_format_state_schema( bool $complete = false ): array {
	$properties = array(
		'url'    => wpagent_oceanwp_free_surface_post_format_text_override_schema(),
		'target' => wpagent_oceanwp_free_surface_post_format_enum_override_schema( array( 'self', 'blank' ) ),
		'quote'  => wpagent_oceanwp_free_surface_post_format_text_override_schema(),
		'link'   => wpagent_oceanwp_free_surface_post_format_enum_override_schema( array( 'post', 'none' ) ),
	);
	return array(
		'type'                 => 'object',
		'properties'           => $properties,
		'minProperties'        => $complete ? 2 : 1,
		'maxProperties'        => 2,
		'additionalProperties' => false,
	);
}

function wpagent_ability_get_oceanwp_post_format_overrides(): array {
	return array(
		'label'               => __( 'Ocean-Extra-Beitragsformat lesen', 'wp-agent-companion' ),
		'description'         => __( 'Liest die eng begrenzten Link- oder Quote-Formatvorgaben eines einzelnen Ocean-Extra-Beitrags ohne HTML oder Shortcodes.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array( 'type' => 'object', 'properties' => array( 'post_id' => array( 'type' => 'integer', 'minimum' => 1 ) ), 'required' => array( 'post_id' ), 'additionalProperties' => false ),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'post_id'    => array( 'type' => 'integer', 'minimum' => 1 ),
				'post_type'  => array( 'type' => 'string', 'enum' => array( 'post' ) ),
				'format'     => array( 'type' => 'string', 'enum' => array( 'link', 'quote' ) ),
				'overrides'  => wpagent_oceanwp_free_surface_post_format_state_schema( true ),
				'state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'post_id', 'post_type', 'format', 'overrides', 'state_hash' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_get_oceanwp_post_format_overrides',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_oceanwp_post_format_overrides( $input ) {
	$target = wpagent_oceanwp_free_surface_post_format_target( absint( is_array( $input ) ? ( $input['post_id'] ?? 0 ) : 0 ) );
	if ( is_wp_error( $target ) ) {
		return $target;
	}
	$snapshot = wpagent_oceanwp_free_surface_post_format_snapshot( $target );
	if ( is_wp_error( $snapshot ) ) {
		return $snapshot;
	}
	return array(
		'post_id'    => (int) $snapshot['post_id'],
		'post_type'  => $snapshot['post_type'],
		'format'     => $snapshot['format'],
		'overrides'  => wpagent_oceanwp_free_surface_post_format_normalize( $snapshot ),
		'state_hash' => wpagent_oceanwp_free_surface_post_format_hash( $snapshot ),
	);
}
