<?php
/**
 * Options.
 *
 * @package ThemeIsle\GutenbergBlocks\Plugins
 */

namespace ThemeIsle\GutenbergBlocks\Plugins;

use ThemeIsle\GutenbergBlocks\Server\Template_Cloud_Server;
use ThemeIsle\GutenbergBlocks\Plugins\Template_Cloud;

/**
 * Class Options_Settings
 */
class Options_Settings {

	/**
	 * The main instance var.
	 *
	 * @var Options_Settings|null
	 */
	protected static $instance = null;

	/**
	 * Initialize the class
	 */
	public function init() {
		add_action( 'init', array( $this, 'register_settings' ), 99 );
		add_action( 'init', array( $this, 'default_block' ), 99 );
		add_action( 'init', array( $this, 'register_meta' ), 19 );
	}

	/**
	 * Register Settings
	 *
	 * @since   1.2.0
	 * @access  public
	 */
	public function register_settings() {
		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_redirect',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Redirect on new install.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_onboarding',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Show Editor Onboarding.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_css_module',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Custom CSS module allows to add custom CSS to each block in Block Editor.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_blocks_animation',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Blocks Animation module allows to add CSS animations to each block in Block Editor.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_block_conditions',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Blocks Conditions module allows to hide/display blocks to your users based on selected conditions.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_patterns_library',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Patterns Library module allows to add predefined patterns to your blocks.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_dynamic_content',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Dynamic Content allows you to display dynamic content, link and images in your content.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_highlight_dynamic',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Easily differentiate between dynamic and normal text in the editor.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_optimize_animations_css',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Optimize Animations CSS.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_disable_review_schema',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Enable Rich Schema in Product Review Block.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_review_scale',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Use 0.5 Scale for Review Block.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => false,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_block_ai_toolbar_module',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Enable the AI Block Toolbar in Editor', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_atomic_wind_blocks',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Enable Atomic Wind Blocks', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => false,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'otter_blocks_logger_flag',
			array(
				'type'         => 'string',
				'description'  => __( 'Become a contributor by opting in to our anonymous data tracking. We guarantee no sensitive data is collected.', 'otter-blocks' ),
				'show_in_rest' => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'otter_blocks_logger_data',
			array(
				'type'         => 'object',
				'description'  => __( 'Anonymous data tracking object.', 'otter-blocks' ),
				'show_in_rest' => array(
					'schema' => array(
						'type'       => 'object',
						'properties' => array(
							'blocks'    => array(
								'type'  => 'array',
								'items' => array(
									'type'       => 'object',
									'properties' => array(
										'name'      => array(
											'type' => 'string',
										),
										'instances' => array(
											'type' => 'number',
										),
									),
								),
							),
							'templates' => array(
								'type'  => 'array',
								'items' => array(
									'type'       => 'object',
									'properties' => array(
										'url'       => array(
											'type' => 'string',
										),
										'instances' => array(
											'type' => 'number',
										),
									),
								),
							),
						),
					),
				),
				'default'      => array(
					'blocks'    => array(),
					'templates' => array(),
				),
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_google_map_block_api_key',
			array(
				'type'              => 'string',
				'description'       => __( 'Google Map API key for the Google Maps Gutenberg Block.', 'otter-blocks' ),
				'sanitize_callback' => 'sanitize_text_field',
				'show_in_rest'      => true,
				'default'           => '',
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_stripe_api_key',
			array(
				'type'              => 'string',
				'description'       => __( 'Stripe API key for the Stripe Block.', 'otter-blocks' ),
				'sanitize_callback' => 'sanitize_text_field',
				'show_in_rest'      => true,
				'default'           => '',
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_google_captcha_api_site_key',
			array(
				'type'              => 'string',
				'description'       => __( 'Google reCaptcha Site API key for the Form Block.', 'otter-blocks' ),
				'sanitize_callback' => 'sanitize_text_field',
				'show_in_rest'      => true,
				'default'           => '',
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_google_captcha_api_secret_key',
			array(
				'type'              => 'string',
				'description'       => __( 'Google reCaptcha Secret API key for the Form Block.', 'otter-blocks' ),
				'sanitize_callback' => 'sanitize_text_field',
				'show_in_rest'      => true,
				'default'           => '',
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_cloudflare_turnstile_site_key',
			array(
				'type'              => 'string',
				'description'       => __( 'Cloudflare Turnstile Site key for the Form Block.', 'otter-blocks' ),
				'sanitize_callback' => 'sanitize_text_field',
				'show_in_rest'      => true,
				'default'           => '',
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_cloudflare_turnstile_secret_key',
			array(
				'type'              => 'string',
				'description'       => __( 'Cloudflare Turnstile Secret key for the Form Block.', 'otter-blocks' ),
				'sanitize_callback' => 'sanitize_text_field',
				'show_in_rest'      => true,
				'default'           => '',
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_default_block',
			array(
				'type'              => 'boolean',
				'description'       => __( 'Make Section block your default block for Pages?', 'otter-blocks' ),
				'sanitize_callback' => 'rest_sanitize_boolean',
				'show_in_rest'      => true,
				'default'           => false,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_global_defaults',
			array(
				'type'              => 'string',
				'description'       => __( 'Global defaults for Gutenberg Blocks.', 'otter-blocks' ),
				'sanitize_callback' => 'sanitize_text_field',
				'show_in_rest'      => true,
				'default'           => '',
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_form_emails',
			array(
				'type'              => 'array',
				'description'       => __( 'Email used in the Form block.', 'otter-blocks' ),
				'sanitize_callback' => function ( $email_settings ) {
					return array_map(
						function ( $item ) {
							if ( isset( $item['form'] ) ) {
								$item['form'] = sanitize_text_field( $item['form'] );
							}
							if ( isset( $item['email'] ) ) {
								$item['email'] = sanitize_text_field( $item['email'] );
							}
							if ( isset( $item['redirectLink'] ) ) {
								$item['redirectLink'] = sanitize_text_field( $item['redirectLink'] );
							}
							if ( isset( $item['titleSubject'] ) ) {
								$item['titleSubject'] = sanitize_text_field( $item['titleSubject'] );
							}
							if ( isset( $item['fromName'] ) ) {
								$item['fromName'] = sanitize_text_field( $item['fromName'] );
							}
							if ( isset( $item['fromEmail'] ) ) {
								$item['fromEmail'] = sanitize_email( $item['fromEmail'] );
							}
							if ( isset( $item['cc'] ) ) {
								$item['cc'] = sanitize_text_field( $item['cc'] );
							}
							if ( isset( $item['bcc'] ) ) {
								$item['bcc'] = sanitize_text_field( $item['bcc'] );
							}
							if ( isset( $item['replyTo'] ) ) {
								$item['replyTo'] = sanitize_email( $item['replyTo'] );
							}
							if ( isset( $item['autoresponder']['body'] ) ) {
								$item['autoresponder']['body'] = wp_kses( $item['autoresponder']['body'], $this::get_allowed_mail_html() );
							}
							if ( isset( $item['autoresponder']['subject'] ) ) {
								$item['autoresponder']['subject'] = sanitize_text_field( $item['autoresponder']['subject'] );
							}
							if ( isset( $item['aiAutoresponder']['enabled'] ) ) {
								$item['aiAutoresponder']['enabled'] = ! empty( $item['aiAutoresponder']['enabled'] );
							}
							if ( isset( $item['aiAutoresponder']['prompt'] ) ) {
								$item['aiAutoresponder']['prompt'] = sanitize_textarea_field( $item['aiAutoresponder']['prompt'] );
							}
							if ( isset( $item['submitMessage'] ) ) {
								$item['submitMessage'] = sanitize_text_field( $item['submitMessage'] );
							}
							if ( isset( $item['errorMessage'] ) ) {
								$item['errorMessage'] = sanitize_text_field( $item['errorMessage'] );
							}
							if ( isset( $item['integration']['provider'] ) ) {
								$item['integration']['provider'] = sanitize_text_field( $item['integration']['provider'] );
							}
							if ( isset( $item['integration']['apiKey'] ) ) {
								$item['integration']['apiKey'] = sanitize_text_field( $item['integration']['apiKey'] );
							}
							if ( isset( $item['integration']['listId'] ) ) {
								$item['integration']['listId'] = sanitize_text_field( $item['integration']['listId'] );
							}
							if ( isset( $item['integration']['action'] ) ) {
								$item['integration']['action'] = sanitize_text_field( $item['integration']['action'] );
							}
							if ( isset( $item['submissionsSaveLocation'] ) ) {
								$item['submissionsSaveLocation'] = sanitize_text_field( $item['submissionsSaveLocation'] );
							}

							if ( isset( $item['emailNotification'] ) ) {
								$item['emailNotification'] = rest_sanitize_boolean( $item['emailNotification'] );
							}

							if ( isset( $item['requiredFields'] ) ) {
								if ( is_array( $item['requiredFields'] ) ) {
									$item['requiredFields'] = array_map( 'sanitize_text_field', $item['requiredFields'] );
								} else {
									$item['requiredFields'] = array();
								}
							}

							return $item;
						},
						$email_settings
					);
				},
				'show_in_rest'      => array(
					'schema' => array(
						'type'  => 'array',
						'items' => array(
							'type'       => 'object',
							'properties' => array(
								'form'                    => array(
									'type' => 'string',
								),
								'hasCaptcha'              => array(
									'type' => array( 'boolean', 'number', 'string' ),
								),
								'email'                   => array(
									'type' => 'string',
								),
								'fromName'                => array(
									'type' => 'string',
								),
								'fromEmail'               => array(
									'type' => 'string',
								),
								'redirectLink'            => array(
									'type' => 'string',
								),
								'emailSubject'            => array(
									'type' => 'string',
								),
								'submitMessage'           => array(
									'type' => 'string',
								),
								'errorMessage'            => array(
									'type' => 'string',
								),
								'cc'                      => array(
									'type' => 'string',
								),
								'bcc'                     => array(
									'type' => 'string',
								),
								'replyTo'                 => array(
									'type' => 'string',
								),
								'autoresponder'           => array(
									'type'       => 'object',
									'properties' => array(
										'subject' => array(
											'type' => 'string',
										),
										'body'    => array(
											'type' => 'string',
										),
									),
								),
								'aiAutoresponder'         => array(
									'type'       => 'object',
									'properties' => array(
										'enabled' => array(
											'type' => 'boolean',
										),
										'prompt'  => array(
											'type' => 'string',
										),
									),
								),
								'integration'             => array(
									'type'       => 'object',
									'properties' => array(
										'provider' => array(
											'type' => 'string',
										),
										'apiKey'   => array(
											'type' => 'string',
										),
										'listId'   => array(
											'type' => 'string',
										),
										'action'   => array(
											'type' => 'string',
										),
									),
								),
								'submissionsSaveLocation' => array(
									'type' => 'string',
								),
								'emailNotification'       => array(
									'type' => array( 'boolean', 'number', 'string' ),
								),
								'webhookId'               => array(
									'type' => 'string',
								),
								'requiredFields'          => array(
									'type'  => 'array',
									'items' => array(
										'type' => 'string',
									),
								),
							),
						),
					),
				),
				'default'           => array(),
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_form_fields_option',
			array(
				'type'              => 'array',
				'description'       => __( 'Form Fields used in the Form block.', 'otter-blocks' ),
				'sanitize_callback' => function ( $fields ) {
					return array_map(
						function ( $item ) {
							if ( isset( $item['fieldOptionName'] ) ) {
								$item['fieldOptionName'] = sanitize_text_field( $item['fieldOptionName'] );
							}
							if ( isset( $item['fieldOptionType'] ) ) {
								$item['fieldOptionType'] = sanitize_text_field( $item['fieldOptionType'] );
							}

							if ( isset( $item['options']['maxFileSize'] ) ) {
								$item['options']['maxFileSize'] = sanitize_text_field( $item['options']['maxFileSize'] );
							}
							if ( isset( $item['options']['allowedFileTypes'] ) && is_array( $item['options']['allowedFileTypes'] ) ) {
								foreach ( $item['options']['allowedFileTypes'] as $key => $value ) {
									$item['options']['allowedFileTypes'][ $key ] = sanitize_text_field( $value );
								}
							}
							if ( isset( $item['options']['saveFiles'] ) ) {
								$item['options']['saveFiles'] = sanitize_text_field( $item['options']['saveFiles'] );
							}
							if ( isset( $item['options']['maxFilesNumber'] ) && ! is_int( $item['options']['maxFilesNumber'] ) ) {
								$item['options']['maxFilesNumber'] = sanitize_text_field( $item['options']['maxFilesNumber'] );
							}

							if ( isset( $item['stripe']['product'] ) ) {
								$item['stripe']['product'] = sanitize_text_field( $item['stripe']['product'] );
							}

							if ( isset( $item['stripe']['price'] ) ) {
								$item['stripe']['price'] = sanitize_text_field( $item['stripe']['price'] );
							}

							if ( isset( $item['stripe']['quantity'] ) && ! is_int( $item['stripe']['quantity'] ) ) {
								$item['stripe']['quantity'] = sanitize_text_field( $item['stripe']['quantity'] );
							}

							return $item;
						},
						$fields
					);
				},
				'show_in_rest'      => array(
					'schema' => array(
						'type'  => 'array',
						'items' => array(
							'type'       => 'object',
							'properties' => array(
								'fieldOptionName' => array(
									'type' => 'string',
								),
								'fieldOptionType' => array(
									'type' => 'string',
								),
								'options'         => array(
									'type'       => 'object',
									'properties' => array(
										'maxFileSize'      => array(
											'type' => array( 'string', 'number' ),
										),
										'allowedFileTypes' => array(
											'type'  => 'array',
											'items' => array(
												'type' => 'string',
											),
										),
										'saveFiles'        => array(
											'type' => 'string',
										),
										'maxFilesNumber'   => array(
											'type' => array( 'string', 'number' ),
										),
									),
									'default'    => array(),
								),
								'stripe'          => array(
									'type'       => 'object',
									'properties' => array(
										'product'  => array(
											'type' => 'string',
										),
										'price'    => array(
											'type' => 'string',
										),
										'quantity' => array(
											'type'    => 'number',
											'default' => 1,
										),
									),

								),
							),
						),
					),
				),
				'default'           => array(),
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_notifications',
			array(
				'type'              => 'object',
				'description'       => __( 'Notifications Logs.', 'otter-blocks' ),
				'sanitize_callback' => function ( $notifications ) {
					return array_map(
						function ( $item ) {
							if ( isset( $item['editor_upsell'] ) ) {
								$item['editor_upsell'] = boolval( $item['editor_upsell'] );
							}
							return $item;
						},
						$notifications
					);
				},
				'show_in_rest'      => array(
					'schema' => array(
						'type'       => 'object',
						'properties' => array(
							'editor_upsell' => array(
								'type' => array( 'boolean', 'number', 'string' ),
							),
						),
					),
				),
				'default'           => array(
					'editor_upsell' => false,
				),
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_webhooks_options',
			array(
				'type'              => 'array',
				'description'       => __( 'Otter Registered Webhooks.', 'otter-blocks' ),
				'sanitize_callback' => function ( $webhooks ) {
					return array_map(
						function ( $item ) {
							if ( isset( $item['id'] ) ) {
								$item['id'] = sanitize_text_field( $item['id'] );
							}
							if ( isset( $item['url'] ) ) {
								$item['url'] = esc_url_raw( $item['url'] );
							}
							if ( isset( $item['name'] ) ) {
								$item['name'] = sanitize_text_field( $item['name'] );
							}
							if ( isset( $item['method'] ) ) {
								$item['method'] = sanitize_text_field( $item['method'] );
							}
							if ( isset( $item['headers'] ) && is_array( $item['headers'] ) ) {
								foreach ( $item['headers'] as &$header ) {
									$header['key']   = sanitize_text_field( $header['key'] );
									$header['value'] = sanitize_text_field( $header['value'] );
								}
							} else {
								$item['headers'] = array();
							}
							return $item;
						},
						$webhooks
					);
				},
				'show_in_rest'      => array(
					'schema' => array(
						'type'  => 'array',
						'items' => array(
							'type'       => 'object',
							'properties' => array(
								'id'      => array(
									'type' => 'string',
								),
								'url'     => array(
									'type' => 'string',
								),
								'headers' => array(
									'type'  => 'array',
									'items' => array(
										'type'       => 'object',
										'properties' => array(
											'key'   => array(
												'type' => 'string',
											),
											'value' => array(
												'type' => 'string',
											),
										),
									),
								),
								'name'    => array(
									'type' => 'string',
								),
								'method'  => array(
									'type' => 'string',
								),
							),
						),
					),
				),
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_open_ai_api_key',
			array(
				'type'              => 'string',
				'description'       => __( 'The OpenAI API Key required for usage of Otter AI features.', 'otter-blocks' ),
				'sanitize_callback' => 'sanitize_text_field',
				'show_in_rest'      => true,
				'default'           => '',
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_otter_ai_usage',
			array(
				'type'              => 'object',
				'description'       => __( 'Usage of Otter AI features.', 'otter-blocks' ),
				'sanitize_callback' => function ( $value ) {
					$sanitized = array(
						'usage_count' => array(),
						'prompts'     => array(),
					);

					if ( ! is_array( $value ) ) {
						return $sanitized;
					}

					if ( isset( $value['usage_count'] ) && is_array( $value['usage_count'] ) ) {
						foreach ( $value['usage_count'] as $item ) {
							if ( ! is_array( $item ) || ! isset( $item['key'], $item['value'] ) || ! is_string( $item['key'] ) || ! is_numeric( $item['value'] ) ) {
								continue;
							}

							$sanitized['usage_count'][] = array(
								'key'   => substr( sanitize_text_field( $item['key'] ), 0, 100 ),
								'value' => max( 0, (int) $item['value'] ),
							);

							if ( count( $sanitized['usage_count'] ) >= 50 ) {
								break;
							}
						}
					}

					if ( isset( $value['prompts'] ) && is_array( $value['prompts'] ) ) {
						foreach ( $value['prompts'] as $item ) {
							if ( ! is_array( $item ) || ! isset( $item['key'], $item['values'] ) || ! is_string( $item['key'] ) || ! is_array( $item['values'] ) ) {
								continue;
							}

							$values = array();

							foreach ( $item['values'] as $prompt ) {
								if ( is_string( $prompt ) ) {
									$values[] = substr( sanitize_textarea_field( $prompt ), 0, 1000 );
								}
							}

							$sanitized['prompts'][] = array(
								'key'    => substr( sanitize_text_field( $item['key'] ), 0, 100 ),
								'values' => array_slice( $values, -10 ),
							);

							if ( count( $sanitized['prompts'] ) >= 50 ) {
								break;
							}
						}
					}

					return $sanitized;
				},
				'show_in_rest'      => array(
					'schema' => array(
						'type'       => 'object',
						'properties' => array(
							'usage_count' => array(
								'type'    => 'array',
								'items'   => array(
									'type'       => 'object',
									'properties' => array(
										'key'   => array(
											'type' => 'string',
										),
										'value' => array(
											'type' => 'integer',
										),
									),
								),
								'default' => array(),
							),
							'prompts'     => array(
								'type'    => 'array',
								'items'   => array(
									'type'       => 'object',
									'properties' => array(
										'key'    => array(
											'type' => 'string',
										),
										'values' => array(
											'type'  => 'array',
											'items' => array(
												'type' => 'string',
											),
										),
									),
								),
								'default' => array(),
							),
						),
					),
				),
				'default'           => array(),
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_disabled_blocks',
			array(
				'type'              => 'array',
				'description'       => __( 'The disabled blocks that will no longer be shown in Inserter.', 'otter-blocks' ),
				'sanitize_callback' => function ( $disabled_blocks ) {
					return array_map( 'sanitize_text_field', $disabled_blocks );
				},
				'default'           => array(),
				'show_in_rest'      => array(
					'schema' => array(
						'type'  => 'array',
						'items' => array(
							'type' => 'string',
						),
					),
				),
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_onboarding_wizard',
			array(
				'type'         => 'boolean',
				'description'  => __( 'Enable FSE Onboarding Wizard.', 'otter-blocks' ),
				'show_in_rest' => true,
				'default'      => true,
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			'themeisle_blocks_settings_prompt_actions',
			array(
				'type'              => 'array',
				'description'       => __( 'The prompt actions list of toolbar.', 'otter-blocks' ),
				'sanitize_callback' => function ( $prompts ) {
					return array_map(
						function ( $item ) {
							if ( isset( $item['title'] ) ) {
								$item['title'] = sanitize_text_field( $item['title'] );
							}
							if ( isset( $item['prompt'] ) ) {
								$item['prompt'] = sanitize_text_field( $item['prompt'] );
							}
							return $item;
						},
						$prompts
					);
				},
				'default'           => array(
					array(
						'title'  => 'Fix Grammar',
						'prompt' => 'Fix any grammatical errors in the following: {text_input}',
					),
					array(
						'title'  => 'Rephrase',
						'prompt' => 'Rephrase the following following: {text_input}',
					),
					array(
						'title'  => 'Make Shorter',
						'prompt' => 'Summarize or shorten the following: {text_input}',
					),
					array(
						'title'  => 'Make Longer',
						'prompt' => 'Expand or elaborate on the following: {text_input}',
					),
				),
				'show_in_rest'      => array(
					'schema' => array(
						'type'  => 'array',
						'items' => array(
							'type'       => 'object',
							'properties' => array(
								'title'  => array(
									'type' => 'string',
								),
								'prompt' => array(
									'type' => 'string',
								),
							),
						),
					),
				),
			)
		);

		register_setting(
			'themeisle_blocks_settings',
			Template_Cloud::SOURCES_SETTING_KEY,
			array(
				'type'              => 'array',
				'description'       => __( 'The template cloud sources from which patterns will be loaded.', 'otter-blocks' ),
				'sanitize_callback' => array( Template_Cloud_Server::class, 'sanitize_template_cloud_sources' ),
				'show_in_rest'      => array(
					'schema' => array(
						'type'  => 'array',
						'items' => array(
							'type'       => 'object',
							'properties' => array(
								'key'  => array(
									'type' => 'string',
								),
								'url'  => array(
									'type' => 'string',
								),
								'name' => array(
									'type' => 'string',
								),
							),
						),
					),
				),
				'default'           => array(),
			)
		);
	}

	/**
	 * Register post meta.
	 *
	 * @since  1.7.0
	 * @access public
	 * @link   https://developer.wordpress.org/reference/functions/register_meta/
	 */
	public function register_meta() {
		register_post_meta(
			'',
			'_themeisle_gutenberg_block_has_review',
			array(
				'show_in_rest'  => true,
				'single'        => true,
				'type'          => 'boolean',
				'auth_callback' => function () {
					return current_user_can( 'edit_posts' );
				},
			)
		);
	}

	/**
	 * Display Default Block
	 *
	 * @since   1.2.0
	 * @access  public
	 */
	public function default_block() {
		if ( ! get_option( 'themeisle_blocks_settings_default_block', false ) ) {
			return;
		}

		$attributes = array();

		$defaults = get_option( 'themeisle_blocks_settings_global_defaults' );
		if ( ! empty( $defaults ) ) {
			$defaults = json_decode( $defaults, true );

			if ( isset( $defaults['themeisle-blocks/advanced-columns'] ) ) {
				$attributes = $defaults['themeisle-blocks/advanced-columns'];
			}
		}

		$post_type_object           = get_post_type_object( 'page' );
		$post_type_object->template = array(
			array( 'themeisle-blocks/advanced-columns', $attributes ),
		);
	}

	/**
	 * Get allowed HTML for mail body.
	 *
	 * @static
	 * @access public
	 * @return array
	 */
	public static function get_allowed_mail_html() {
		$allowed_html = wp_kses_allowed_html( 'post' );

		$not_allowed_tags = array( 'input', 'label', 'form', 'select', 'textarea', 'button', 'fieldset', 'legend', 'datalist', 'output', 'option', 'optgroup', 'video', 'audio' );
		foreach ( $not_allowed_tags as $tag ) {
			unset( $allowed_html[ $tag ] );
		}

		return $allowed_html;
	}

	/**
	 * The instance method for the static class.
	 * Defines and returns the instance of the static class.
	 *
	 * @static
	 * @since 1.2.0
	 * @access public
	 * @return Options_Settings
	 */
	public static function instance() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
			self::$instance->init();
		}

		return self::$instance;
	}

	/**
	 * Throw error on object clone
	 *
	 * The whole idea of the singleton design pattern is that there is a single
	 * object therefore, we don't want the object to be cloned.
	 *
	 * @access public
	 * @since 1.2.0
	 * @return void
	 */
	public function __clone() {
		// Cloning instances of the class is forbidden.
		_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; huh?', 'otter-blocks' ), '1.0.0' );
	}

	/**
	 * Disable unserializing of the class
	 *
	 * @access public
	 * @since 1.2.0
	 * @return void
	 */
	public function __wakeup() {
		// Unserializing instances of the class is forbidden.
		_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; huh?', 'otter-blocks' ), '1.0.0' );
	}
}
