<?php
/**
 * Module: JetSmartFilters Date Range Filter.
 */
namespace Jet_Engine_Divi_Views\Components\Jet_Smart_Filters\Modules;

if ( ! defined( 'ABSPATH' ) ) {
	die( 'Direct access forbidden.' );
}

use ET\Builder\Framework\DependencyManagement\Interfaces\DependencyInterface;
use ET\Builder\Packages\ModuleLibrary\ModuleRegistration;
use ET\Builder\Packages\Module\Module;
use ET\Builder\FrontEnd\BlockParser\BlockParserStore;
use ET\Builder\FrontEnd\Module\Style;
use ET\Builder\Packages\Module\Options\Text\TextStyle;
use Jet_Engine_Divi_Views\Utils;

class Date_Range_Filter implements DependencyInterface {

	private static function get_default_settings() {

		return [
			'filter_id'         => 0,
			'content_provider'  => 'not-selected',
			'apply_type'        => 'ajax',
			'apply_on'          => 'value',
			'apply_button'      => true,
			'hide_apply_button' => false,
			'apply_button_text' => __( 'Apply filter', 'jet-smart-filters' ),
			'show_label'        => false,
			'query_id'          => '',
			'apply_indexer'     => false,
			'show_counter'      => false,
			'counter_prefix'    => '(',
			'counter_suffix'    => ')',
			'show_items_rule'   => 'show',
			'change_items_rule' => 'always',
		];
	}

	private static function normalize_toggle_value( $value ) {

		if ( is_bool( $value ) ) {
			return $value;
		}

		if ( is_numeric( $value ) ) {
			return (bool) absint( $value );
		}

		if ( ! is_string( $value ) ) {
			return $value;
		}

		$normalized = strtolower( trim( $value ) );

		if ( in_array( $normalized, [ 'on', 'true', 'yes' ], true ) ) {
			return true;
		}

		if ( in_array( $normalized, [ 'off', 'false', 'no', '' ], true ) ) {
			return false;
		}

		return $value;
	}

	private static function get_prepared_attrs( $attrs, $block ) {

		$prepared_attrs = [];

		foreach ( $attrs as $key => $value ) {
			if ( isset( $value['innerContent']['desktop']['value'] ) ) {
				$prepared_attrs[ $key ] = $value['innerContent']['desktop']['value'];
			}
		}

		$prepared_attrs = wp_parse_args( $prepared_attrs, self::get_default_settings() );

		foreach ( [
			'apply_button',
			'hide_apply_button',
			'show_label',
			'apply_indexer',
			'show_counter',
		] as $toggle_key ) {
			if ( array_key_exists( $toggle_key, $prepared_attrs ) ) {
				$prepared_attrs[ $toggle_key ] = self::normalize_toggle_value( $prepared_attrs[ $toggle_key ] );
			}
		}

		if ( empty( $prepared_attrs['blockID'] ) ) {
			$prepared_attrs['blockID'] = $block->parsed_block['id'] ?? '';
		}

		return $prepared_attrs;
	}

	/**
	 * Module's style components.
	 *
	 * This function is equivalent of JS function ModuleStyles located in
	 * module/styles.tsx.
	 *
	 * @param array $args {
	 *     An array of arguments.
	 *
	 *      @type string $id                Module ID. In VB, the ID of module is UUIDV4. In FE, the ID is order index.
	 *      @type string $name              Module name.
	 *      @type string $attrs             Module attributes.
	 *      @type string $parentAttrs       Parent attrs.
	 *      @type string $orderClass        Selector class name.
	 *      @type string $parentOrderClass  Parent selector class name.
	 *      @type string $wrapperOrderClass Wrapper selector class name.
	 *      @type string $settings          Custom settings.
	 *      @type string $state             Attributes state.
	 *      @type string $mode              Style mode.
	 *      @type ModuleElements $elements  ModuleElements instance.
	 * }
	 */
	public static function module_styles( $args ) {

		$elements                    = $args['elements'];
		$settings                    = $args['settings'] ?? [];
		$default_printed_style_attrs = $args['defaultPrintedStyleAttrs'] ?? [];
		$attrs                       = $args['attrs'] ?? [];
		$order_class                 = $args['orderClass'] ?? '';

		$block_id = $attrs['blockID']['innerContent']['desktop']['value'] ?? $attrs['blockID'] ?? '';
		$block_id = is_string( $block_id ) ? sanitize_html_class( $block_id ) : '';
		$popup = $block_id ? '.jet-smart-filters-datepicker-' . $block_id . '.ui-datepicker' : '.ui-datepicker';

		$selectors = [
			'filter_content'      => "{$order_class} .jet-date-range",
			'inputs'              => "{$order_class} .jet-date-range__inputs",
			'input'               => "{$order_class} .jet-date-range__inputs > input",
			'label'               => "{$order_class} .jet-filter-label",
			'apply_button'        => "{$order_class} .jet-date-range__submit.apply-filters__button",
			'calendar'            => $popup,
			'calendar_title'      => $popup . ' .ui-datepicker-title',
			'prev_span'           => $popup . '.ui-datepicker .ui-datepicker-prev > span',
			'next_span'           => $popup . '.ui-datepicker .ui-datepicker-next > span',
			'prev_hover_span'     => $popup . '.ui-datepicker .ui-datepicker-prev:hover > span',
			'next_hover_span'     => $popup . '.ui-datepicker .ui-datepicker-next:hover > span',
			'week_header'         => $popup . ' .ui-datepicker-calendar thead',
			'week_day'            => $popup . ' .ui-datepicker-calendar thead > tr > th',
			'week_day_content'    => $popup . ' .ui-datepicker-calendar thead > tr > th > span',
			'days_body'           => $popup . ' .ui-datepicker-calendar tbody',
			'day_cell'            => $popup . ' .ui-datepicker-calendar tbody > tr > td',
			'day_cell_first'      => $popup . ' .ui-datepicker-calendar tbody > tr > td:first-child',
			'day_cell_last'       => $popup . ' .ui-datepicker-calendar tbody > tr > td:last-child',
			'day_content'         => $popup . ' .ui-datepicker-calendar tbody > tr > td > span, ' . $popup . ' .ui-datepicker-calendar tbody > tr > td > a',
			'day_content_span'    => $popup . ' .ui-datepicker-calendar tbody > tr > td > span',
			'day_content_link'    => $popup . ' .ui-datepicker-calendar tbody > tr > td > a',
			'day_content_hover'   => $popup . ' .ui-datepicker-calendar tbody > tr > td > a:hover, ' . $popup . ' .ui-datepicker-calendar tbody > tr > td.ui-datepicker-today > a:hover',
			'day_content_active'  => $popup . ' .ui-datepicker-calendar tbody > tr > td > a.ui-state-active',
			'day_content_current' => $popup . ' .ui-datepicker-calendar tbody > tr > td.ui-datepicker-today > a, ' . $popup . ' .ui-datepicker-calendar tbody > tr > td.ui-datepicker-today > span',
		];

		$input_typography_styles = Utils\build_typography_styles( $selectors['input'], Utils\extract_typography_attrs( $attrs['module']['decoration']['inputTypography'] ?? null ) );
		$input_border_styles = Utils\build_border_styles( $selectors['input'], Utils\extract_border_attrs( $attrs['module']['decoration']['inputBorder'] ?? null ) );
		$input_spacing_styles = Utils\build_spacing_styles( $selectors['input'], Utils\extract_spasing_attrs( $attrs['module']['decoration']['inputSpacing'] ?? null ) );
		$calendar_typography_styles = Utils\build_typography_styles( $selectors['calendar'], Utils\extract_typography_attrs( $attrs['module']['decoration']['calendarTypography'] ?? null ) );
		$calendar_border_styles = Utils\build_border_styles( $selectors['calendar'], Utils\extract_border_attrs( $attrs['module']['decoration']['calendarBorder'] ?? null ) );
		$calendar_spacing_styles = Utils\build_spacing_styles( $selectors['calendar'], Utils\extract_spasing_attrs( $attrs['module']['decoration']['calendarSpacing'] ?? null ) );
		$calendar_caption_typography_styles = Utils\build_typography_styles( $selectors['calendar_title'], Utils\extract_typography_attrs( $attrs['module']['decoration']['calendarCaptionTypography'] ?? null ) );
		$week_header_border_styles = Utils\build_border_styles( $selectors['week_header'], Utils\extract_border_attrs( $attrs['module']['decoration']['calendarWeekHeaderBorder'] ?? null ) );
		$week_day_padding_styles = Utils\build_spacing_styles( $selectors['week_day'], Utils\extract_spasing_attrs( $attrs['module']['decoration']['calendarWeekDayPadding'] ?? null ) );
		$week_day_border_styles = Utils\build_border_styles( $selectors['week_day'], Utils\extract_border_attrs( $attrs['module']['decoration']['calendarWeekDayBorder'] ?? null ) );
		$week_day_typography_styles = Utils\build_typography_styles( $selectors['week_day_content'], Utils\extract_typography_attrs( $attrs['module']['decoration']['calendarWeekDayTypography'] ?? null ) );
		$week_day_content_border_styles = Utils\build_border_styles( $selectors['week_day_content'], Utils\extract_border_attrs( $attrs['module']['decoration']['calendarWeekDayContentBorder'] ?? null ) );
		$week_day_content_padding_styles = Utils\build_spacing_styles( $selectors['week_day_content'], Utils\extract_spasing_attrs( $attrs['module']['decoration']['calendarWeekDayContentPadding'] ?? null ) );
		$days_border_styles = Utils\build_border_styles( $selectors['days_body'], Utils\extract_border_attrs( $attrs['module']['decoration']['calendarDaysBorder'] ?? null ) );
		$day_padding_styles = Utils\build_spacing_styles( $selectors['day_cell'], Utils\extract_spasing_attrs( $attrs['module']['decoration']['calendarDayPadding'] ?? null ) );
		$day_border_styles = Utils\build_border_styles( $selectors['day_cell'], Utils\extract_border_attrs( $attrs['module']['decoration']['calendarDayBorder'] ?? null ) );
		$day_typography_styles = Utils\build_typography_styles( $selectors['day_content'], Utils\extract_typography_attrs( $attrs['module']['decoration']['calendarDayTypography'] ?? null ) );
		$day_content_border_styles = Utils\build_border_styles( $selectors['day_content'], Utils\extract_border_attrs( $attrs['module']['decoration']['calendarDayContentBorder'] ?? null ) );
		$day_content_padding_styles = Utils\build_spacing_styles( $selectors['day_content'], Utils\extract_spasing_attrs( $attrs['module']['decoration']['calendarDayContentPadding'] ?? null ) );
		$label_typography_styles = Utils\build_typography_styles( $selectors['label'], Utils\extract_typography_attrs( $attrs['module']['decoration']['labelTypography'] ?? null ) );
		$apply_typography_styles = Utils\build_typography_styles( $selectors['apply_button'], Utils\extract_typography_attrs( $attrs['module']['decoration']['applyTypography'] ?? null ) );
		$apply_border_styles = Utils\build_border_styles( $selectors['apply_button'], Utils\extract_border_attrs( $attrs['module']['decoration']['applyBorder'] ?? null ) );
		$apply_spacing_styles = Utils\build_spacing_styles( $selectors['apply_button'], Utils\extract_spasing_attrs( $attrs['module']['decoration']['applySpacing'] ?? null ) );

		$prev_next_size = $attrs['module']['decoration']['calendarPrevNextSize'] ?? null;
		$prev_next_size_prev = self::map_responsive_value( $prev_next_size, static function( $value ) {
			return "calc({$value} / 2) calc({$value} / 2) calc({$value} / 2) 0";
		} );
		$prev_next_size_next = self::map_responsive_value( $prev_next_size, static function( $value ) {
			return "calc({$value} / 2) 0 calc({$value} / 2) calc({$value} / 2)";
		} );
		Style::add(
			[
				'id'            => $args['id'],
				'name'          => $args['name'],
				'orderIndex'    => $args['orderIndex'],
				'storeInstance' => $args['storeInstance'],
				'styles'        => [
					$elements->style(
						[
							'attrName'   => 'module',
							'styleProps' => [
								'defaultPrintedStyleAttrs' => $default_printed_style_attrs['module']['decoration'] ?? [],
								'disabledOn'               => [
									'disabledModuleVisibility' => $settings['disabledModuleVisibility'] ?? null,
								],
								'advancedStyles' => array_merge(
									$input_typography_styles,
									$input_border_styles,
									$input_spacing_styles,
									$calendar_typography_styles,
									$calendar_border_styles,
									$calendar_spacing_styles,
									$calendar_caption_typography_styles,
									$week_header_border_styles,
									$week_day_padding_styles,
									$week_day_border_styles,
									$week_day_typography_styles,
									$week_day_content_border_styles,
									$week_day_content_padding_styles,
									$days_border_styles,
									$day_padding_styles,
									$day_border_styles,
									$day_typography_styles,
									$day_content_border_styles,
									$day_content_padding_styles,
									$label_typography_styles,
									$apply_typography_styles,
									$apply_border_styles,
									$apply_spacing_styles,
									[
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['filter_content'], 'attr' => $attrs['module']['decoration']['contentPosition'] ?? [], 'property' => 'display', 'declarationFunction' => static function( $args ) { return ! empty( $args['attrValue'] ) ? 'flex' : ''; } ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['filter_content'], 'attr' => $attrs['module']['decoration']['contentPosition'] ?? [], 'property' => 'flex-direction' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['filter_content'], 'attr' => $attrs['module']['decoration']['contentLineAlignment'] ?? [], 'property' => 'justify-content' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['filter_content'], 'attr' => $attrs['module']['decoration']['contentBlockAlignment'] ?? [], 'property' => 'align-items' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['inputs'], 'attr' => $attrs['module']['decoration']['inputWidth'] ?? [], 'property' => 'max-width' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['input'], 'attr' => $attrs['module']['decoration']['inputColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['input'] . '::placeholder', 'attr' => $attrs['module']['decoration']['inputColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['input'], 'attr' => $attrs['module']['decoration']['inputBackgroundColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['calendar'], 'attr' => $attrs['module']['decoration']['calendarVerOffset'] ?? [], 'property' => 'margin-top' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['calendar'], 'attr' => $attrs['module']['decoration']['calendarHorOffset'] ?? [], 'property' => 'margin-left' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['calendar'], 'attr' => $attrs['module']['decoration']['calendarWidth'] ?? [], 'property' => 'width' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['calendar'], 'attr' => $attrs['module']['decoration']['calendarBgColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['calendar_title'], 'attr' => $attrs['module']['decoration']['calendarCaptionColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['prev_span'], 'attr' => $prev_next_size_prev, 'property' => 'border-width' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['next_span'], 'attr' => $prev_next_size_next, 'property' => 'border-width' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['prev_span'], 'attr' => $attrs['module']['decoration']['calendarPrevNextNormalColor'] ?? [], 'property' => 'border-right-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['next_span'], 'attr' => $attrs['module']['decoration']['calendarPrevNextNormalColor'] ?? [], 'property' => 'border-left-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['prev_hover_span'], 'attr' => $attrs['module']['decoration']['calendarPrevNextHoverColor'] ?? [], 'property' => 'border-right-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['next_hover_span'], 'attr' => $attrs['module']['decoration']['calendarPrevNextHoverColor'] ?? [], 'property' => 'border-left-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['week_header'], 'attr' => $attrs['module']['decoration']['calendarWeekHeaderBgColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['week_day_content'], 'attr' => $attrs['module']['decoration']['calendarWeekDayColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['week_day_content'], 'attr' => $attrs['module']['decoration']['calendarWeekDayBgColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['days_body'], 'attr' => $attrs['module']['decoration']['calendarDaysBgColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_span'] . ', ' . $selectors['day_content_link'], 'attr' => $attrs['module']['decoration']['calendarDayDefaultColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_span'] . ', ' . $selectors['day_content_link'], 'attr' => $attrs['module']['decoration']['calendarDayDefaultBgColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_hover'], 'attr' => $attrs['module']['decoration']['calendarDayHoverColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_hover'], 'attr' => $attrs['module']['decoration']['calendarDayHoverBgColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_hover'], 'attr' => $attrs['module']['decoration']['calendarDayHoverBorderColor'] ?? [], 'property' => 'border-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_active'], 'attr' => $attrs['module']['decoration']['calendarDayActiveColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_active'], 'attr' => $attrs['module']['decoration']['calendarDayActiveBgColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_active'], 'attr' => $attrs['module']['decoration']['calendarDayActiveBorderColor'] ?? [], 'property' => 'border-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_current'], 'attr' => $attrs['module']['decoration']['calendarDayCurrentColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_current'], 'attr' => $attrs['module']['decoration']['calendarDayCurrentBgColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['day_content_current'], 'attr' => $attrs['module']['decoration']['calendarDayCurrentBorderColor'] ?? [], 'property' => 'border-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['label'], 'attr' => $attrs['module']['decoration']['labelAlignment'] ?? [], 'property' => 'text-align' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['label'], 'attr' => $attrs['module']['decoration']['labelColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['label'], 'attr' => $attrs['module']['decoration']['labelGapY'] ?? [], 'property' => 'margin-bottom' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['apply_button'], 'attr' => $attrs['module']['decoration']['applyNormalColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['apply_button'], 'attr' => $attrs['module']['decoration']['applyNormalBgColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['apply_button'] . ':hover', 'attr' => $attrs['module']['decoration']['applyHoverColor'] ?? [], 'property' => 'color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['apply_button'] . ':hover', 'attr' => $attrs['module']['decoration']['applyHoverBgColor'] ?? [], 'property' => 'background-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['apply_button'] . ':hover', 'attr' => $attrs['module']['decoration']['applyHoverBorderColor'] ?? [], 'property' => 'border-color' ] ],
										[ 'componentName' => 'divi/common', 'props' => [ 'selector' => $selectors['apply_button'], 'attr' => $attrs['module']['decoration']['applyAlignment'] ?? [], 'property' => 'align-self' ] ],
									]
								),
							],
						]
					),
				],
			]
		);
	}

	private static function map_responsive_value( $attr, callable $callback ) {

		if ( ! is_array( $attr ) ) {
			return [];
		}

		$result = [];

		foreach ( $attr as $device => $value ) {
			$raw = $value['value'] ?? $value['default'] ?? null;

			if ( null === $raw || '' === $raw ) {
				continue;
			}

			$result[ $device ] = [
				'default' => $callback( $raw ),
			];
		}

		return $result;
	}

	/**
	 * Set script data of used module options.
	 *
	 * @since ??
	 *
	 * @param array $args {
	 *   Array of arguments.
	 *
	 *   @type string $id       Module id.
	 *   @type string $selector Module selector.
	 *   @type array  $attrs    Module attributes.
	 * }
	 */
	public static function module_script_data( $args ) {
	}

	/**
	 * Module classnames function for Dynamic module.
	 *
	 * This function is equivalent of JS function moduleClassnames located in
	 * src/components/dynamic-module/module-classnames.ts.
	 *
	 * @since ??
	 *
	 * @param array $args {
	 *     An array of arguments.
	 *
	 *     @type object $classnamesInstance Instance of ET\Builder\Packages\Module\Layout\Components\Classnames.
	 *     @type array  $attrs              Block attributes data that being rendered.
	 * }
	 */
	public static function module_classnames( $args ) {
	}

	/**
	 * Dynamic module render callback which outputs server side rendered HTML on the Front-End.
	 *
	 * @since ??
	 *
	 * @param array          $attrs    Block attributes that were saved by VB.
	 * @param string         $content  Block content.
	 * @param \WP_Block      $block    Parsed block object that being rendered.
	 * @param ModuleElements $elements ModuleElements instance.
	 *
	 * @return string HTML rendered of module.
	 */
	public static function render_callback( $attrs, $content, $block, $elements ) {

		$prepared_attrs = self::get_prepared_attrs( $attrs, $block );

		$parent       = BlockParserStore::get_parent( $block->parsed_block['id'], $block->parsed_block['storeInstance'] );
		$parent_attrs = $parent->attrs ?? [];

		$filters_block_type = jet_smart_filters()->blocks->get_block_type( 'date-range' );

		$content = $filters_block_type->render_callback( $prepared_attrs );

		return Module::render(
			[
				// FE only.
				'orderIndex'          => $block->parsed_block['orderIndex'],
				'storeInstance'       => $block->parsed_block['storeInstance'],

				// VB equivalent.
				'id'                  => $block->parsed_block['id'],
				'name'                => $block->block_type->name,
				'moduleCategory'      => $block->block_type->category,
				'attrs'               => $attrs,
				'elements'            => $elements,
				'classnamesFunction'  => [ Date_Range_Filter::class, 'module_classnames' ],
				'stylesComponent'     => [ Date_Range_Filter::class, 'module_styles' ],
				'scriptDataComponent' => [ Date_Range_Filter::class, 'module_script_data' ],
				'parentAttrs'         => $parent_attrs,
				'parentId'            => $parent->id ?? '',
				'parentName'          => $parent->blockName ?? '',
				'children'            => [ $content ],
			]
		);
	}

	/**
	 * Get JetEngine render class instance
	 */
	public static function get_jet_engine_render_instance( $attributes ) {
		return jet_engine()->listings->get_render_instance( self::get_jet_engine_render_name(), $attributes );
	}

	/**
	 * Return name of JetEngine renderer for current module
	 */
	public static function get_jet_engine_render_name() {
		return 'dynamic-field';
	}

	/**
	 * Loads `DynamicField` and registers Front-End render callback and REST API Endpoints.
	 *
	 * @since ??
	 *
	 * @return void
	 */
	public function load() {

		$module_json_folder_path = JET_ENGINE_DIVI_VIEWS_MODULES_JSON_PATH . 'date-range-filter/';

		add_action(
			'init',
			function() use ( $module_json_folder_path ) {
				ModuleRegistration::register_module(
					$module_json_folder_path,
					[
						'render_callback' => [ Date_Range_Filter::class, 'render_callback' ],
					]
				);
			}
		);
	}
}
