<?php

namespace DIFL\Server\Modules\TimelineTabsItem;

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

use DIFL\Server\Traits\GetPropsTrait;
use DIFL\Server\Traits\UnifiedStyleRenderer;
use DIFL\Server\Traits\StyleUtil;
use ET\Builder\Framework\DependencyManagement\Interfaces\DependencyInterface;
use ET\Builder\FrontEnd\BlockParser\BlockParserStore;
use ET\Builder\FrontEnd\Module\Style;
use ET\Builder\Packages\Module\Layout\Components\StyleCommon\CommonStyle;
use ET\Builder\Packages\Module\Module;
use ET\Builder\Packages\Module\Options\Css\CssStyle;
use ET\Builder\Packages\Module\Options\Element\ElementClassnames;
use ET\Builder\Packages\Module\Options\Text\TextClassnames;
use ET\Builder\Packages\ModuleLibrary\ModuleRegistration;
use ET\Builder\Packages\Module\Options\Loop\LoopUtils;

class TimelineTabsItem implements DependencyInterface {

	use GetPropsTrait;
	use UnifiedStyleRenderer;
	use StyleUtil;

	protected $styles;

	public static function custom_css() {
		return \WP_Block_Type_Registry::get_instance()
			->get_registered( 'difl/timeline-tabs-item' )
			->customCssFields ?? [];
	}

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

		$classnames_instance->add(
			TextClassnames::text_options_classnames(
				$attrs['module']['advanced']['text'] ?? [],
				[ 'orientation' => false ]
			),
			true
		);

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

		$classnames_instance->add( 'difl-tt-item', true );
	}

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

	protected function getDefaultKeys( $args ) {
		$attrs    = $args['attrs'];
		$metaData = $args['elements']->module_metadata->attributes;

		foreach ( $metaData as $key => $value ) {
			if ( isset( $attrs[ $key ] ) && ! is_array( $attrs[ $key ] ) ) {
				continue;
			}
			if ( ! isset( $attrs[ $key ] ) ) {
				$attrs[ $key ] = [];
			}
			if ( empty( $attrs[ $key ]['innerContent'] ) ) {
				$attrs[ $key ]['innerContent'] = [ 'desktop' => [ 'value' => [] ] ];
			}
			if ( empty( $attrs[ $key ]['decoration'] ) ) {
				$attrs[ $key ]['decoration'] = [ 'desktop' => [ 'value' => [] ] ];
			}
		}
		return $attrs;
	}

	public static function module_styles( $args ) {
		$instance    = new static();
		$attrs       = $instance->getDefaultKeys( $args );
		$elements    = $args['elements'];
		$settings    = $args['settings'] ?? [];
		$order_class = $args['orderClass'];

		$instance->initializeProps( $elements, $attrs );
		$instance->styles = $instance->renderUnifiedStyles( $elements, $attrs, $order_class, 'difl/timeline-tabs-item' );

		// Per-tab icon font-style (FontAwesome family + weight, or ETmodules for Divi
		// icons). The icon span lives inside the parent's nav tab wrapper which carries
		// this child's order class, so this selector reaches it.
		$icon_font_style = CommonStyle::style( [
			'selector'            => "{$order_class} .difl-tt-tab-item__media.et-pb-icon",
			'attr'                => $attrs['item_obj_settings']['innerContent'] ?? [],
			'declarationFunction' => static function ( $props ) {
				$icon = $props['attrValue']['media_icon'] ?? null;
				return $icon ? static::get_font_style( $icon ) : '';
			},
		] );

		// Per-tab icon color — hand-written so we control the resolution.
		$icon_color_style = CommonStyle::style( [
			'selector'            => "{$order_class} .difl-tt-tab-item__media.et-pb-icon",
			'attr'                => $attrs['item_obj_settings']['innerContent'] ?? [],
			'declarationFunction' => static function ( $props ) {
				$c = $props['attrValue']['media_icon_color'] ?? null;
				return ( $c && is_string( $c ) ) ? "color: {$c};" : '';
			},
		] );

		Style::add( [
			'id'            => $args['id'],
			'name'          => $args['name'],
			'orderIndex'    => $args['orderIndex'],
			'storeInstance' => $args['storeInstance'],
			'styles'        => [
				$elements->style( [
					'attrName'   => 'module',
					'styleProps' => [
						'disabledOn' => [
							'disabledModuleVisibility' => $settings['disabledModuleVisibility'] ?? null,
						],
					],
				] ),
				CssStyle::style( [
					'selector'  => $order_class,
					'attr'      => $attrs['css'] ?? [],
					'cssFields' => self::custom_css(),
				] ),
				...$instance->styles,
				$icon_font_style,
				$icon_color_style,
			],
		] );
	}

	public function render( $attrs, $content = '' ) {
		return et_core_sanitized_previously( $content );
	}

	public static function render_callback( $attrs, $content, $block, $elements ) {
		global $df_tt_data;

		$instance = new static();
		$instance->initializeProps( $elements, $attrs );

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

		$title          = esc_html( $instance->props['title'] ?? '' );
		$description    = esc_html( $instance->props['description'] ?? '' );
		$use_icon       = ( $instance->props['use_icon'] ?? 'off' ) === 'on';
		$media_image    = $instance->props['media_image'] ?? null;
		$media_icon     = $instance->props['media_icon']  ?? null;

		// Resolve `$variable(...)$` dynamic-content tokens HERE — this is the
		// only place where loop iteration context (`__loop_iteration` on
		// $attrs + active LoopContext) still exists. Resolving later in the
		// parent's render would read the page's $post and return the wrong
		// image for every iteration. Non-loop case falls back to standard
		// page-level resolution automatically.
		if ( is_string( $media_image ) && str_contains( $media_image, '$variable(' ) ) {
			$media_image = LoopUtils::process_dynamic_content( $media_image, $attrs );
		}

		$order_class = \ET\Builder\Packages\ModuleUtils\ModuleUtils::get_module_order_class_name(
			$block->parsed_block['id'],
			$block->parsed_block['storeInstance']
		);

		// Color + size for the per-item icon are emitted via customCssAttr in module.json
		// (UnifiedStyleRenderer handles them in both PHP and VB).
		$df_tt_data[ $order_class ] = [
			'title'       => $title,
			'description' => $description,
			'use_icon'    => $use_icon,
			'media_image' => $media_image,
			'media_icon'  => $media_icon,
		];

		return Module::render( [
			'orderIndex'          => $block->parsed_block['orderIndex'],
			'storeInstance'       => $block->parsed_block['storeInstance'],
			'attrs'               => $attrs,
			'elements'            => $elements,
			'id'                  => $block->parsed_block['id'],
			'moduleClassName'     => '',
			'name'                => $block->block_type->name,
			'moduleCategory'      => $block->block_type->category,
			'classnamesFunction'  => [ TimelineTabsItem::class, 'module_classnames' ],
			'stylesComponent'     => [ TimelineTabsItem::class, 'module_styles' ],
			'scriptDataComponent' => [ TimelineTabsItem::class, 'module_script_data' ],
			'parentAttrs'         => $parent_attrs,
			'parentId'            => $parent->id ?? '',
			'parentName'          => $parent->blockName ?? '',
			'children'            => $elements->style_components( [ 'attrName' => 'module' ] )
				. $instance->render( $attrs, $content ),
		] );
	}

	public function load(): void {
		$module_json_folder_path = DIFL_MODULES_JSON_PATH . 'TimelineTabsItem/';

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