<?php
/**
 * Matador / Blocks
 *
 * @link        https://matadorjobs.com/
 * @since       4.0.0
 *
 * @package     Matador Jobs Board
 * @subpackage  Blocks
 * @author      Matador US LP, Jeremy Scott, Paul Bearne
 * @copyright   (c) 2024 Matador Software, LLC
 *
 * @license     http://opensource.org/licenses/gpl-3.0.php GNU Public License
 */

namespace matador\MatadorJobs\Editors\Blocks;

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

use matador\Matador;
use matador\MatadorJobs\Core\Logger;
use matador\MatadorJobs\Core\Severity;
use WP_Query;

/**
 * Class Blocks
 *
 * @since 4.0.0
 *
 * @final
 */
final class Blocks {
	/**
	 * Constructor
	 *
	 * @since    4.0.0
	 */
	public function __construct() {
		add_filter( 'block_categories_all', [ __CLASS__, 'register_block_category' ] );
		add_action( 'init', [ __CLASS__, 'blocks_init' ] );
		add_action( 'enqueue_block_editor_assets', [ __CLASS__, 'block_assets_scripts_enqueue' ] );
	}

	/**
	 * Register Matador Block Category
	 *
	 * @since 4.0.0
	 *
	 * @param array $categories - the existing block categories.
	 *
	 * @return array
	 */
	public static function register_block_category( array $categories ): array {
		$categories[] = [
			'slug'  => 'matador-jobs',
			'title' => 'Matador Jobs',
			'icon' => null,
		];

		return $categories;
	}

	/**
	 * Register Matador Blocks
	 *
	 * @since 4.0.0
	 *
	 * @return void
	 */
	public static function blocks_init(): void {

		// Register the Block Metadata Collection
		$base_path = __DIR__ . '/build/';
		if ( function_exists( 'wp_register_block_metadata_collection' ) && file_exists( $base_path . 'blocks-manifest.php' ) ) {
			\wp_register_block_metadata_collection(
				$base_path,
				$base_path . 'blocks-manifest.php'
			);
		}

		// Register each of the Blocks.
		$blocks_to_register = [
			'job-application',
			'job-application-link',
			'job-description',
			'job-field',
			'job-relative-age',
			'job-taxonomy-filters',
			'jobs-orderby',
			'jobs-search',
			'jobs-search-id',
			'jobs-search-keyword',
			'jobs-search-reset',
			'jobs-search-submit',
			'jobs-search-taxonomy',
		];

		foreach ( $blocks_to_register as $block_name ) {

			$args = apply_filters( "matador_block_{$block_name}_registration_args", [] );

			register_block_type_from_metadata( $base_path . $block_name, $args );
		}
	}

	/**
	 * Enqueue Block Assets Scripts
	 *
	 * The Jobs List block is actually a registered variation of the query loop, the API for registering variations
	 * only exists in JS, so we need to load the script that does this for us here
	 *
	 * @since 4.0.0
	 *
	 * @return void
	 */
	public static function block_assets_scripts_enqueue() : void {
		$block_asset_dependencies = [ 'wp-i18n', 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' ];

		$block_variants = [
			'matador-jobs-query-loop-variation'    => 'jobs-list.js',
			'matador-jobs-read-more-variation'     => 'job-link.js',
		];

		foreach ( $block_variants as $name => $path ) {
			wp_enqueue_script( $name, plugins_url( "build/$path", __FILE__ ), $block_asset_dependencies, '1.0.0', true );
		}
	}

	public static function generate_css_variables( array $css_var_mappings, \WP_Block $block ): string {

		if ( empty( $block->attributes ) && empty( $block->context ) ) {
			Logger::entry( 'blocks_css_variable_missing_block_data', __( 'Unable to generate css variables for block from given block data', 'matador-jobs' ), SEVERITY::ERROR, [ 'block_data' => $block ] );
			return '';
		}
		$block_attributes = $block->attributes;
		$block_context    = $block->context;

		$style = '';

		foreach ( $css_var_mappings as $attribute_key => $css_var ) {

			$css_value = $block_attributes[ $attribute_key ] ?? '';

			// If the value is blank, it may be coming from a parent block via context, so check for the value there.
			if ( ! empty( $block_context[ $attribute_key ] ) ) {
				$css_value = $block_context[ $attribute_key ];
			}

			if ( ! is_string( $css_value ) ) {
				// Attribute is using a complex data type, needs special treatment.
				switch ( $attribute_key ) {
					case 'inputPadding':
					case 'inputsPadding':
					case 'matador-jobs/searchFieldInputsPadding':
					case 'inputMargin':
					case 'inputsMargin':
					case 'matador-jobs/searchFieldInputsMargin':
					case 'labelsTextColor':
					case 'labelsPadding':
					case 'labelsMargin':
					case 'submitButtonPadding':
					case 'submitButtonMargin':
						foreach ( $css_var as $sub_key => $sub_var ) {
							$value = $block_attributes[ $attribute_key ][ $sub_key ] ?? $block_context[ $attribute_key ][ $sub_key ] ?? '';

							if ( ! empty( $value ) ) {
								$style .= $sub_var . ':' . esc_attr( $value ) . ';';
							}
						}
						break;
					case 'inputsBorders':
					case 'submitButtonBorders':
						foreach ( $css_var as $sub_key => $sub_var ) {
							$value = $block_attributes[ $attribute_key ][ $sub_key ] ?? $block_context[ $attribute_key ][ $sub_key ] ?? '';

							if ( ! empty( $value ) && is_array( $value ) ) {

								foreach ( $block_attributes[ $attribute_key ][ $sub_key ] as $border_att => $border_val ) {
									$style .= $sub_var . '-' . $border_att . ': ' . $border_val . ';';
								}
								continue;
							}

							if ( ! empty( $value ) && is_string( $value ) ) {
								$style .= $sub_var . ': ' . $value . ';';
							}
						}
						break;

					default:
						Logger::entry( 'blocks_css_variables_unhandled_attribute', __( 'Unhandled style attribute passed to block:', 'matador-jobs' ) . ' ' . $attribute_key, SEVERITY::NOTE, [ 'block' => $block->blockName ] );
						break;
				}
				continue; // skip to next iteration as $style variable properly updated.
			}

			if ( ! empty( $css_value ) ) {
				$style .= $css_var . ':' . esc_attr( $css_value ) . ';';
			}
		}

		return $style;
	}
}
