<?php
/**
 * Handle Gutenberg blocks.
 *
 * @package YITH\DynamicPricingAndDiscounts\Classes
 */

defined( 'ABSPATH' ) || exit;

if ( ! class_exists( 'YWDPD_Gutenberg' ) ) {
	/**
	 * Gutenberg class
	 *
	 * @since 3.0.0
	 */
	class YWDPD_Gutenberg {
		use YWDPD_Singleton_Trait;

		/**
		 * Blocks
		 *
		 * @var array
		 */
		private $blocks = array();

		/**
		 * YITH_WCBK_Gutenberg constructor.
		 */
		private function __construct() {
			global $wp_version;

			$this->load();
			add_action( 'init', array( $this, 'init' ) );
			$categories_hook = version_compare( $wp_version, '5.8', '>=' ) ? 'block_categories_all' : 'block_categories';
			add_filter( $categories_hook, array( $this, 'block_category' ), 100, 2 );
			add_filter( 'pre_load_script_translations', array( $this, 'script_translations' ), 10, 4 );
		}

		/**
		 * Load classes.
		 */
		private function load() {
			require_once YITH_YWDPD_INC . '/builders/gutenberg/render/abstract-ywdpd-render-block.php';
			require_once YITH_YWDPD_INC . '/builders/gutenberg/render/class-ywdpd-dynamic-rule-products-block.php';
		}

		/**
		 * Init Gutenberg blocks
		 */
		public function init() {
			$asset_file = include YITH_YWDPD_DIR . 'assets/js/gutenberg/index.asset.php';

			wp_register_script(
				'ywdpd-gutenberg-blocks',
				YITH_YWDPD_ASSETS_URL . '/js/gutenberg/index.js',
				$asset_file['dependencies'],
				$asset_file['version'],
				true
			);

			wp_register_style(
				'ywdpd-block-components',
				YITH_YWDPD_ASSETS_URL . '/js/gutenberg/style-index.css',
				array(),
				YITH_YWDPD_VERSION
			);

			$products_per_row = absint( wc_get_default_products_per_row() );

			register_block_type(
				'yith/ywdpd-dynamic-rules',
				array(
					'render_callback' => array( $this, 'render_dynamic_discounted_products' ),
					'editor_script'   => 'ywdpd-gutenberg-blocks',
					'editor_style'    => 'ywdpd-block-components',
					'style'           => array( 'wc-blocks-style' ),
					'attributes'      => array(
						'contentVisibility' => array(
							'type'       => 'object',
							'properties' => array(
								'image'  => array(
									'type'    => 'boolean',
									'default' => true,
								),
								'title'  => array(
									'type'    => 'boolean',
									'default' => true,
								),
								'price'  => array(
									'type'    => 'boolean',
									'default' => true,
								),
								'rating' => array(
									'type'    => 'boolean',
									'default' => true,
								),
								'button' => array(
									'type'    => 'boolean',
									'default' => true,
								),
							),
						),
						'columns'           => array(
							'type'    => 'number',
							'default' => $products_per_row,
						),
						'rows'              => array(
							'type'    => 'number',
							'default' => 1,
						),
						'includeAll'        => array(
							'type'    => 'boolean',
							'default' => true,
						),
						'ruleType'          => array(
							'type'    => 'string',
							'default' => '',
						),
						'ruleIds'           => array(
							'type'    => 'array',
							'default' => array(),
						),
					),
					'supports'        => array(
						'multiple' => false,
					),
				)
			);
			wp_localize_script(
				'ywdpd-gutenberg-blocks',
				'ywdpdBlocks',
				array(
					'siteURL'               => get_site_url(),
					'defaultProductsPerRow' => $products_per_row,
					'ruleCount'             => array_sum( (array) wp_count_posts( 'ywdpd_discount' ) ),
				)
			);
			wp_set_script_translations( 'ywdpd-gutenberg-blocks', 'ywdpd', plugin_basename( YITH_YWDPD_DIR ) . '/languages' );
		}

		/**
		 * Render the booking products block.
		 *
		 * @param array $attributes Attributes.
		 *
		 * @return string
		 * @throws Exception The exception.
		 */
		public function render_dynamic_discounted_products( $attributes ) {
			$block_renderer = new YWDPD_Dynamic_Rule_Products_Block( $attributes );
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended
			if ( ( isset( $_REQUEST['action'] ) && 'edit' === $_REQUEST['action'] ) || ( isset( $_REQUEST['context'] ) && 'edit' === $_REQUEST['context'] ) ) {
				$block_renderer->set_is_preview( true );
				$block_renderer->set_allow_blank_state( true );
			}
			ob_start();

			$block_renderer->render();

			return ob_get_clean();
		}

		/**
		 * Add YITH Category
		 *
		 * @param array   $categories Block categories array.
		 * @param WP_Post $post The current post.
		 *
		 * @return array block categories
		 */
		public function block_category( $categories, $post ) {
			$found_key = array_search( 'yith-blocks', array_column( $categories, 'slug' ), true );

			if ( ! $found_key ) {
				$categories[] = array(
					'slug'  => 'yith-blocks',
					'title' => 'YITH',
				);
			}

			return $categories;
		}

		/**
		 * Create the json translation through the PHP file.
		 * So, it's possible using normal translations (with PO files) also for JS translations
		 *
		 * @param string|null $json_translations Translations.
		 * @param string      $file The file.
		 * @param string      $handle The handle.
		 * @param string      $domain The text-domain.
		 *
		 * @return string|null
		 */
		public function script_translations( $json_translations, $file, $handle, $domain ) {
			if ( 'ywdpd' === $domain ) {

				if ( 'ywdpd-gutenberg-blocks' === $handle ) {
					$path = trailingslashit( YITH_YWDPD_DIR . 'languages/' ) . 'gutenberg-i18n.php';
					if ( file_exists( $path ) ) {
						$translations = include $path;

						$json_translations = wp_json_encode(
							array(
								'domain'      => 'ywdpd',
								'locale_data' => array(
									'messages' =>
										array(
											'' => array(
												'domain'       => 'ywdpd',
												'lang'         => get_locale(),
												'plural-forms' => 'nplurals=2; plural=(n != 1);',
											),
										)
										+
										$translations,
								),
							)
						);

					}
				}
			}

			return $json_translations;
		}

	}
}
