<?php
/** Bounded, definition-only readers for Pods 3.3.9 Settings and extensions. */

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

const WPAGENT_PODS_FREE_MAX_PER_PAGE       = 50;
const WPAGENT_PODS_FREE_MAX_ITEMS          = 200;
const WPAGENT_PODS_FREE_MAX_FIELDS         = 50;
const WPAGENT_PODS_FREE_MAX_TOTAL_FIELDS   = 200;
const WPAGENT_PODS_FREE_MAX_TEXT_BYTES     = 2048;
const WPAGENT_PODS_FREE_MAX_SEARCH_BYTES   = 100;

/** @return true|WP_Error */
function wpagent_pods_free_require_api() {
	$available = wpagent_pods_require_api();
	if ( is_wp_error( $available ) ) {
		return $available;
	}
	if ( ! defined( 'PODS_VERSION' ) || version_compare( PODS_VERSION, '3.3.9', '<' ) || version_compare( PODS_VERSION, '4.0.0', '>=' ) ) {
		return new WP_Error( 'wpagent_pods_free_provider_version', __( 'Für diese begrenzte Pods-Definitionsansicht wird Pods 3.3.9 oder neuer innerhalb der Hauptversion 3 benötigt.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$api = pods_api();
	foreach ( array( 'load_pods', 'load_pod', 'load_groups', 'load_group' ) as $method ) {
		if ( ! is_object( $api ) || ! is_callable( array( $api, $method ) ) ) {
			return new WP_Error( 'wpagent_pods_free_api_missing', __( 'Die benötigte native Pods-Lese-API ist nicht verfügbar.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
	}
	return true;
}

/** @return string|WP_Error */
function wpagent_pods_free_name( $value, string $label = 'name' ) {
	$name = wpagent_pods_name( $value );
	if ( is_wp_error( $name ) ) {
		return new WP_Error( 'wpagent_pods_free_name', sprintf( __( '%s muss ein gültiger Pods-Bezeichner sein.', 'wp-agent-companion' ), $label ), array( 'status' => 400 ) );
	}
	return $name;
}

/** @return string|WP_Error */
function wpagent_pods_free_search( $value ) {
	$search = is_string( $value ) ? trim( $value ) : '';
	if ( strlen( $search ) > WPAGENT_PODS_FREE_MAX_SEARCH_BYTES || sanitize_text_field( $search ) !== $search ) {
		return new WP_Error( 'wpagent_pods_free_search', __( 'search muss reiner Text mit höchstens 100 Byte sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	return $search;
}

/** @return int|WP_Error */
function wpagent_pods_free_positive_integer( $value, string $label, int $default, int $maximum ) {
	if ( null === $value ) {
		return $default;
	}
	if ( ( ! is_int( $value ) && ! ( is_string( $value ) && ctype_digit( $value ) ) ) || 1 > (int) $value || $maximum < (int) $value ) {
		/* translators: 1: input field name, 2: maximum value. */
		return new WP_Error( 'wpagent_pods_free_limit', sprintf( __( '%1$s muss eine positive Ganzzahl bis %2$d sein.', 'wp-agent-companion' ), $label, $maximum ), array( 'status' => 400 ) );
	}
	return (int) $value;
}

/** @return array{page:int,per_page:int}|WP_Error */
function wpagent_pods_free_page_input( array $input ) {
	$page = wpagent_pods_free_positive_integer( $input['page'] ?? null, 'page', 1, WPAGENT_PODS_FREE_MAX_ITEMS );
	$per_page = wpagent_pods_free_positive_integer( $input['per_page'] ?? null, 'per_page', 20, WPAGENT_PODS_FREE_MAX_PER_PAGE );
	if ( is_wp_error( $page ) || is_wp_error( $per_page ) ) {
		return is_wp_error( $page ) ? $page : $per_page;
	}
	return array( 'page' => $page, 'per_page' => $per_page );
}

/** @return int|WP_Error */
function wpagent_pods_free_max_fields( array $input ) {
	return wpagent_pods_free_positive_integer( $input['max_fields'] ?? null, 'max_fields', 20, WPAGENT_PODS_FREE_MAX_FIELDS );
}

/** @return array{text:string,truncated:bool} */
function wpagent_pods_free_preview( $value, int $maximum = WPAGENT_PODS_FREE_MAX_TEXT_BYTES ): array {
	$text = is_scalar( $value ) ? (string) $value : '';
	if ( strlen( $text ) <= $maximum ) {
		return array( 'text' => $text, 'truncated' => false );
	}
	if ( function_exists( 'mb_strcut' ) ) {
		return array( 'text' => mb_strcut( $text, 0, $maximum, 'UTF-8' ), 'truncated' => true );
	}
	$preview = substr( $text, 0, $maximum );
	while ( '' !== $preview && 1 !== preg_match( '//u', $preview ) ) {
		$preview = substr( $preview, 0, -1 );
	}
	return array( 'text' => $preview, 'truncated' => true );
}

/** @return array<int,object>|WP_Error */
function wpagent_pods_free_load_pods() {
	try {
		$pods = pods_api()->load_pods( array( 'bypass_cache' => true ) );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_pods_free_pods_read_failed', __( 'Die Pods-Definitionen konnten nicht gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	if ( ! is_array( $pods ) || count( $pods ) > WPAGENT_PODS_FREE_MAX_ITEMS ) {
		return new WP_Error( 'wpagent_pods_free_pods_limit', __( 'Die Anzahl der Pods-Definitionen überschreitet die sichere Lesegrenze.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	foreach ( $pods as $pod ) {
		if ( ! is_object( $pod ) || ! is_callable( array( $pod, 'get_args' ) ) || ! is_callable( array( $pod, 'get_id' ) ) ) {
			return new WP_Error( 'wpagent_pods_free_pods_incomplete', __( 'Pods lieferte eine unvollständige Definitionsliste.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
	}
	return array_values( $pods );
}

/** @return object|WP_Error */
function wpagent_pods_free_get_pod( string $name ) {
	try {
		$pod = pods_api()->load_pod( array( 'name' => $name, 'bypass_cache' => true ) );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_pods_free_pod_read_failed', __( 'Die Pods-Definition konnte nicht gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	if ( ! is_object( $pod ) || ! is_callable( array( $pod, 'get_args' ) ) || ! is_callable( array( $pod, 'get_id' ) ) ) {
		return new WP_Error( 'wpagent_pods_free_pod_not_found', __( 'Pods-Definition nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	return $pod;
}

/** @return object|WP_Error */
function wpagent_pods_free_get_pod_by_id( int $id ) {
	if ( $id < 1 ) {
		return new WP_Error( 'wpagent_pods_free_pod_not_found', __( 'Pods-Definition nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	try {
		$pod = pods_api()->load_pod( array( 'id' => $id, 'bypass_cache' => true ) );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_pods_free_pod_read_failed', __( 'Die Pods-Definition konnte nicht gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	if ( ! is_object( $pod ) || ! is_callable( array( $pod, 'get_args' ) ) || ! is_callable( array( $pod, 'get_id' ) ) ) {
		return new WP_Error( 'wpagent_pods_free_pod_not_found', __( 'Pods-Definition nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	return $pod;
}

function wpagent_pods_free_is_settings( object $pod ): bool {
	$args = $pod->get_args();
	return 'settings' === (string) ( $args['type'] ?? '' ) && 'option' === (string) ( $args['storage'] ?? '' );
}

function wpagent_pods_free_is_object_extension( object $pod ): bool {
	$args = $pod->get_args();
	$type = (string) ( $args['type'] ?? '' );
	return in_array( $type, array( 'post_type', 'taxonomy', 'user', 'comment', 'media' ), true )
		&& method_exists( $pod, 'is_extended' )
		&& $pod->is_extended();
}

/** @return array<int,object>|WP_Error */
function wpagent_pods_free_fields( object $pod, ?object $group = null ) {
	$params = array( 'pod_id' => (int) $pod->get_id(), 'bypass_cache' => true );
	if ( null !== $group ) {
		$params['group_id'] = (int) $group->get_id();
	}
	try {
		$fields = pods_api()->load_fields( $params );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_pods_free_fields_read_failed', __( 'Die Pods-Felddefinitionen konnten nicht gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	if ( ! is_array( $fields ) || count( $fields ) > WPAGENT_PODS_FREE_MAX_TOTAL_FIELDS ) {
		return new WP_Error( 'wpagent_pods_free_fields_limit', __( 'Die Anzahl der Pods-Felddefinitionen überschreitet die sichere Lesegrenze.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	foreach ( $fields as $field ) {
		if ( ! is_object( $field ) || ! is_callable( array( $field, 'get_args' ) ) || ! is_callable( array( $field, 'get_id' ) ) ) {
			return new WP_Error( 'wpagent_pods_free_fields_incomplete', __( 'Pods lieferte unvollständige Felddefinitionen.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
	}
	usort(
		$fields,
		static function ( object $left, object $right ): int {
			$left_args = $left->get_args();
			$right_args = $right->get_args();
			$weight = (int) ( $left_args['weight'] ?? 0 ) <=> (int) ( $right_args['weight'] ?? 0 );
			return 0 !== $weight ? $weight : strcasecmp( (string) ( $left_args['name'] ?? '' ), (string) ( $right_args['name'] ?? '' ) );
		}
	);
	return array_values( $fields );
}

/** @return array<string,mixed> */
function wpagent_pods_free_field_state( object $field ): array {
	$args = $field->get_args();
	$label = wpagent_pods_free_preview( $args['label'] ?? '' );
	$description = wpagent_pods_free_preview( $args['description'] ?? '' );
	$type = (string) ( $args['type'] ?? '' );
	$repeatable = ! empty( $args['repeatable'] );
	return array(
		'id'                            => (int) $field->get_id(),
		'name'                          => (string) ( $args['name'] ?? '' ),
		'label'                         => $label['text'],
		'label_truncated'               => $label['truncated'],
		'description'                   => $description['text'],
		'description_truncated'         => $description['truncated'],
		'type'                          => $type,
		'required'                      => ! empty( $args['required'] ),
		'repeatable'                    => $repeatable,
		'weight'                        => (int) ( $args['weight'] ?? 0 ),
		'has_unsupported_value_surface' => $repeatable || in_array( $type, array( 'pick', 'file', 'avatar' ), true ),
		'hash'                          => wpagent_pods_hash( $args ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_pods_free_pod_state( object $pod, int $max_fields ) {
	$fields = wpagent_pods_free_fields( $pod );
	if ( is_wp_error( $fields ) ) {
		return $fields;
	}
	$args = $pod->get_args();
	$label = wpagent_pods_free_preview( $args['label'] ?? '' );
	$description = wpagent_pods_free_preview( $args['description'] ?? '' );
	$field_material = array();
	foreach ( $fields as $field ) {
		$field_args = $field->get_args();
		$field_material[ (string) $field->get_id() ] = $field_args;
	}
	ksort( $field_material, SORT_STRING );
	return array(
		'id'                => (int) $pod->get_id(),
		'name'              => (string) ( $args['name'] ?? '' ),
		'kind'              => (string) ( $args['type'] ?? '' ),
		'object'            => (string) ( $args['object'] ?? '' ),
		'extended'          => wpagent_pods_free_is_object_extension( $pod ),
		'storage'           => (string) ( $args['storage'] ?? '' ),
		'label'             => $label['text'],
		'label_truncated'   => $label['truncated'],
		'description'       => $description['text'],
		'description_truncated' => $description['truncated'],
		'field_count'       => count( $fields ),
		'fields'            => array_map( 'wpagent_pods_free_field_state', array_slice( $fields, 0, $max_fields ) ),
		'fields_truncated'  => count( $fields ) > $max_fields,
		'values_exposed'    => false,
		'hash'              => wpagent_pods_hash( array( 'pod' => $args, 'fields' => $field_material ) ),
	);
}

/** @return array<int,object>|WP_Error */
function wpagent_pods_free_load_groups( ?object $pod = null ) {
	$params = array( 'bypass_cache' => true );
	if ( null !== $pod ) {
		$params['pod_id'] = (int) $pod->get_id();
	}
	try {
		$groups = pods_api()->load_groups( $params );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_pods_free_groups_read_failed', __( 'Die Pods-Feldgruppen konnten nicht gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	if ( ! is_array( $groups ) || count( $groups ) > WPAGENT_PODS_FREE_MAX_ITEMS ) {
		return new WP_Error( 'wpagent_pods_free_groups_limit', __( 'Die Anzahl der Pods-Feldgruppen überschreitet die sichere Lesegrenze.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	foreach ( $groups as $group ) {
		if ( ! is_object( $group ) || ! is_callable( array( $group, 'get_args' ) ) || ! is_callable( array( $group, 'get_id' ) ) ) {
			return new WP_Error( 'wpagent_pods_free_groups_incomplete', __( 'Pods lieferte unvollständige Feldgruppen.', 'wp-agent-companion' ), array( 'status' => 500 ) );
		}
	}
	return array_values( $groups );
}

/** @return object|WP_Error */
function wpagent_pods_free_get_group( object $pod, string $name ) {
	try {
		$group = pods_api()->load_group( array( 'pod_id' => (int) $pod->get_id(), 'name' => $name, 'bypass_cache' => true ) );
	} catch ( Throwable $error ) {
		return new WP_Error( 'wpagent_pods_free_group_read_failed', __( 'Die Pods-Feldgruppe konnte nicht gelesen werden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	if ( ! is_object( $group ) || ! is_callable( array( $group, 'get_args' ) ) || ! is_callable( array( $group, 'get_id' ) ) ) {
		return new WP_Error( 'wpagent_pods_free_group_not_found', __( 'Pods-Feldgruppe nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	return $group;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_pods_free_group_state( object $pod, object $group, int $max_fields ) {
	$fields = wpagent_pods_free_fields( $pod, $group );
	if ( is_wp_error( $fields ) ) {
		return $fields;
	}
	$args = $group->get_args();
	$label = wpagent_pods_free_preview( $args['label'] ?? '' );
	$description = wpagent_pods_free_preview( $args['description'] ?? '' );
	$field_material = array();
	foreach ( $fields as $field ) {
		$field_material[ (string) $field->get_id() ] = $field->get_args();
	}
	ksort( $field_material, SORT_STRING );
	return array(
		'id'                  => (int) $group->get_id(),
		'pod_id'              => (int) $pod->get_id(),
		'pod_name'            => (string) ( $pod->get_args()['name'] ?? '' ),
		'name'                => (string) ( $args['name'] ?? '' ),
		'label'               => $label['text'],
		'label_truncated'     => $label['truncated'],
		'description'         => $description['text'],
		'description_truncated' => $description['truncated'],
		'type'                => (string) ( $args['type'] ?? '' ),
		'weight'              => (int) ( $args['weight'] ?? 0 ),
		'field_count'         => count( $fields ),
		'fields'              => array_map( 'wpagent_pods_free_field_state', array_slice( $fields, 0, $max_fields ) ),
		'fields_truncated'    => count( $fields ) > $max_fields,
		'hash'                => wpagent_pods_hash( array( 'group' => $args, 'fields' => $field_material ) ),
	);
}

function wpagent_pods_free_matches_search( object $pod, string $search ): bool {
	if ( '' === $search ) {
		return true;
	}
	$args = $pod->get_args();
	$haystack = (string) ( $args['name'] ?? '' ) . ' ' . (string) ( $args['label'] ?? '' ) . ' ' . (string) ( $args['label_singular'] ?? '' );
	return false !== stripos( $haystack, $search );
}

function wpagent_pods_free_group_matches_search( object $group, string $search ): bool {
	if ( '' === $search ) {
		return true;
	}
	$args = $group->get_args();
	return false !== stripos( (string) ( $args['name'] ?? '' ) . ' ' . (string) ( $args['label'] ?? '' ), $search );
}

/** @return array<string,mixed> */
function wpagent_pods_free_field_output_schema(): array {
	$properties = array(
		'id' => array( 'type' => 'integer' ), 'name' => array( 'type' => 'string' ), 'label' => array( 'type' => 'string' ),
		'label_truncated' => array( 'type' => 'boolean' ), 'description' => array( 'type' => 'string' ),
		'description_truncated' => array( 'type' => 'boolean' ), 'type' => array( 'type' => 'string' ),
		'required' => array( 'type' => 'boolean' ), 'repeatable' => array( 'type' => 'boolean' ), 'weight' => array( 'type' => 'integer' ),
		'has_unsupported_value_surface' => array( 'type' => 'boolean' ), 'hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
	);
	return array( 'type' => 'object', 'properties' => $properties, 'required' => array_keys( $properties ), 'additionalProperties' => false );
}

/** @return array<string,mixed> */
function wpagent_pods_free_pod_output_schema(): array {
	$properties = array(
		'id' => array( 'type' => 'integer' ), 'name' => array( 'type' => 'string' ), 'kind' => array( 'type' => 'string' ),
		'object' => array( 'type' => 'string' ), 'extended' => array( 'type' => 'boolean' ), 'storage' => array( 'type' => 'string' ),
		'label' => array( 'type' => 'string' ), 'label_truncated' => array( 'type' => 'boolean' ),
		'description' => array( 'type' => 'string' ), 'description_truncated' => array( 'type' => 'boolean' ),
		'field_count' => array( 'type' => 'integer' ), 'fields' => array( 'type' => 'array', 'maxItems' => WPAGENT_PODS_FREE_MAX_FIELDS, 'items' => wpagent_pods_free_field_output_schema() ),
		'fields_truncated' => array( 'type' => 'boolean' ), 'values_exposed' => array( 'type' => 'boolean', 'enum' => array( false ) ),
		'hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
	);
	return array( 'type' => 'object', 'properties' => $properties, 'required' => array_keys( $properties ), 'additionalProperties' => false );
}

/** @return array<string,mixed> */
function wpagent_pods_free_group_output_schema(): array {
	$properties = array(
		'id' => array( 'type' => 'integer' ), 'pod_id' => array( 'type' => 'integer' ), 'pod_name' => array( 'type' => 'string' ),
		'name' => array( 'type' => 'string' ), 'label' => array( 'type' => 'string' ), 'label_truncated' => array( 'type' => 'boolean' ),
		'description' => array( 'type' => 'string' ), 'description_truncated' => array( 'type' => 'boolean' ),
		'type' => array( 'type' => 'string' ), 'weight' => array( 'type' => 'integer' ), 'field_count' => array( 'type' => 'integer' ),
		'fields' => array( 'type' => 'array', 'maxItems' => WPAGENT_PODS_FREE_MAX_FIELDS, 'items' => wpagent_pods_free_field_output_schema() ),
		'fields_truncated' => array( 'type' => 'boolean' ), 'hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
	);
	return array( 'type' => 'object', 'properties' => $properties, 'required' => array_keys( $properties ), 'additionalProperties' => false );
}
