<?php

/**
 * Lottie Module.
 *
 * @package DiviSupreme.
 */

declare(strict_types=1);

namespace DiviSupreme\Modules;

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


use ET\Builder\Framework\DependencyManagement\Interfaces\DependencyInterface;
use ET\Builder\Framework\Utility\HTMLUtility;
use ET\Builder\FrontEnd\Module\Style;
use ET\Builder\Packages\Module\Module;
use ET\Builder\Packages\Module\Options\Element\ElementClassnames;
use ET\Builder\Packages\ModuleLibrary\ModuleRegistration;
use ET\Builder\Packages\Module\Layout\Components\StyleCommon\CommonStyle;
use ET\Builder\Packages\IconLibrary\IconFont\Utils;
use ET\Builder\Packages\Module\Options\Text\TextStyle;
use ET\Builder\Packages\StyleLibrary\Utils\StyleDeclarations;
use ET\Builder\Packages\Module\Options\Css\CssStyle;



/**
 * Class that handles "Lottie Module" module.
 */
class Lottie implements DependencyInterface
{

	/**
	 * Register module.
	 * `DependencyInterface` interface ensures class method name `load()` is executed for initialization.
	 */
	public function load()
	{
		add_action('init', array(self::class, 'register_module'));
	}

	/**
	 * Initilises the module.
	 *
	 * @return void
	 */
	public static function dsm_initialise()
	{
		add_action(
			'divi_module_library_modules_dependency_tree',
			function ($dependency_tree) {
				$dependency_tree->add_dependency(new self());
			}
		);
	}


	/**
	 * Register module.
	 */
	public static function register_module()
	{

		$module_json_path = DSM_DIR_PATH . 'divi-5/public/packages/module-library/lottie';

		ModuleRegistration::register_module(
			$module_json_path,
			array(
				'render_callback' => array(self::class, 'render_callback'),
			)
		);
	}

	/**
	 * Render module style.
	 *
	 * @param array $args - Arguments.
	 */
	public static function module_styles($args)
	{
		$attrs = $args['attrs'] ?? array();
		$elements = $args['elements'];

		Style::add(
			array(
				'id' => $args['id'],
				'name' => $args['name'],
				'orderIndex' => $args['orderIndex'],
				'storeInstance' => $args['storeInstance'],
				'styles' => array(
					// Module.
					$elements->style(
						array(
							'attrName' => 'module',
							'styleProps' => array(
								'disabledOn' => array(
									'disabledModuleVisibility' => $args['settings']['disabledModuleVisibility'] ?? null,
								),
							),
						)
					),

					CssStyle::style(
						array(
							'selector' => $args['orderClass'],
							'attr' => $attrs['css'] ?? array(),
						)
					),

					TextStyle::style(
						array(
							'selector' => $args['orderClass'],
							'attr' => $attrs['module']['advanced']['text'] ?? array(),
						)
					),
				),
			)
		);
	}

	/**
	 * Render module script data.
	 *
	 * @param array $args - Arguments.
	 */
	public static function module_script_data($args)
	{
		$elements = $args['elements'];

		// Element Script Data Options.
		$elements->script_data(
			array(
				'attrName' => 'module',
			)
		);
	}

	/**
	 * Render module classnames.
	 *
	 * @param array $args - Arguments.
	 */
	public static function module_classnames($args)
	{
		$classnames_instance = $args['classnamesInstance'];
		$attrs = $args['attrs'];

		// Module.
		$classnames_instance->add(
			ElementClassnames::classnames(
				array(
					'attrs' => $attrs['module']['decoration'] ?? array(),
				)
			)
		);
	}

	/**
	 * Render module HTML output.
	 *
	 * @param array     $attrs - Modules Attributes.
	 * @param string    $content - Content.
	 * @param \WP_Block $block - Block.
	 * @param mixed     $elements - Elements.
	 */
	public static function render_callback($attrs, $content, $block, $elements)
	{

		$raw_lottie_url = $attrs['lottie_url']['innerContent']['desktop']['value'] ?? '';
		$lottie_url = '';
		if (is_array($raw_lottie_url)) {
			$lottie_url = isset($raw_lottie_url['src']) ? (string) $raw_lottie_url['src'] : '';
		} elseif (is_string($raw_lottie_url)) {
			$lottie_url = $raw_lottie_url;
		}
		$lottie_loop = $attrs['lottie_loop']['innerContent']['desktop']['value'] ?? '';
		$loop_no_times = $attrs['loop_no_times']['innerContent']['desktop']['value'] ?? '';
		$lottie_delay = $attrs['lottie_delay']['innerContent']['desktop']['value'] ?? '';
		$lottie_direction = $attrs['lottie_direction']['innerContent']['desktop']['value'] ?? '';
		$lottie_speed = $attrs['lottie_speed']['innerContent']['desktop']['value'] ?? '';
		$lottie_play_on_hover = $attrs['lottie_play_on_hover']['innerContent']['desktop']['value'] ?? '';
		$lottie_trigger_method = $attrs['lottie_trigger_method']['innerContent']['desktop']['value'] ?? '';
		$lottie_scroll = $attrs['lottie_scroll']['innerContent']['desktop']['value'] ?? '';
		$lottie_mouseout_action = $attrs['lottie_mouseout_action']['innerContent']['desktop']['value'] ?? '';
		$lottie_animation_viewport = $attrs['lottie_animation_viewport']['innerContent']['desktop']['value'] ?? '';

		wp_enqueue_script('dsm-lottie-frontend');

		$data_attrs[] = array(
			'path' => $lottie_url,
			'loop' => 'off' !== $lottie_loop ? true : false,
			'loop_no' => $loop_no_times,
			'delay' => $lottie_delay,
			'direction' => $lottie_direction,
			'speed' => $lottie_speed,
			'hover' => 'off' !== $lottie_play_on_hover ? true : false,
			'trigger' => $lottie_trigger_method,
			'scroll' => $lottie_scroll,
			'mouseout' => $lottie_mouseout_action,
			'viewport' => $lottie_animation_viewport,
		);

		$container = sprintf(
			'<div class="dsm_lottie_wrapper dsm-frontend" data-params=%1$s></div>',
			wp_json_encode($data_attrs)
		);

		// Module Inner.
		// Essentially, this is the module content.
		// Were wrapping the title and content in a div with class `et_pb_module_inner`.
		$module_inner = HTMLUtility::render(
			array(
				'tag' => 'div',
				'attributes' => array(
					'class' => 'et_pb_module_inner',
				),
				'childrenSanitizer' => 'et_core_esc_previously',
				'children' => $container,
			)
		);

		// This are the module elements that will be rendered in the frontend.
		$module_elements = $elements->style_components(
			array(
				'attrName' => 'module',
			)
		);

		// This are the children of the module container, which are the module elements and the module inner.
		$module_container_children = $module_elements . $module_inner;

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

				// VB equivalent.
				'attrs' => $attrs,
				'elements' => $elements,
				'id' => $block->parsed_block['id'],
				'moduleClassName' => 'dsm_lottie',
				'name' => $block->block_type->name,
				'classnamesFunction' => array(self::class, 'module_classnames'),
				'moduleCategory' => $block->block_type->category,
				'stylesComponent' => array(self::class, 'module_styles'),
				'scriptDataComponent' => array(self::class, 'module_script_data'),
				'children' => $module_container_children,
			)
		);
	}
}
