<?php

/**
 * Icon Divider 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\Css\CssStyle;
use ET\Builder\Packages\StyleLibrary\Utils\StyleDeclarations;

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

	/**
	 * Register module.
	 */
	public function load()
	{
		add_action('init', array(self::class, 'register_module'));
	}

	public static function dsm_initialise()
	{
		add_action(
			'divi_module_library_modules_dependency_tree',
			function ($dependency_tree) {
				$dependency_tree->add_dependency(new self());
			}
		);
	}

	public static function register_module()
	{
		$module_json_path = DSM_DIR_PATH . 'divi-5/public/packages/module-library/icon-divider';

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

	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(
					$elements->style(
						array(
							'attrName' => 'module',
							'styleProps' => array(
								'disabledOn' => array(
									'disabledModuleVisibility' => $args['settings']['disabledModuleVisibility'] ?? null,
								),
							),
						)
					),

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

					/**
					 * Icon picker SSR: `$elements->style( font_icon )` does not map FA reliably; declare family/weight explicitly.
					 *
					 * Selector matches rendered markup `{orderClass} .dsm-icon-divider-image .et-pb-icon`.
					 */
					CommonStyle::style(
						array(
							'selector' => "{$args['orderClass']} .dsm-icon-divider-image .et-pb-icon",
							'attr' => $attrs['font_icon']['innerContent'] ?? array(),
							'declarationFunction' => array( self::class, 'icon_divider_font_icon_style_declaration' ),
						)
					),

					$elements->style(
						array(
							'attrName' => 'image_icon',
						)
					),

					CommonStyle::style(
						array(
							'selector' => "{$args['orderClass']} .dsm-icon-divider-image",
							'attr' => $attrs['image_max_width']['innerContent'] ?? array(),
							'property' => 'max-width',
						)
					),

					CommonStyle::style(
						array(
							'selector' => "{$args['orderClass']} .dsm-divider",
							'attr' => $attrs['color']['innerContent'] ?? array(),
							'property' => 'border-top-color',
						)
					),

					CommonStyle::style(
						array(
							'selector' => "{$args['orderClass']} .dsm-divider",
							'attr' => $attrs['divider_weight']['innerContent'] ?? array(),
							'property' => 'border-top-width',
						)
					),

					CommonStyle::style(
						array(
							'selector' => "{$args['orderClass']} .dsm-divider",
							'attr' => $attrs['divider_style']['innerContent'] ?? array(),
							'property' => 'border-top-style',
						)
					),

					CommonStyle::style(
						array(
							'selector' => "{$args['orderClass']} .dsm-icon-divider-wrapper",
							'attr' => $attrs['icon_gap']['innerContent'] ?? array(),
							'property' => 'gap',
						)
					),
				),
			)
		);
	}

	/**
	 * Font-face rules for `.et-pb-icon` glyphs (SSR). Mirrors Card / Icon List; omits `content` — glyph HTML comes from PHP output.
	 *
	 * @param array<string, mixed> $params CommonStyle declaration params (`attrValue` = picker leaf).
	 */
	public static function icon_divider_font_icon_style_declaration(array $params): string {
		$icon_attr = isset( $params['attrValue'] ) && is_array( $params['attrValue'] ) ? $params['attrValue'] : array();

		if ( isset( $icon_attr['settings'] ) && is_array( $icon_attr['settings'] ) ) {
			$icon_attr = $icon_attr['settings'];
		}

		$style_declarations = new StyleDeclarations(
			array(
				'returnType' => 'string',
				'important'  => array(
					'font-family' => true,
					'font-weight' => true,
				),
			)
		);

		if ( isset( $icon_attr['type'] ) && is_string( $icon_attr['type'] ) && '' !== $icon_attr['type'] ) {
			$font_family = Utils::is_fa_icon( $icon_attr ) ? 'FontAwesome' : 'ETmodules';
			$style_declarations->add( 'font-family', '"' . $font_family . '"' );
		}

		if ( isset( $icon_attr['weight'] ) && '' !== $icon_attr['weight'] ) {
			$style_declarations->add( 'font-weight', (string) $icon_attr['weight'] );
		}

		return $style_declarations->value();
	}

	public static function module_script_data($args)
	{
		$elements = $args['elements'];
		$elements->script_data(
			array(
				'attrName' => 'module',
			)
		);
	}

	public static function module_classnames($args)
	{
		$classnames_instance = $args['classnamesInstance'];
		$attrs = $args['attrs'];

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

	private static function get_image_alt_from_url($image_url)
	{
		if (empty($image_url)) {
			return '';
		}

		global $wpdb;

		$attachment_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE guid = %s", $image_url));

		if (!$attachment_id) {
			$upload_dir = wp_upload_dir();
			$image_path = str_replace($upload_dir['baseurl'], '', $image_url);
			$image_path = ltrim($image_path, '/');

			$attachment_id = $wpdb->get_var($wpdb->prepare(
				"SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s LIMIT 1",
				'%' . $wpdb->esc_like(basename($image_path)) . '%'
			));
		}

		if ($attachment_id) {
			$alt = get_post_meta($attachment_id, '_wp_attachment_image_alt', true);
			return $alt ? trim($alt) : '';
		}

		return '';
	}

	/**
	 * Resolve image URL from Divi 5 upload innerContent.
	 *
	 * @param array $attrs Module attrs.
	 * @return string
	 */
	private static function get_image_src_from_attrs($attrs)
	{
		$raw = $attrs['image']['innerContent']['desktop']['value'] ?? '';
		if (is_string($raw)) {
			return $raw;
		}
		if (is_array($raw) && isset($raw['src']) && is_string($raw['src'])) {
			return $raw['src'];
		}
		return '';
	}

	/**
	 * Render module HTML output.
	 *
	 * @param array     $attrs    Module attrs.
	 * @param string    $content  Inner content.
	 * @param \WP_Block $block    Block instance.
	 * @param mixed     $elements Module elements.
	 * @return string
	 */
	public static function render_callback($attrs, $content, $block, $elements)
	{

		$use_icon = $attrs['use_icon']['innerContent']['desktop']['value'] ?? 'off';
		$image = self::get_image_src_from_attrs($attrs);
		$alignment = $attrs['align']['innerContent']['desktop']['value'] ?? 'center';
		$divider_position_value = $attrs['divider_position']['innerContent']['desktop']['value'] ?? 'center';
		$divider_alignment = 'dsm-icon-divider-align-' . $alignment;
		$divider_position = 'dsm-icon-divider-vertical-position-' . $divider_position_value;

		$use_circle = $attrs['use_circle']['innerContent']['desktop']['value'] ?? 'off';
		$use_circle_border = $attrs['use_circle_border']['innerContent']['desktop']['value'] ?? 'off';
		$icon_color = $attrs['icon_color']['innerContent']['desktop']['value'] ?? '';
		$circle_color = $attrs['circle_color']['innerContent']['desktop']['value'] ?? '';
		$circle_border_color = $attrs['circle_border_color']['innerContent']['desktop']['value'] ?? '';
		$use_icon_font_size = $attrs['use_icon_font_size']['innerContent']['desktop']['value'] ?? 'off';
		$icon_font_size = $attrs['icon_font_size']['innerContent']['desktop']['value'] ?? '96px';

		$icon_class = 'et-pb-icon';
		if ('on' === $use_circle) {
			$icon_class .= ' et-pb-icon-circle';
		}
		if ('on' === $use_circle && 'on' === $use_circle_border) {
			$icon_class .= ' et-pb-icon-circle-border';
		}

		$icon_style = '';
		if ('' !== $icon_color) {
			$icon_style .= sprintf('color:%1$s;', esc_attr($icon_color));
		}
		if ('on' === $use_circle && '' !== $circle_color) {
			$icon_style .= sprintf(' background-color:%1$s;', esc_attr($circle_color));
		}
		if ('on' === $use_circle && 'on' === $use_circle_border && '' !== $circle_border_color) {
			$icon_style .= sprintf(' border-color:%1$s;', esc_attr($circle_border_color));
		}
		if ('on' === $use_icon_font_size && '' !== $icon_font_size) {
			$icon_style .= sprintf(' font-size:%1$s;', esc_attr($icon_font_size));
		}

		$icon_settings = is_array( $attrs['font_icon']['innerContent']['desktop']['value'] ?? null )
			? $attrs['font_icon']['innerContent']['desktop']['value']
			: array();
		$icon_value    = Utils::process_font_icon( $icon_settings );
		$icon          = HTMLUtility::render(
			array(
				'tag'               => 'span',
				'attributes'        => array(
					'class' => esc_attr( $icon_class ),
					'style' => $icon_style,
				),
				'childrenSanitizer' => 'et_core_esc_previously',
				'children'          => is_string( $icon_value ) ? $icon_value : '',
			)
		);

		$image_alt = self::get_image_alt_from_url($image);
		$image_alt = $image_alt ? esc_attr($image_alt) : '';

		$divider_image = sprintf(
			'<img src="%1$s" alt="%2$s" />',
			esc_url($image),
			$image_alt
		);

		$image_wrap_class = 'on' === $use_icon ? '' : 'dsm-image';

		$image_icon_divider_markup = sprintf(
			'<div class="dsm-icon-divider-wrapper %2$s %3$s">
				<div class="dsm-icon-divider-before dsm-divider"></div>
				<div class="dsm-icon-divider-image %4$s">
					<span class="dsm-icon-divider-image-wrap">%1$s</span>
				</div>
				<div class="dsm-icon-divider-after dsm-divider"></div>
			</div>',
			'on' === $use_icon ? $icon : $divider_image,
			esc_attr($divider_alignment),
			esc_attr($divider_position),
			esc_attr($image_wrap_class)
		);

		$module_inner = HTMLUtility::render(
			array(
				'tag' => 'div',
				'attributes' => array(
					'class' => 'et_pb_module_inner',
				),
				'childrenSanitizer' => 'et_core_esc_previously',
				'children' => $image_icon_divider_markup,
			)
		);

		$module_elements = $elements->style_components(
			array(
				'attrName' => 'module',
			)
		);

		$module_container_children = $module_elements . $module_inner;

		return Module::render(
			array(
				'orderIndex' => $block->parsed_block['orderIndex'],
				'storeInstance' => $block->parsed_block['storeInstance'],
				'attrs' => $attrs,
				'elements' => $elements,
				'id' => $block->parsed_block['id'],
				'moduleClassName' => 'dsm_icon_divider',
				'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,
			)
		);
	}
}