<?php
/** Closed, bounded public schemas for MB Relationships definitions and connections. */

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

/** @return array<string,mixed> */
function wpagent_metabox_relationship_boolean_schema(): array {
	return array(
		'anyOf' => array(
			array( 'type' => 'boolean' ),
			array( 'type' => 'integer', 'enum' => array( 0, 1 ) ),
			array( 'type' => 'string', 'enum' => array( 'true', 'false', '0', '1' ) ),
		),
	);
}

/** @return array<string,mixed> */
function wpagent_metabox_relationship_scalar_schema(): array {
	return array(
		'anyOf' => array(
			array( 'type' => 'string', 'maxLength' => 500 ),
			array( 'type' => 'integer', 'minimum' => -2147483648, 'maximum' => 2147483647 ),
			array( 'type' => 'number', 'minimum' => -2147483648, 'maximum' => 2147483647 ),
			array( 'type' => 'boolean' ),
			array( 'type' => 'null' ),
		),
	);
}

/** @return array<string,mixed> */
function wpagent_metabox_relationship_admin_column_schema( bool $runtime = false ): array {
	$source = array(
		'type' => 'object',
		'properties' => array(
			'enable'   => wpagent_metabox_relationship_boolean_schema(),
			'position' => wpagent_metabox_relationship_scalar_schema(),
			'title'    => array( 'type' => 'string', 'maxLength' => 200 ),
			'link'     => array(
				'anyOf' => array(
					array( 'type' => 'string', 'enum' => array( 'view', 'edit', 'false' ) ),
					array( 'type' => 'boolean', 'enum' => array( false ) ),
				),
			),
		),
		'additionalProperties' => false,
	);
	if ( ! $runtime ) {
		return $source;
	}
	$runtime_object = $source;
	unset( $runtime_object['properties']['enable'] );
	return array(
		'anyOf' => array(
			array( 'type' => 'boolean', 'enum' => array( true ) ),
			wpagent_metabox_relationship_scalar_schema(),
			$runtime_object,
		),
	);
}

/** @return array<string,mixed> */
function wpagent_metabox_relationship_meta_box_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'title'    => array( 'type' => 'string', 'maxLength' => 200 ),
			'context'  => array( 'type' => 'string', 'enum' => array( 'normal', 'side' ) ),
			'priority' => array( 'type' => 'string', 'enum' => array( 'low', 'high' ) ),
			'style'    => array( 'type' => 'string', 'enum' => array( 'default', 'seamless' ) ),
			'closed'   => wpagent_metabox_relationship_boolean_schema(),
			'class'    => array( 'type' => 'string', 'maxLength' => 500 ),
		),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_metabox_relationship_field_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'name'              => array( 'type' => 'string', 'maxLength' => 200 ),
			'label_description' => array( 'type' => 'string', 'maxLength' => 500 ),
			'desc'              => array( 'type' => 'string', 'maxLength' => 500 ),
			'placeholder'       => array( 'type' => 'string', 'maxLength' => 200 ),
			'add_new'           => wpagent_metabox_relationship_boolean_schema(),
			'query_args'        => array( 'type' => 'object', 'maxProperties' => 100, 'additionalProperties' => wpagent_metabox_relationship_scalar_schema() ),
			'max_clone'         => array(
				'anyOf' => array(
					array( 'type' => 'integer', 'minimum' => 0, 'maximum' => 1000 ),
					array( 'type' => 'string', 'pattern' => '^(?:0|[1-9][0-9]{0,3})$', 'maxLength' => 4 ),
				),
			),
			'add_button'        => array( 'type' => 'string', 'maxLength' => 200 ),
			'before'            => array( 'type' => 'string', 'maxLength' => 10000 ),
			'after'             => array( 'type' => 'string', 'maxLength' => 10000 ),
			'class'             => array( 'type' => 'string', 'maxLength' => 500 ),
		),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_metabox_relationship_side_schema( bool $runtime = false ): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'object_type'          => array( 'type' => 'string', 'enum' => array( 'post', 'term', 'user' ) ),
			'post_type'            => array( 'type' => 'string', 'pattern' => '^[a-z0-9_-]{1,20}$', 'maxLength' => 20 ),
			'taxonomy'             => array( 'type' => 'string', 'pattern' => '^[a-z0-9_-]{1,32}$', 'maxLength' => 32 ),
			'has_one_relationship' => wpagent_metabox_relationship_boolean_schema(),
			'empty_message'        => array( 'type' => 'string', 'maxLength' => 500 ),
			'admin_filter'         => wpagent_metabox_relationship_boolean_schema(),
			'admin_column'         => wpagent_metabox_relationship_admin_column_schema( $runtime ),
			'meta_box'             => wpagent_metabox_relationship_meta_box_schema(),
			'field'                => wpagent_metabox_relationship_field_schema(),
		),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_metabox_relationship_settings_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'id'          => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_-]{0,43}$', 'maxLength' => 44 ),
			'from'        => wpagent_metabox_relationship_side_schema(),
			'to'          => wpagent_metabox_relationship_side_schema(),
			'reciprocal'  => wpagent_metabox_relationship_boolean_schema(),
			'delete_data' => wpagent_metabox_relationship_boolean_schema(),
		),
		'required' => array( 'id', 'from', 'to' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_metabox_relationship_runtime_schema(): array {
	$side = array(
		'oneOf' => array(
			array( 'type' => 'string', 'pattern' => '^[a-z0-9_-]{1,20}$', 'maxLength' => 20 ),
			wpagent_metabox_relationship_side_schema( true ),
		),
	);
	return array(
		'type' => 'object',
		'properties' => array(
			'id'          => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_-]{0,43}$', 'maxLength' => 44 ),
			'from'        => $side,
			'to'          => $side,
			'reciprocal'  => wpagent_metabox_relationship_boolean_schema(),
			'delete_data' => wpagent_metabox_relationship_boolean_schema(),
		),
		'required' => array( 'id', 'from', 'to' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_metabox_relationship_state_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'id' => array( 'type' => 'integer', 'minimum' => 1 ),
			'title' => array( 'type' => 'string', 'maxLength' => 200 ),
			'slug' => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_-]{0,43}(?:__trashed(?:-[1-9][0-9]{0,3})?)?$', 'maxLength' => 58 ),
			'status' => array( 'type' => 'string', 'enum' => array( 'publish', 'draft', 'trash' ) ),
			'settings' => wpagent_metabox_relationship_settings_schema(),
			'relationship' => wpagent_metabox_relationship_runtime_schema(),
			'hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
		),
		'required' => array( 'id', 'title', 'slug', 'status', 'settings', 'relationship', 'hash' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_metabox_connection_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'relationship_id' => array( 'type' => 'string', 'pattern' => '^[a-z][a-z0-9_-]{0,43}$', 'maxLength' => 44 ),
			'from' => array( 'type' => 'integer', 'minimum' => 1 ),
			'to' => array( 'type' => 'integer', 'minimum' => 1 ),
			'order_from' => array( 'type' => 'integer', 'minimum' => 0 ),
			'order_to' => array( 'type' => 'integer', 'minimum' => 0 ),
			'exists' => array( 'type' => 'boolean' ),
			'hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
		),
		'required' => array( 'relationship_id', 'from', 'to', 'order_from', 'order_to', 'exists', 'hash' ),
		'additionalProperties' => false,
	);
}
