<?php
/** Closed, bounded public Gravity Forms projections. */

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

/** @return string|WP_Error */
function wpagent_gravity_public_string( $value, int $maximum, string $field, bool $allow_empty = true ) {
	return wpagent_forms_public_string( $value, $maximum, 'gravity', $field, $allow_empty );
}

/** @return int|WP_Error */
function wpagent_gravity_public_id( $value, string $field ) {
	if ( is_int( $value ) || ( is_string( $value ) && ctype_digit( $value ) ) ) {
		$id = (int) $value;
		if ( $id >= 0 ) {
			return $id;
		}
	}
	return wpagent_forms_public_output_error( 'gravity', $field );
}

/** @return array<int,array<string,mixed>>|WP_Error */
function wpagent_gravity_public_choices( $value, string $field ) {
	if ( null === $value ) {
		return array();
	}
	$choices = wpagent_forms_public_list( $value, WPAGENT_FORMS_PUBLIC_MAX_OPTIONS, 'gravity', $field );
	if ( is_wp_error( $choices ) ) {
		return $choices;
	}
	$result = array();
	foreach ( $choices as $index => $choice ) {
		$choice = wpagent_forms_public_object( $choice, 20, 'gravity', $field . '.' . $index );
		if ( is_wp_error( $choice ) ) {
			return $choice;
		}
		$text = wpagent_gravity_public_string( $choice['text'] ?? '', WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT, $field . '.' . $index . '.text' );
		$value = wpagent_gravity_public_string( $choice['value'] ?? '', WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT, $field . '.' . $index . '.value' );
		if ( is_wp_error( $text ) || is_wp_error( $value ) ) {
			return is_wp_error( $text ) ? $text : $value;
		}
		$result[] = array( 'text' => $text, 'value' => $value, 'isSelected' => ! empty( $choice['isSelected'] ) );
	}
	return $result;
}

/** @return array<int,array<string,string>>|WP_Error */
function wpagent_gravity_public_inputs( $value, string $field ) {
	if ( null === $value ) {
		return array();
	}
	$inputs = wpagent_forms_public_list( $value, WPAGENT_FORMS_PUBLIC_MAX_OPTIONS, 'gravity', $field );
	if ( is_wp_error( $inputs ) ) {
		return $inputs;
	}
	$result = array();
	foreach ( $inputs as $index => $input ) {
		$input = wpagent_forms_public_object( $input, 20, 'gravity', $field . '.' . $index );
		if ( is_wp_error( $input ) ) {
			return $input;
		}
		$raw_id = $input['id'] ?? '';
		if ( ! is_string( $raw_id ) && ! is_int( $raw_id ) ) {
			return wpagent_forms_public_output_error( 'gravity', $field . '.' . $index . '.id' );
		}
		$id = wpagent_gravity_public_string( (string) $raw_id, 64, $field . '.' . $index . '.id', false );
		$label = wpagent_gravity_public_string( $input['label'] ?? '', WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT, $field . '.' . $index . '.label' );
		$name = wpagent_gravity_public_string( $input['name'] ?? '', 128, $field . '.' . $index . '.name' );
		if ( is_wp_error( $id ) || is_wp_error( $label ) || is_wp_error( $name ) ) {
			return is_wp_error( $id ) ? $id : ( is_wp_error( $label ) ? $label : $name );
		}
		$result[] = array( 'id' => $id, 'label' => $label, 'name' => $name );
	}
	return $result;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_gravity_public_field( $value, int $index ) {
	$field = wpagent_forms_public_object( $value, 100, 'gravity', 'fields.' . $index );
	if ( is_wp_error( $field ) ) {
		return $field;
	}
	$id = wpagent_gravity_public_id( $field['id'] ?? -1, 'fields.' . $index . '.id' );
	$type = wpagent_gravity_public_string( $field['type'] ?? '', 64, 'fields.' . $index . '.type', false );
	if ( is_wp_error( $id ) || is_wp_error( $type ) ) {
		return is_wp_error( $id ) ? $id : $type;
	}
	$row = array( 'id' => $id, 'type' => $type, 'label' => wpagent_gravity_public_string( $field['label'] ?? '', WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT, 'fields.' . $index . '.label' ), 'description' => wpagent_gravity_public_string( $field['description'] ?? '', WPAGENT_FORMS_PUBLIC_MAX_TEXT, 'fields.' . $index . '.description' ), 'placeholder' => wpagent_gravity_public_string( $field['placeholder'] ?? '', WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT, 'fields.' . $index . '.placeholder' ), 'defaultValue' => wpagent_gravity_public_string( $field['defaultValue'] ?? '', WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT, 'fields.' . $index . '.defaultValue' ), 'isRequired' => ! empty( $field['isRequired'] ), 'inputName' => wpagent_gravity_public_string( $field['inputName'] ?? '', 128, 'fields.' . $index . '.inputName' ), 'choices' => wpagent_gravity_public_choices( $field['choices'] ?? null, 'fields.' . $index . '.choices' ), 'inputs' => wpagent_gravity_public_inputs( $field['inputs'] ?? null, 'fields.' . $index . '.inputs' ) );
	foreach ( $row as $item ) {
		if ( is_wp_error( $item ) ) {
			return $item;
		}
	}
	return $row;
}

/** @return array<int,array<string,mixed>>|WP_Error */
function wpagent_gravity_public_records( $value, string $field, bool $confirmation ) {
	$records = wpagent_forms_public_object( $value, WPAGENT_FORMS_PUBLIC_MAX_OPTIONS, 'gravity', $field );
	if ( is_wp_error( $records ) ) {
		return $records;
	}
	$result = array();
	foreach ( $records as $id => $record ) {
		$record = wpagent_forms_public_object( $record, 100, 'gravity', $field . '.' . $id );
		if ( is_wp_error( $record ) ) {
			return $record;
		}
		$raw_id = $record['id'] ?? $id;
		if ( ! is_string( $raw_id ) && ! is_int( $raw_id ) ) {
			return wpagent_forms_public_output_error( 'gravity', $field . '.' . $id . '.id' );
		}
		$row = array( 'id' => wpagent_gravity_public_string( (string) $raw_id, 128, $field . '.' . $id . '.id', false ), 'name' => wpagent_gravity_public_string( $record['name'] ?? '', 255, $field . '.' . $id . '.name' ), 'type' => wpagent_gravity_public_string( $record['type'] ?? ( $confirmation ? 'message' : 'notification' ), 64, $field . '.' . $id . '.type' ), 'active' => ! empty( $record['isActive'] ) || ! empty( $record['is_active'] ) );
		if ( $confirmation ) {
			$row['url'] = wpagent_gravity_public_string( $record['url'] ?? '', 2048, $field . '.' . $id . '.url' );
			$row['page_id'] = wpagent_gravity_public_id( $record['pageId'] ?? $record['page_id'] ?? 0, $field . '.' . $id . '.page_id' );
			$message = wpagent_gravity_public_string( $record['message'] ?? '', WPAGENT_FORMS_PUBLIC_MAX_TEXT, $field . '.' . $id . '.message' );
			$row['has_message'] = ! is_wp_error( $message ) && '' !== $message;
			if ( is_wp_error( $message ) ) {
				return $message;
			}
		} else {
			$row['event'] = wpagent_gravity_public_string( $record['event'] ?? '', 128, $field . '.' . $id . '.event' );
			$row['to'] = wpagent_gravity_public_string( $record['to'] ?? '', 2000, $field . '.' . $id . '.to' );
			$row['subject'] = wpagent_gravity_public_string( $record['subject'] ?? '', 2000, $field . '.' . $id . '.subject' );
		}
		foreach ( $row as $item ) {
			if ( is_wp_error( $item ) ) {
				return $item;
			}
		}
		$result[] = $row;
	}
	return $result;
}

/** @param array<string,mixed> $form @return array<string,mixed>|WP_Error */
function wpagent_gravity_public_settings( array $form ) {
	$strings = array(
		'labelPlacement' => array( 'top_label', 'left_label', 'right_label' ),
		'descriptionPlacement' => array( 'above', 'below' ),
		'subLabelPlacement' => array( 'above', 'below' ),
		'requiredIndicator' => array( 'text', 'asterisk', 'custom' ),
	);
	$defaults = array( 'labelPlacement' => 'top_label', 'descriptionPlacement' => 'above', 'subLabelPlacement' => 'above', 'requiredIndicator' => 'text' );
	$result = array();
	foreach ( $strings as $key => $allowed ) {
		$value = wpagent_gravity_public_string( $form[ $key ] ?? $defaults[ $key ], 64, 'settings.' . $key, false );
		if ( is_wp_error( $value ) || ! in_array( $value, $allowed, true ) ) {
			return is_wp_error( $value ) ? $value : wpagent_forms_public_output_error( 'gravity', 'settings.' . $key );
		}
		$result[ $key ] = $value;
	}
	$result['customRequiredIndicator'] = wpagent_gravity_public_string( $form['customRequiredIndicator'] ?? '', 100, 'settings.customRequiredIndicator' );
	$result['cssClass'] = wpagent_gravity_public_string( $form['cssClass'] ?? '', 500, 'settings.cssClass' );
	foreach ( array( 'validationSummary', 'enableAnimation' ) as $key ) {
		$value = $form[ $key ] ?? false;
		if ( ! is_bool( $value ) ) {
			return wpagent_forms_public_output_error( 'gravity', 'settings.' . $key );
		}
		$result[ $key ] = $value;
	}
	$markup = $form['markupVersion'] ?? 2;
	if ( ! is_int( $markup ) || ! in_array( $markup, array( 1, 2 ), true ) ) {
		return wpagent_forms_public_output_error( 'gravity', 'settings.markupVersion' );
	}
	$result['markupVersion'] = $markup;
	foreach ( $result as $value ) {
		if ( is_wp_error( $value ) ) {
			return $value;
		}
	}
	return $result;
}

/** @param array<string,mixed> $form @return array<string,mixed>|WP_Error */
function wpagent_gravity_public_form_payload( array $form ) {
	$fields = wpagent_forms_public_list( $form['fields'] ?? array(), WPAGENT_FORMS_PUBLIC_MAX_FIELDS, 'gravity', 'fields' );
	if ( is_wp_error( $fields ) ) {
		return $fields;
	}
	$public_fields = array();
	foreach ( $fields as $index => $field ) {
		$public = wpagent_gravity_public_field( $field, $index );
		if ( is_wp_error( $public ) ) {
			return $public;
		}
		$public_fields[] = $public;
	}
	$button = wpagent_forms_public_object( $form['button'] ?? array(), 20, 'gravity', 'button' );
	if ( is_wp_error( $button ) ) {
		return $button;
	}
	$button = array( 'type' => wpagent_gravity_public_string( $button['type'] ?? 'text', 64, 'button.type' ), 'text' => wpagent_gravity_public_string( $button['text'] ?? '', 500, 'button.text' ) );
	$notifications = wpagent_gravity_public_records( $form['notifications'] ?? array(), 'notifications', false );
	$confirmations = wpagent_gravity_public_records( $form['confirmations'] ?? array(), 'confirmations', true );
	$settings = wpagent_gravity_public_settings( $form );
	$id = wpagent_gravity_public_id( $form['id'] ?? -1, 'id' );
	if ( is_wp_error( $id ) || $id <= 0 ) {
		return is_wp_error( $id ) ? $id : wpagent_forms_public_output_error( 'gravity', 'id' );
	}
	$payload = array( 'provider' => 'gravity-forms', 'id' => $id, 'title' => wpagent_gravity_public_string( $form['title'] ?? '', 255, 'title' ), 'description' => wpagent_gravity_public_string( $form['description'] ?? '', WPAGENT_FORMS_PUBLIC_MAX_TEXT, 'description' ), 'date_created' => wpagent_gravity_public_string( $form['date_created'] ?? '', 64, 'date_created' ), 'is_active' => ! empty( $form['is_active'] ), 'is_trash' => ! empty( $form['is_trash'] ), 'version' => wpagent_gravity_public_string( $form['version'] ?? '', 64, 'version' ), 'shortcode' => sprintf( '[gravityform id="%d"]', $id ), 'fields' => $public_fields, 'button' => $button, 'notifications' => $notifications, 'confirmations' => $confirmations, 'settings' => $settings, 'state_hash' => wpagent_gravity_form_state_hash( $form ) );
	foreach ( $payload as $item ) {
		if ( is_wp_error( $item ) ) {
			return $item;
		}
	}
	return $payload;
}

/** @return array<string,mixed> */
function wpagent_gravity_form_list_item_schema(): array {
	return wpagent_forms_public_object_schema( array( 'provider' => wpagent_forms_public_string_schema( 32, true ), 'id' => array( 'type' => 'integer', 'minimum' => 1 ), 'title' => wpagent_forms_public_string_schema( 255 ), 'date_created' => wpagent_forms_public_string_schema( 64 ), 'is_active' => array( 'type' => 'boolean' ), 'is_trash' => array( 'type' => 'boolean' ), 'shortcode' => wpagent_forms_public_string_schema( 64 ), 'state_hash' => wpagent_forms_public_hash_schema() ), array( 'provider', 'id', 'title', 'date_created', 'is_active', 'is_trash', 'shortcode', 'state_hash' ) );
}

/** @return array<string,mixed> */
function wpagent_gravity_form_output_schema(): array {
	$choice = wpagent_forms_public_object_schema( array( 'text' => wpagent_forms_public_string_schema( WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT ), 'value' => wpagent_forms_public_string_schema( WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT ), 'isSelected' => array( 'type' => 'boolean' ) ), array( 'text', 'value', 'isSelected' ) );
	$input = wpagent_forms_public_object_schema( array( 'id' => wpagent_forms_public_string_schema( 64, true ), 'label' => wpagent_forms_public_string_schema( WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT ), 'name' => wpagent_forms_public_string_schema( 128 ) ), array( 'id', 'label', 'name' ) );
	$field = wpagent_forms_public_object_schema( array( 'id' => array( 'type' => 'integer', 'minimum' => 0 ), 'type' => wpagent_forms_public_string_schema( 64, true ), 'label' => wpagent_forms_public_string_schema( WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT ), 'description' => wpagent_forms_public_string_schema( WPAGENT_FORMS_PUBLIC_MAX_TEXT ), 'placeholder' => wpagent_forms_public_string_schema( WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT ), 'defaultValue' => wpagent_forms_public_string_schema( WPAGENT_FORMS_PUBLIC_MAX_SHORT_TEXT ), 'isRequired' => array( 'type' => 'boolean' ), 'inputName' => wpagent_forms_public_string_schema( 128 ), 'choices' => wpagent_forms_public_list_schema( $choice, WPAGENT_FORMS_PUBLIC_MAX_OPTIONS ), 'inputs' => wpagent_forms_public_list_schema( $input, WPAGENT_FORMS_PUBLIC_MAX_OPTIONS ) ), array( 'id', 'type', 'label', 'description', 'placeholder', 'defaultValue', 'isRequired', 'inputName', 'choices', 'inputs' ) );
	$button = wpagent_forms_public_object_schema( array( 'type' => wpagent_forms_public_string_schema( 64 ), 'text' => wpagent_forms_public_string_schema( 500 ) ), array( 'type', 'text' ) );
	$notification = wpagent_forms_public_object_schema( array( 'id' => wpagent_forms_public_string_schema( 128, true ), 'name' => wpagent_forms_public_string_schema( 255 ), 'type' => wpagent_forms_public_string_schema( 64 ), 'active' => array( 'type' => 'boolean' ), 'event' => wpagent_forms_public_string_schema( 128 ), 'to' => wpagent_forms_public_string_schema( 2000 ), 'subject' => wpagent_forms_public_string_schema( 2000 ) ), array( 'id', 'name', 'type', 'active', 'event', 'to', 'subject' ) );
	$confirmation = wpagent_forms_public_object_schema( array( 'id' => wpagent_forms_public_string_schema( 128, true ), 'name' => wpagent_forms_public_string_schema( 255 ), 'type' => wpagent_forms_public_string_schema( 64 ), 'active' => array( 'type' => 'boolean' ), 'url' => wpagent_forms_public_string_schema( 2048 ), 'page_id' => array( 'type' => 'integer', 'minimum' => 0 ), 'has_message' => array( 'type' => 'boolean' ) ), array( 'id', 'name', 'type', 'active', 'url', 'page_id', 'has_message' ) );
	$settings = wpagent_forms_public_object_schema( array( 'labelPlacement' => array( 'type' => 'string', 'enum' => array( 'top_label', 'left_label', 'right_label' ) ), 'descriptionPlacement' => array( 'type' => 'string', 'enum' => array( 'above', 'below' ) ), 'subLabelPlacement' => array( 'type' => 'string', 'enum' => array( 'above', 'below' ) ), 'validationSummary' => array( 'type' => 'boolean' ), 'requiredIndicator' => array( 'type' => 'string', 'enum' => array( 'text', 'asterisk', 'custom' ) ), 'customRequiredIndicator' => wpagent_forms_public_string_schema( 100 ), 'cssClass' => wpagent_forms_public_string_schema( 500 ), 'enableAnimation' => array( 'type' => 'boolean' ), 'markupVersion' => array( 'type' => 'integer', 'enum' => array( 1, 2 ) ) ), array( 'labelPlacement', 'descriptionPlacement', 'subLabelPlacement', 'validationSummary', 'requiredIndicator', 'customRequiredIndicator', 'cssClass', 'enableAnimation', 'markupVersion' ) );
	return wpagent_forms_public_object_schema( array( 'provider' => wpagent_forms_public_string_schema( 32, true ), 'id' => array( 'type' => 'integer', 'minimum' => 1 ), 'title' => wpagent_forms_public_string_schema( 255 ), 'description' => wpagent_forms_public_string_schema( WPAGENT_FORMS_PUBLIC_MAX_TEXT ), 'date_created' => wpagent_forms_public_string_schema( 64 ), 'is_active' => array( 'type' => 'boolean' ), 'is_trash' => array( 'type' => 'boolean' ), 'version' => wpagent_forms_public_string_schema( 64 ), 'shortcode' => wpagent_forms_public_string_schema( 64 ), 'fields' => wpagent_forms_public_list_schema( $field, WPAGENT_FORMS_PUBLIC_MAX_FIELDS ), 'button' => $button, 'notifications' => wpagent_forms_public_list_schema( $notification, WPAGENT_FORMS_PUBLIC_MAX_OPTIONS ), 'confirmations' => wpagent_forms_public_list_schema( $confirmation, WPAGENT_FORMS_PUBLIC_MAX_OPTIONS ), 'settings' => $settings, 'state_hash' => wpagent_forms_public_hash_schema() ), array( 'provider', 'id', 'title', 'description', 'date_created', 'is_active', 'is_trash', 'version', 'shortcode', 'fields', 'button', 'notifications', 'confirmations', 'settings', 'state_hash' ) );
}
