<?php
/**
 * Module: JetEngine Maps Listing.
 */
namespace Jet_Engine_Divi_Views\Components\Jet_Engine\Modules;

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

use ET\Builder\Framework\DependencyManagement\Interfaces\DependencyInterface;
use ET\Builder\Packages\ModuleLibrary\ModuleRegistration;
use Jet_Engine_Divi_Views\Module_Render;
use ET\Builder\FrontEnd\Module\Style;
use Jet_Engine_Divi_Views\Utils;

class Maps_Listing implements DependencyInterface {

	/**
	 * Module styles callback.
	 */
	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'] ?? '';

		$selectors = [
			'popup_pin'                     => "{$order_class} .popup-has-pin .jet-map-box:after",
			'popup_preloader'               => "{$order_class} .jet-map-preloader.is-active",
			'popup_loader'                  => "{$order_class} .jet-map-preloader.is-active .jet-map-loader",
			'marker_wrap'                   => "{$order_class} .jet-map-marker-wrap",
			'marker_wrap_after'             => "{$order_class} .jet-map-marker-wrap:after",
			'marker_wrap_hover'             => "{$order_class} .jet-map-marker-wrap:hover",
			'marker_wrap_hover_after'       => "{$order_class} .jet-map-marker-wrap:hover:after",
			'marker'                        => "{$order_class} .jet-map-marker",
			'marker_path'                   => "{$order_class} .jet-map-marker path",
			'marker_no_color'               => "{$order_class} .jet-map-marker:not(.keep-color, .custom-color)",
			'marker_no_color_path'          => "{$order_class} .jet-map-marker:not(.keep-color, .custom-color) path",
			'marker_image'                  => "{$order_class} .jet-map-marker-image",
			'cluster_text'                  => "{$order_class} .cluster span, {$order_class} .marker-cluster span",
			'user_location_marker_wrap'     => "{$order_class} .jet-map-user-location-marker-wrap",
			'user_location_marker_wrap_after' => "{$order_class} .jet-map-user-location-marker-wrap:after",
			'user_location_marker_wrap_hover' => "{$order_class} .jet-map-user-location-marker-wrap:hover",
			'user_location_marker_wrap_hover_after' => "{$order_class} .jet-map-user-location-marker-wrap:hover:after",
			'user_location_marker'          => "{$order_class} .jet-map-user-location-marker",
			'user_location_marker_path'     => "{$order_class} .jet-map-user-location-marker path",
			'user_location_marker_no_color' => "{$order_class} .jet-map-user-location-marker:not(.keep-color, .custom-color)",
			'user_location_marker_no_color_path' => "{$order_class} .jet-map-user-location-marker:not(.keep-color, .custom-color) path",
			'user_location_marker_image'    => "{$order_class} .jet-map-user-location-marker-image",
		];

		$marker_typography = Utils\extract_typography_attrs( $attrs['module']['decoration']['markerTypography'] ?? null );
		$marker_typography_styles = Utils\build_typography_styles( $selectors['marker_wrap'], $marker_typography );
		$marker_border = Utils\extract_border_attrs( $attrs['module']['decoration']['markerBorder'] ?? null );
		$marker_border_styles = Utils\build_border_styles( $selectors['marker_wrap'], $marker_border );
		$marker_spacing = Utils\extract_spasing_attrs( $attrs['module']['decoration']['markerSpacing'] ?? null );
		$marker_spacing_styles = Utils\build_spacing_styles( $selectors['marker_wrap'], $marker_spacing );
		$cluster_typography = Utils\extract_typography_attrs( $attrs['module']['decoration']['markerClusterTypography'] ?? null );
		$cluster_typography_styles = Utils\build_typography_styles( $selectors['cluster_text'], $cluster_typography );

		$user_marker_typography = Utils\extract_typography_attrs( $attrs['module']['decoration']['userLocationMarkerTypography'] ?? null );
		$user_marker_typography_styles = Utils\build_typography_styles( $selectors['user_location_marker_wrap'], $user_marker_typography );
		$user_marker_border = Utils\extract_border_attrs( $attrs['module']['decoration']['userLocationMarkerBorder'] ?? null );
		$user_marker_border_styles = Utils\build_border_styles( $selectors['user_location_marker_wrap'], $user_marker_border );
		$user_marker_spacing = Utils\extract_spasing_attrs( $attrs['module']['decoration']['userLocationMarkerSpacing'] ?? null );
		$user_marker_spacing_styles = Utils\build_spacing_styles( $selectors['user_location_marker_wrap'], $user_marker_spacing );

		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(
									$marker_typography_styles,
									$marker_border_styles,
									$marker_spacing_styles,
									$cluster_typography_styles,
									$user_marker_typography_styles,
									$user_marker_border_styles,
									$user_marker_spacing_styles,
									[
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'margin',
												'selector' => $selectors['popup_pin'],
												'attr'     => $attrs['module']['decoration']['popupPinSize'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'border-width',
												'selector' => $selectors['popup_pin'],
												'attr'     => $attrs['module']['decoration']['popupPinSize'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'border-color',
												'selector' => $selectors['popup_pin'],
												'attr'     => $attrs['module']['decoration']['popupPinColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'background-color',
												'selector' => $selectors['popup_preloader'],
												'attr'     => $attrs['module']['decoration']['popupPreloaderBgColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'color',
												'selector' => $selectors['popup_loader'],
												'attr'     => $attrs['module']['decoration']['popupPreloaderColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'height',
												'selector' => $selectors['popup_preloader'],
												'attr'     => $attrs['module']['decoration']['popupPreloaderHeight'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'width',
												'selector' => $selectors['marker_wrap'],
												'attr'     => $attrs['module']['decoration']['markerWidth'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'width',
												'selector' => $selectors['marker_image'],
												'attr'     => $attrs['module']['decoration']['markerWidth'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'font-size',
												'selector' => $selectors['marker'],
												'attr'     => $attrs['module']['decoration']['markerIconSize'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'color',
												'selector' => $selectors['marker_wrap'],
												'attr'     => $attrs['module']['decoration']['markerColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'background-color',
												'selector' => $selectors['marker_wrap'],
												'attr'     => $attrs['module']['decoration']['markerBgColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'border-color',
												'selector' => $selectors['marker_wrap_after'],
												'attr'     => $attrs['module']['decoration']['markerBgColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'color',
												'selector' => $selectors['marker_no_color'],
												'attr'     => $attrs['module']['decoration']['markerIconColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'fill',
												'selector' => $selectors['marker_no_color_path'],
												'attr'     => $attrs['module']['decoration']['markerIconColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'color',
												'selector' => $selectors['marker_wrap_hover'],
												'attr'     => $attrs['module']['decoration']['markerColorHover'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'background-color',
												'selector' => $selectors['marker_wrap_hover'],
												'attr'     => $attrs['module']['decoration']['markerBgColorHover'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'border-color',
												'selector' => $selectors['marker_wrap_hover_after'],
												'attr'     => $attrs['module']['decoration']['markerBgColorHover'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'color',
												'selector' => $selectors['marker'],
												'attr'     => $attrs['module']['decoration']['markerIconColorHover'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'fill',
												'selector' => $selectors['marker_path'],
												'attr'     => $attrs['module']['decoration']['markerIconColorHover'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'text-align',
												'selector' => $selectors['marker_wrap'],
												'attr'     => $attrs['module']['decoration']['markerAlignment'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'margin',
												'selector' => $selectors['marker_wrap_after'],
												'attr'     => $attrs['module']['decoration']['markerPinSize'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'border-width',
												'selector' => $selectors['marker_wrap_after'],
												'attr'     => $attrs['module']['decoration']['markerPinSize'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'margin-bottom',
												'selector' => $selectors['marker_wrap'],
												'attr'     => $attrs['module']['decoration']['markerPinSize'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'color',
												'selector' => $selectors['cluster_text'],
												'attr'     => $attrs['module']['decoration']['markerClusterTextColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'width',
												'selector' => $selectors['user_location_marker_wrap'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerWidth'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'width',
												'selector' => $selectors['user_location_marker_image'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerWidth'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'font-size',
												'selector' => $selectors['user_location_marker'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerIconSize'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'color',
												'selector' => $selectors['user_location_marker_wrap'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'background-color',
												'selector' => $selectors['user_location_marker_wrap'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerBgColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'border-color',
												'selector' => $selectors['user_location_marker_wrap_after'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerBgColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'color',
												'selector' => $selectors['user_location_marker_no_color'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerIconColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'fill',
												'selector' => $selectors['user_location_marker_no_color_path'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerIconColor'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'color',
												'selector' => $selectors['user_location_marker_wrap_hover'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerColorHover'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'background-color',
												'selector' => $selectors['user_location_marker_wrap_hover'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerBgColorHover'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'border-color',
												'selector' => $selectors['user_location_marker_wrap_hover_after'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerBgColorHover'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'color',
												'selector' => $selectors['user_location_marker'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerIconColorHover'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'fill',
												'selector' => $selectors['user_location_marker_path'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerIconColorHover'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'margin',
												'selector' => $selectors['user_location_marker_wrap_after'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerPinSize'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'border-width',
												'selector' => $selectors['user_location_marker_wrap_after'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerPinSize'] ?? [],
											],
										],
										[
											'componentName' => 'divi/common',
											'props'         => [
												'property' => 'margin-bottom',
												'selector' => $selectors['user_location_marker_wrap'],
												'attr'     => $attrs['module']['decoration']['userLocationMarkerPinSize'] ?? [],
											],
										],
									]
								),
							],
						]
					),
				],
			]
		);
	}

	/**
	 * Set script data of used module options.
	 */
	public static function module_script_data( $args ) {
	}

	/**
	 * Module classnames callback.
	 */
	public static function module_classnames( $args ) {
	}

	/**
	 * Render callback.
	 */
	public static function render_callback( $attrs, $content, $block, $elements ) {

		$prepared_attrs = [];

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

		$normalize_toggle = function ( $value ) {
			if ( true === $value || 1 === $value || '1' === $value || 'true' === $value || 'yes' === $value || 'on' === $value ) {
				return true;
			}

			if ( false === $value || 0 === $value || '0' === $value || '' === $value || null === $value || 'false' === $value || 'no' === $value || 'off' === $value ) {
				return false;
			}

			return (bool) $value;
		};

		$decode_json_array = function ( $value ) {
			if ( is_array( $value ) ) {
				return $value;
			}

			if ( ! is_string( $value ) || '' === trim( $value ) ) {
				return [];
			}

			$decoded = json_decode( wp_unslash( $value ), true );

			return is_array( $decoded ) ? $decoded : [];
		};

		$normalize_media_pair = function ( $id_key, $url_key ) use ( &$prepared_attrs ) {
			if ( ! empty( $prepared_attrs[ $url_key ] ) && is_array( $prepared_attrs[ $url_key ] ) ) {
				if ( isset( $prepared_attrs[ $url_key ]['url'] ) ) {
					$prepared_attrs[ $url_key ] = $prepared_attrs[ $url_key ]['url'];
				}
			}

			if ( ! empty( $prepared_attrs[ $id_key ] ) && is_array( $prepared_attrs[ $id_key ] ) ) {
				if ( isset( $prepared_attrs[ $id_key ]['id'] ) ) {
					$prepared_attrs[ $id_key ] = absint( $prepared_attrs[ $id_key ]['id'] );
				} elseif ( isset( $prepared_attrs[ $id_key ]['url'] ) ) {
					$prepared_attrs[ $url_key ] = $prepared_attrs[ $id_key ]['url'];
					$prepared_attrs[ $id_key ]  = 0;
				}
			}

			if ( ! empty( $prepared_attrs[ $id_key ] ) && is_string( $prepared_attrs[ $id_key ] ) ) {
				$media_string = trim( $prepared_attrs[ $id_key ] );

				if ( filter_var( $media_string, FILTER_VALIDATE_URL ) ) {
					$prepared_attrs[ $url_key ] = $media_string;
					$prepared_attrs[ $id_key ]  = 0;
				} elseif ( is_numeric( $media_string ) ) {
					$prepared_attrs[ $id_key ] = absint( $media_string );
				}
			}

			if ( ! empty( $prepared_attrs[ $id_key ] ) && empty( $prepared_attrs[ $url_key ] ) ) {
				$media_url = wp_get_attachment_url( absint( $prepared_attrs[ $id_key ] ) );

				if ( $media_url ) {
					$prepared_attrs[ $url_key ] = $media_url;
				}
			}

			if ( empty( $prepared_attrs[ $id_key ] ) && ! empty( $prepared_attrs[ $url_key ] ) && is_string( $prepared_attrs[ $url_key ] ) ) {
				$attachment_id = attachment_url_to_postid( $prepared_attrs[ $url_key ] );

				if ( $attachment_id ) {
					$prepared_attrs[ $id_key ] = absint( $attachment_id );
				}
			}
		};

		$prepared_attrs['lisitng_id']                           = $prepared_attrs['lisitng_id'] ?? '';
		$prepared_attrs['address_field']                        = $prepared_attrs['address_field'] ?? '';
		$prepared_attrs['add_lat_lng']                          = isset( $prepared_attrs['add_lat_lng'] ) ? $normalize_toggle( $prepared_attrs['add_lat_lng'] ) : false;
		$prepared_attrs['lat_lng_address_field']                = $prepared_attrs['lat_lng_address_field'] ?? '';
		$prepared_attrs['map_height']                           = isset( $prepared_attrs['map_height'] ) ? absint( $prepared_attrs['map_height'] ) : 500;
		$prepared_attrs['posts_num']                            = isset( $prepared_attrs['posts_num'] ) ? absint( $prepared_attrs['posts_num'] ) : 6;
		$prepared_attrs['auto_center']                          = isset( $prepared_attrs['auto_center'] ) ? $normalize_toggle( $prepared_attrs['auto_center'] ) : true;
		$prepared_attrs['max_zoom']                             = '' !== ( $prepared_attrs['max_zoom'] ?? '' ) ? absint( $prepared_attrs['max_zoom'] ) : null;
		$prepared_attrs['min_zoom']                             = '' !== ( $prepared_attrs['min_zoom'] ?? '' ) ? absint( $prepared_attrs['min_zoom'] ) : null;
		$prepared_attrs['custom_center']                        = $prepared_attrs['custom_center'] ?? '';
		$prepared_attrs['custom_zoom']                          = isset( $prepared_attrs['custom_zoom'] ) ? absint( $prepared_attrs['custom_zoom'] ) : 11;
		$prepared_attrs['custom_style']                         = $prepared_attrs['custom_style'] ?? '';
		$prepared_attrs['zoom_control']                         = $prepared_attrs['zoom_control'] ?? 'auto';
		$prepared_attrs['zoom_controls']                        = isset( $prepared_attrs['zoom_controls'] ) ? $normalize_toggle( $prepared_attrs['zoom_controls'] ) : true;
		$prepared_attrs['fullscreen_control']                   = isset( $prepared_attrs['fullscreen_control'] ) ? $normalize_toggle( $prepared_attrs['fullscreen_control'] ) : true;
		$prepared_attrs['street_view_controls']                 = isset( $prepared_attrs['street_view_controls'] ) ? $normalize_toggle( $prepared_attrs['street_view_controls'] ) : true;
		$prepared_attrs['map_type_controls']                    = isset( $prepared_attrs['map_type_controls'] ) ? $normalize_toggle( $prepared_attrs['map_type_controls'] ) : true;
		$prepared_attrs['centering_on_open']                    = isset( $prepared_attrs['centering_on_open'] ) ? $normalize_toggle( $prepared_attrs['centering_on_open'] ) : false;
		$prepared_attrs['zoom_on_open']                         = '' !== ( $prepared_attrs['zoom_on_open'] ?? '' ) ? absint( $prepared_attrs['zoom_on_open'] ) : null;
		$prepared_attrs['marker_type']                          = $prepared_attrs['marker_type'] ?? 'icon';
		$prepared_attrs['marker_icon']                          = isset( $prepared_attrs['marker_icon'] ) ? absint( $prepared_attrs['marker_icon'] ) : 0;
		$prepared_attrs['marker_icon_url']                      = $prepared_attrs['marker_icon_url'] ?? '';
		$prepared_attrs['marker_image_field']                   = $prepared_attrs['marker_image_field'] ?? '';
		$prepared_attrs['marker_image_size']                    = $prepared_attrs['marker_image_size'] ?? 'full';
		$prepared_attrs['marker_image_field_custom']            = $prepared_attrs['marker_image_field_custom'] ?? '';
		$prepared_attrs['marker_icon_color_apply_to']           = $prepared_attrs['marker_icon_color_apply_to'] ?? 'keep_jsm';
		$prepared_attrs['marker_label_type']                    = $prepared_attrs['marker_label_type'] ?? 'post_title';
		$prepared_attrs['marker_label_field']                   = $prepared_attrs['marker_label_field'] ?? '';
		$prepared_attrs['marker_label_field_custom']            = $prepared_attrs['marker_label_field_custom'] ?? '';
		$prepared_attrs['marker_label_text']                    = $prepared_attrs['marker_label_text'] ?? '';
		$prepared_attrs['marker_label_format_cb']               = $prepared_attrs['marker_label_format_cb'] ?? '';
		$prepared_attrs['marker_label_custom']                  = isset( $prepared_attrs['marker_label_custom'] ) ? $normalize_toggle( $prepared_attrs['marker_label_custom'] ) : false;
		$prepared_attrs['marker_label_custom_output']           = $prepared_attrs['marker_label_custom_output'] ?? '%s';
		$prepared_attrs['multiple_marker_types']                = isset( $prepared_attrs['multiple_marker_types'] ) ? $normalize_toggle( $prepared_attrs['multiple_marker_types'] ) : false;
		$prepared_attrs['multiple_markers']                     = $decode_json_array( $prepared_attrs['multiple_markers'] ?? [] );
		$prepared_attrs['marker_clustering']                    = isset( $prepared_attrs['marker_clustering'] ) ? $normalize_toggle( $prepared_attrs['marker_clustering'] ) : true;
		$prepared_attrs['cluster_max_zoom']                     = '' !== ( $prepared_attrs['cluster_max_zoom'] ?? '' ) ? absint( $prepared_attrs['cluster_max_zoom'] ) : null;
		$prepared_attrs['cluster_radius']                       = '' !== ( $prepared_attrs['cluster_radius'] ?? '' ) ? absint( $prepared_attrs['cluster_radius'] ) : null;
		$prepared_attrs['is_custom_marker_cluster_images']      = isset( $prepared_attrs['is_custom_marker_cluster_images'] ) ? $normalize_toggle( $prepared_attrs['is_custom_marker_cluster_images'] ) : false;
		$prepared_attrs['marker_cluster_images']                = $decode_json_array( $prepared_attrs['marker_cluster_images'] ?? [] );
		$prepared_attrs['user_location_enabled']                = isset( $prepared_attrs['user_location_enabled'] ) ? $normalize_toggle( $prepared_attrs['user_location_enabled'] ) : false;
		$prepared_attrs['user_location_marker_icon_color']      = $prepared_attrs['user_location_marker_icon_color'] ?? '';
		$prepared_attrs['user_location_marker_icon_color_apply_to'] = $prepared_attrs['user_location_marker_icon_color_apply_to'] ?? 'keep';
		$prepared_attrs['user_location_marker_type']            = $prepared_attrs['user_location_marker_type'] ?? 'text';
		$prepared_attrs['user_location_marker_label_text']      = $prepared_attrs['user_location_marker_label_text'] ?? 'Your Location';
		$prepared_attrs['user_location_marker_icon']            = isset( $prepared_attrs['user_location_marker_icon'] ) ? absint( $prepared_attrs['user_location_marker_icon'] ) : 0;
		$prepared_attrs['user_location_marker_icon_url']        = $prepared_attrs['user_location_marker_icon_url'] ?? '';
		$prepared_attrs['user_location_marker_image_size']      = $prepared_attrs['user_location_marker_image_size'] ?? '';
		$prepared_attrs['popup_width']                          = isset( $prepared_attrs['popup_width'] ) ? absint( $prepared_attrs['popup_width'] ) : 320;
		$prepared_attrs['popup_offset']                         = isset( $prepared_attrs['popup_offset'] ) ? absint( $prepared_attrs['popup_offset'] ) : 40;
		$prepared_attrs['popup_pin']                            = isset( $prepared_attrs['popup_pin'] ) ? $normalize_toggle( $prepared_attrs['popup_pin'] ) : false;
		$prepared_attrs['popup_preloader']                      = isset( $prepared_attrs['popup_preloader'] ) ? $normalize_toggle( $prepared_attrs['popup_preloader'] ) : false;
		$prepared_attrs['popup_open_on']                        = $prepared_attrs['popup_open_on'] ?? 'click';
		$prepared_attrs['custom_query']                         = isset( $prepared_attrs['custom_query'] ) ? $normalize_toggle( $prepared_attrs['custom_query'] ) : false;
		$prepared_attrs['custom_query_id']                      = $prepared_attrs['custom_query_id'] ?? '';
		$prepared_attrs['posts_query']                          = $decode_json_array( $prepared_attrs['posts_query'] ?? [] );
		$prepared_attrs['meta_query_relation']                  = $prepared_attrs['meta_query_relation'] ?? 'AND';
		$prepared_attrs['tax_query_relation']                   = $prepared_attrs['tax_query_relation'] ?? 'AND';
		$prepared_attrs['hide_widget_if']                       = $prepared_attrs['hide_widget_if'] ?? '';

		$normalize_media_pair( 'marker_icon', 'marker_icon_url' );
		$normalize_media_pair( 'user_location_marker_icon', 'user_location_marker_icon_url' );

		if ( empty( $prepared_attrs['_block_id'] ) ) {
			$prepared_attrs['_block_id'] = ! empty( $block->parsed_block['id'] ) ? $block->parsed_block['id'] : wp_unique_id( 'jet-map-' );
		}

		if ( ! isset( $prepared_attrs['_element_id'] ) || ! is_scalar( $prepared_attrs['_element_id'] ) ) {
			$prepared_attrs['_element_id'] = '';
		} else {
			$prepared_attrs['_element_id'] = (string) $prepared_attrs['_element_id'];
		}

		if ( empty( $prepared_attrs['lisitng_id'] ) ) {
			return 'Please select a base listing item';
		}

		$render = self::get_jet_engine_render_instance( $prepared_attrs );

		if ( ! $render ) {
			return 'Listing renderer class not found';
		}

		$divi_module_render = new Module_Render();

		$content = $divi_module_render->render_content(
			$render,
			$attrs,
			$block,
			$elements,
			self::class
		);

		return sprintf(
			'<div data-is-block="jet-engine/maps-listing">%s</div>',
			$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 JetEngine render name.
	 */
	public static function get_jet_engine_render_name() {
		return 'maps-listing';
	}

	/**
	 * Register module.
	 */
	public function load() {

		$module_json_folder_path = JET_ENGINE_DIVI_VIEWS_MODULES_JSON_PATH . 'maps-listing/';

		add_action(
			'init',
			function() use ( $module_json_folder_path ) {
				if ( ! jet_engine()->modules->is_module_active( 'maps-listings' ) ) {
					return;
				}

				ModuleRegistration::register_module(
					$module_json_folder_path,
					[
						'render_callback' => [ Maps_Listing::class, 'render_callback' ],
					]
				);
			}
		);
	}
}
