<?php
namespace Jet_Engine_Divi_Views\Components\Jet_Engine;

use Jet_Engine_Divi_Views\Components\Base_Component;

// Prevent direct access to the file.
if ( ! defined( 'WPINC' ) ) {
	die;
}

/**
 * Base component class
 */
class Component extends Base_Component {

	/**
	 * Register component
	 *
	 * @return void
	 */
	public function register() {

		if ( ! function_exists( 'jet_engine' ) ) {
			return;
		}

		new Attributes_Injector();

		add_action( 'jet-engine/divi-views/register-modules', [ $this, 'register_modules' ] );
		add_filter( 'jet-engine-divi-views/modules-controller/assets', [ $this, 'modules_assets' ] );
		add_filter( 'jet-engine/blocks-views/editor-data', [ $this, 'modify_editor_data' ] );
		add_filter( 'register_block_type_args', [ $this, 'ensure_dynamic_link_store_attributes' ], 20, 2 );
		add_filter( 'jet-engine-divi-views/wizard/localize-config', [ $this, 'modify_localize_config' ] );
		add_action( 'wp_enqueue_scripts', [ $this, 'maybe_enqueue_front_assets_for_divi_editor' ], 20 );

		$listing_namager = new Listing\Manager();
		new Layout_Manager( $listing_namager->get_view_id() );

		add_filter( 'divi_module_dynamic_content_resolved_value_jet_loop_object', [ $this, 'process_loop_object' ], 0, 2 );
	}

	/**
	 * Return string representation of the current object to use while rendering
	 *
	 * @param mixed $value
	 * @param array $args
	 * @return mixed
	 */
	public function process_loop_object( $value, $args ) {
		$value = serialize($args['loop_object'] );
		return $value;
	}

	/**
	 * Get component ID
	 *
	 * @return string
	 */
	public function get_id() {
		return 'jet-engine-divi-views';
	}

	/**
	 * Register modules
	 *
	 * @param object $dependency_tree Dependency tree instance.
	 */
	public function register_modules( $dependency_tree ) {

		jet_engine()->blocks_views->block_types->register_block_types();

		$dependency_tree->add_dependency( new Modules\Dynamic_Field() );
		$dependency_tree->add_dependency( new Modules\Dynamic_Image() );
		$dependency_tree->add_dependency( new Modules\Dynamic_Repeater() );
		$dependency_tree->add_dependency( new Modules\Dynamic_Meta() );
		$dependency_tree->add_dependency( new Modules\Dynamic_Link() );
		$dependency_tree->add_dependency( new Modules\Dynamic_Terms() );
		$dependency_tree->add_dependency( new Modules\Listing_Grid() );
		$dependency_tree->add_dependency( new Modules\Listing_Calendar() );
		$dependency_tree->add_dependency( new Modules\Maps_Listing() );
	}

	/**
	 * Register module related assets and data
	 */
	public function modules_assets( $assets ) {

		if ( ! class_exists( '\Jet_Engine_Blocks_Views_Editor' ) ) {
			require_once jet_engine()->blocks_views->component_path( 'editor.php' );
		}

		$editor = new \Jet_Engine_Blocks_Views_Editor( true );

		$assets[] = [
			'handle'   => 'jet-engine-divi-views-editor',
			'src'      => JET_ENGINE_DIVI_VIEWS_URL . 'assets/js/jet-engine-bundle.js',
			'deps'     => [],
			'localize' => [
				'object' => 'JetEngineDiviViews',
				'data'   => $editor->get_block_editor_config(),
			],
		];

		return $assets;
	}

	/**
	 * @param $data
	 * @return mixed
	 */

	/**
	 * Ensure JetEngine dynamic-link block keeps Data Stores attrs available on all requests.
	 * Some REST preview requests can register the block before the Data Stores module extends its schema.
	 *
	 * @param array  $args       Block registration args.
	 * @param string $block_name Full block name.
	 * @return array
	 */
	public function ensure_dynamic_link_store_attributes( $args, $block_name ) {

		if ( 'jet-engine/dynamic-link' !== $block_name ) {
			return $args;
		}

		if ( empty( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) {
			$args['attributes'] = [];
		}

		$compat_attributes = [
			'dynamic_link_store' => [
				'type'    => 'string',
				'default' => '',
			],
			'added_to_store_text' => [
				'type'    => 'string',
				'default' => '',
			],
			'added_to_store_url' => [
				'type'    => 'string',
				'default' => '',
			],
			'dynamic_link_synch_grid' => [
				'type'    => 'boolean',
				'default' => false,
			],
			'dynamic_link_synch_grid_id' => [
				'type'    => 'string',
				'default' => '',
			],
			'remove_post_from_listing' => [
				'type'    => 'boolean',
				'default' => false,
			],
		];

		foreach ( $compat_attributes as $attribute_name => $attribute_config ) {
			if ( ! isset( $args['attributes'][ $attribute_name ] ) ) {
				$args['attributes'][ $attribute_name ] = $attribute_config;
			}
		}

		return $args;
	}

	public function modify_editor_data( $data ) {
		$calendar_module = jet_engine()->modules->get_module( 'calendar' );
		$active_modules  = jet_engine()->modules->get_active_modules();

		$disabled_callbacks = [];

		if ( ! in_array( 'gallery-grid', $active_modules, true ) ) {
			$disabled_callbacks[] = 'jet_engine_img_gallery_grid';
		}

		if ( ! in_array( 'gallery-slider', $active_modules, true ) ) {
			$disabled_callbacks[] = 'jet_engine_img_gallery_slider';
		}

		if ( ! empty( $disabled_callbacks ) ) {
			if ( ! empty( $data['filterCallbacks'] ) && is_array( $data['filterCallbacks'] ) ) {
				$data['filterCallbacks'] = array_values(
					array_filter(
						$data['filterCallbacks'],
						function ( $callback ) use ( $disabled_callbacks ) {
							$value = $callback['value'] ?? null;

							return ! in_array( $value, $disabled_callbacks, true );
						}
					)
				);
			}

			if ( ! empty( $data['filterCallbacksArgs'] ) && is_array( $data['filterCallbacksArgs'] ) ) {
				$data['filterCallbacksArgs'] = array_values(
					array_filter(
						$data['filterCallbacksArgs'],
						function ( $arg ) use ( $disabled_callbacks ) {
							$condition = $arg['condition'] ?? null;

							if ( is_array( $condition ) ) {
								$condition = array_values(
									array_filter(
										$condition,
										function ( $callback_name ) use ( $disabled_callbacks ) {
											return ! in_array( $callback_name, $disabled_callbacks, true );
										}
									)
								);

								if ( empty( $condition ) ) {
									return false;
								}

								$arg['condition'] = $condition;
							} elseif ( is_string( $condition ) && in_array( $condition, $disabled_callbacks, true ) ) {
								return false;
							}

							return true;
						}
					)
				);
			}
		}

		$data['calendarGroupKeys'] = $calendar_module ? $calendar_module->get_calendar_group_keys( true ) : [];

		$data['mapsListingDummyMapUrl'] = jet_engine()->plugin_url( 'includes/modules/maps-listings/assets/images/dummy-map.png' );

		if ( ! empty( $data['mapsListingConfig'] ) ) {
			$data['mapsListingConfig']['dummyMapUrl'] = $data['mapsListingDummyMapUrl'];
		}

		return $data;
	}

	/**
	 * @param $data
	 * @return mixed
	 */
	public function modify_localize_config( $data ) {
		$divi_compatibility_modules = apply_filters( 'jet-engine-divi-views/jet-engine-compatibility-plugins',
			[ 'gallery-grid', 'gallery-slider', 'calendar', 'maps-listings' ]
		);

		$internal_modules = jet_engine()->modules->get_all_modules_for_js( true, 'internal' );
		$internal_modules = array_map( function ( $module_data ) {

			switch ( $module_data['value'] ) {
				case 'gallery-grid':
					$module_data['details_alt'] = __( 'After activation, in the Callback feature of the Content settings tab of the Dynamic Field widget in Elementor page builder appears an “Images gallery grid” option.', 'jet-engine-divi-views' );
					break;

				case 'gallery-slider':
					$module_data['details_alt'] = __( 'Turn dynamic listing grids into beautiful slideshows that engage visitors.', 'jet-engine-divi-views' );;
					break;

				case 'calendar':
					$module_data['details_alt'] = __( 'Display a live availability calendar for customers to see open time slots and book instantly.', 'jet-engine-divi-views' );;
					break;

				case 'maps-listings':
					$module_data['details_alt'] = __( 'Build interactive maps where visitors instantly find whats near them.', 'jet-engine-divi-views' );;
					break;

				default:
					$module_data['details_alt'] = false;
					break;
			}

			return $module_data;
		}, $internal_modules );

		$internal_modules =  array_filter( $internal_modules, function( $module_data ) use ( $divi_compatibility_modules ) {
			return in_array( $module_data['value'], $divi_compatibility_modules );
		} );



		$data['internalModules'] = $internal_modules;
		$data['externalModules'] = jet_engine()->modules->get_all_modules_for_js( true, 'external' );
		$data['activeModules'] = jet_engine()->modules->get_active_modules();

		return $data;
	}

	/**
	 * Ensure JetEngine front scripts/styles are available in Divi Visual Builder.
	 * Without these assets listing-grid JS init hooks may not run in editor.
	 *
	 * @return void
	 */
	public function maybe_enqueue_front_assets_for_divi_editor() {

		$is_divi_fb = ! empty( $_GET['et_fb'] ) && '1' === (string) $_GET['et_fb']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		if ( ! $is_divi_fb ) {
			return;
		}

		if ( ! isset( jet_engine()->frontend ) ) {
			return;
		}

		if ( method_exists( jet_engine()->frontend, 'frontend_styles' ) ) {
			jet_engine()->frontend->frontend_styles();
		}

		if ( method_exists( jet_engine()->frontend, 'preview_scripts' ) ) {
			jet_engine()->frontend->preview_scripts();
		}
	}
}
