<?php
/**
 * CSS generator for the List Item block's marker icon.
 *
 * The generic main/hover CSS for the <li> (.uniqueClass) comes from the shared
 * generator. This helper produces the list-item-specific selectors the shared
 * generator cannot express:
 *   - .uniqueClass { list-style: none }                  — when the item has its own marker
 *   - .uniqueClass .icon { width/height, color, … }      — marker icon box (a.k.a. .__marker)
 *   - .uniqueClass .icon svg { width:100%; height:100% } — svg fills the sized box
 *   plus the matching :hover variants.
 *
 * @package AxcelersBlocks
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! function_exists( 'axcelersblocks_list_item_generate_icon_css' ) ) {
	/**
	 * Generate the list-item-specific marker/icon CSS rules.
	 *
	 * @param string $unique_class Block-scoped unique class.
	 * @param array  $devices      Device map from axcelersblocks_get_responsive_devices().
	 * @param array  $attributes   Full block attributes.
	 * @return string[] CSS rule strings (with media queries where needed).
	 */
	function axcelersblocks_list_item_generate_icon_css( string $unique_class, array $devices, array $attributes ): array {
		$class = sanitize_html_class( $unique_class );
		$rules = [];

		// Keep list-item-specific icon CSS aligned with the shared generator:
		// desktop-only legacy/default responsive values become base mobile rules
		// for the min-width cascade.
		$has_css_v = function ( $v ) use ( &$has_css_v ) {
			if ( is_bool( $v ) || is_null( $v ) ) { return false; }
			if ( is_string( $v ) ) { return '' !== $v; }
			if ( is_array( $v ) ) {
				foreach ( $v as $item ) {
					if ( $has_css_v( $item ) ) { return true; }
				}
			}
			return false;
		};

		foreach ( $attributes as &$attribute_value ) {
			if ( ! is_array( $attribute_value ) ) { continue; }
			$has_desktop = isset( $attribute_value['desktop'] ) && $has_css_v( $attribute_value['desktop'] );
			$has_tablet  = isset( $attribute_value['tablet'] ) && $has_css_v( $attribute_value['tablet'] );
			$has_mobile  = isset( $attribute_value['mobile'] ) && $has_css_v( $attribute_value['mobile'] );
			if ( $has_desktop && ! $has_mobile ) {
				$attribute_value['mobile'] = $attribute_value['desktop'];
			}
			if ( $has_tablet && ! $has_desktop ) {
				$attribute_value['desktop'] = $attribute_value['tablet'];
				if ( ! $has_mobile ) {
					$attribute_value['mobile'] = $attribute_value['tablet'];
				}
			}
		}
		unset( $attribute_value );

		// Normalise an iconSize value (legacy string = both sides, or { width, height }).
		$icon_size_sides = static function ( $raw ) {
			$width  = '';
			$height = '';
			if ( is_string( $raw ) ) {
				$width  = $raw;
				$height = $raw;
			} elseif ( is_array( $raw ) ) {
				$width  = isset( $raw['width'] )  && is_string( $raw['width'] )  ? $raw['width']  : '';
				$height = isset( $raw['height'] ) && is_string( $raw['height'] ) ? $raw['height'] : '';
			}
			return [
				'width'  => axcelersblocks_sanitize_css_value( $width ),
				'height' => axcelersblocks_sanitize_css_value( $height ),
			];
		};

		$icon_effect_to_css = static function ( $effect, $property ) {
			if ( ! is_array( $effect ) ) {
				return null;
			}
			$value_or_default = static function ( $value, $fallback ) {
				return ( isset( $value ) && '' !== $value ) ? $value : $fallback;
			};
			switch ( $property ) {
				case 'box-shadow':
					$shadow = $effect['boxShadow'] ?? null;
					if ( ! is_array( $shadow ) ) { return null; }
					$x      = $value_or_default( $shadow['xOffset'] ?? null, '0px' );
					$y      = $value_or_default( $shadow['yOffset'] ?? null, '0px' );
					$blur   = $value_or_default( $shadow['blurRadius'] ?? null, '0px' );
					$spread = $value_or_default( $shadow['spreadRadius'] ?? null, '0px' );
					$color  = $value_or_default( $shadow['color'] ?? null, 'transparent' );
					$inset  = ! empty( $shadow['inset'] ) ? 'inset ' : '';
					if ( '0px' === $x && '0px' === $y && '0px' === $blur && '0px' === $spread && 'transparent' === $color && '' === $inset ) {
						return null;
					}
					return $inset . $x . ' ' . $y . ' ' . $blur . ' ' . $spread . ' ' . $color;

				case 'transition':
					$transition = $effect['transition'] ?? null;
					if ( ! is_array( $transition ) ) { return null; }
					$prop   = $value_or_default( $transition['property'] ?? null, 'all' );
					$dur    = $value_or_default( $transition['duration'] ?? null, '0s' );
					$timing = $value_or_default( $transition['timingFunction'] ?? null, 'ease' );
					$delay  = $value_or_default( $transition['delay'] ?? null, '0s' );
					if ( 'all' === $prop && '0s' === $dur && 'ease' === $timing && '0s' === $delay ) {
						return null;
					}
					return $prop . ' ' . $dur . ' ' . $timing . ' ' . $delay;

				case 'filter':
					$filter = $effect['filter'] ?? null;
					if ( ! is_array( $filter ) ) { return null; }
					$filters = [];
					if ( ! empty( $filter['blur'] ) ) { $filters[] = 'blur(' . $filter['blur'] . ')'; }
					if ( ! empty( $filter['brightness'] ) && '100%' !== $filter['brightness'] ) { $filters[] = 'brightness(' . $filter['brightness'] . ')'; }
					if ( ! empty( $filter['contrast'] ) && '100%' !== $filter['contrast'] ) { $filters[] = 'contrast(' . $filter['contrast'] . ')'; }
					if ( ! empty( $filter['grayscale'] ) && '0%' !== $filter['grayscale'] ) { $filters[] = 'grayscale(' . $filter['grayscale'] . ')'; }
					if ( ! empty( $filter['hueRotate'] ) && '0deg' !== $filter['hueRotate'] ) { $filters[] = 'hue-rotate(' . $filter['hueRotate'] . ')'; }
					if ( ! empty( $filter['invert'] ) && '0%' !== $filter['invert'] ) { $filters[] = 'invert(' . $filter['invert'] . ')'; }
					if ( ! empty( $filter['opacity'] ) && '100%' !== $filter['opacity'] ) { $filters[] = 'opacity(' . $filter['opacity'] . ')'; }
					if ( ! empty( $filter['saturate'] ) && '100%' !== $filter['saturate'] ) { $filters[] = 'saturate(' . $filter['saturate'] . ')'; }
					if ( ! empty( $filter['sepia'] ) && '0%' !== $filter['sepia'] ) { $filters[] = 'sepia(' . $filter['sepia'] . ')'; }
					return ! empty( $filters ) ? implode( ' ', $filters ) : null;

				case 'text-shadow':
					$text_shadow = $effect['textShadow'] ?? null;
					if ( ! is_array( $text_shadow ) ) { return null; }
					$x     = $value_or_default( $text_shadow['xOffset'] ?? null, '0px' );
					$y     = $value_or_default( $text_shadow['yOffset'] ?? null, '0px' );
					$blur  = $value_or_default( $text_shadow['blurRadius'] ?? null, '0px' );
					$color = $value_or_default( $text_shadow['color'] ?? null, 'transparent' );
					if ( '0px' === $x && '0px' === $y && '0px' === $blur && 'transparent' === $color ) {
						return null;
					}
					return $x . ' ' . $y . ' ' . $blur . ' ' . $color;

				case 'transform':
					return axcelersblocks_build_transform_style( $effect['transform'] ?? null );

				case 'opacity':
					return isset( $effect['opacity'] ) && '' !== $effect['opacity'] && '1' !== $effect['opacity'] ? $effect['opacity'] : null;

				case 'visibility':
					return ! empty( $effect['visibility'] ) && 'visible' !== $effect['visibility'] ? $effect['visibility'] : null;
			}
			return null;
		};

		// ─── list-style reset (item has its own custom marker) ────────────────────
		$item_has_own_icon = ! empty( $attributes['iconSvg'] ) && is_string( $attributes['iconSvg'] ) && false !== strpos( $attributes['iconSvg'], '<svg' );
		if ( $item_has_own_icon ) {
			$rules[] = ".{$class}{list-style:none;}";
		}

		// ─── Base icon colour ─────────────────────────────────────────────────────
		$color = axcelersblocks_sanitize_css_value( $attributes['iconColor'] ?? '' );
		if ( '' !== $color ) {
			$rules[] = ".{$class} .icon{color:{$color};}";
		}

		// ─── Icon size (width/height) + svg fill, normal ──────────────────────────
		if ( isset( $attributes['iconSize'] ) && is_array( $attributes['iconSize'] ) ) {
			$previous_key = '';
			foreach ( $devices as $device => $config ) {
				$sides  = $icon_size_sides( $attributes['iconSize'][ $device ] ?? '' );
				$width  = $sides['width'];
				$height = $sides['height'];
				$key    = $width . '|' . $height;

				if ( ( '' === $width && '' === $height ) || ( 'mobile' !== $device && $key === $previous_key ) ) {
					continue;
				}
				$previous_key = $key;

				$decls = [];
				if ( '' !== $width )  { $decls[] = 'width:' . $width; }
				if ( '' !== $height ) { $decls[] = 'height:' . $height; }
				$rule = sprintf(
					'.%1$s .icon{%2$s;}.%1$s .icon svg{width:100%%;height:100%%;display:block;}',
					$class,
					implode( ';', $decls )
				);
				$rules[] = ! empty( $config['media'] ) ? $config['media'] . ' { ' . $rule . ' }' : $rule;
			}
		}

		// ─── Icon size (width/height) + svg fill, hover ───────────────────────────
		if ( isset( $attributes['iconSize__hover'] ) && is_array( $attributes['iconSize__hover'] ) ) {
			$previous_base_width  = '';
			$previous_base_height = '';
			$previous_hover_key   = '';
			foreach ( $devices as $device => $config ) {
				$hover_sides = $icon_size_sides( $attributes['iconSize__hover'][ $device ] ?? '' );
				$base_sides  = $icon_size_sides( $attributes['iconSize'][ $device ] ?? '' );

				$base_width  = '' !== $base_sides['width']  ? $base_sides['width']  : $previous_base_width;
				$base_height = '' !== $base_sides['height'] ? $base_sides['height'] : $previous_base_height;
				if ( '' !== $base_sides['width'] )  { $previous_base_width  = $base_sides['width']; }
				if ( '' !== $base_sides['height'] ) { $previous_base_height = $base_sides['height']; }

				$width  = ( '' !== $hover_sides['width']  && $hover_sides['width']  !== $base_width )  ? $hover_sides['width']  : '';
				$height = ( '' !== $hover_sides['height'] && $hover_sides['height'] !== $base_height ) ? $hover_sides['height'] : '';

				if ( '' === $width && '' === $height ) {
					continue;
				}
				$key = $width . '|' . $height;
				if ( 'mobile' !== $device && $key === $previous_hover_key ) {
					continue;
				}
				$previous_hover_key = $key;

				$decls = [];
				if ( '' !== $width )  { $decls[] = 'width:' . $width; }
				if ( '' !== $height ) { $decls[] = 'height:' . $height; }
				$rule = sprintf(
					'.%1$s:hover .icon{%2$s;}.%1$s:hover .icon svg{width:100%%;height:100%%;display:block;}',
					$class,
					implode( ';', $decls )
				);
				$rules[] = ! empty( $config['media'] ) ? $config['media'] . ' { ' . $rule . ' }' : $rule;
			}
		}

		// ─── Icon position + effect (accumulate per device, mobile-first cascade) ──
		$position_rules = [
			[ 'property' => 'position',   'value' => $attributes['iconPosition'] ?? null ],
			[ 'property' => 'top',        'value' => $attributes['iconInset'] ?? null, 'edge' => 'top' ],
			[ 'property' => 'right',      'value' => $attributes['iconInset'] ?? null, 'edge' => 'right' ],
			[ 'property' => 'bottom',     'value' => $attributes['iconInset'] ?? null, 'edge' => 'bottom' ],
			[ 'property' => 'left',       'value' => $attributes['iconInset'] ?? null, 'edge' => 'left' ],
			[ 'property' => 'overflow-x', 'value' => $attributes['iconOverflowX'] ?? null ],
			[ 'property' => 'overflow-y', 'value' => $attributes['iconOverflowY'] ?? null ],
			[ 'property' => 'z-index',    'value' => $attributes['iconZIndex'] ?? null ],
		];
		$effect_properties = [ 'box-shadow', 'transition', 'filter', 'text-shadow', 'transform', 'opacity', 'visibility' ];

		// Accumulate declarations per device with a property-keyed mobile-first cascade.
		$collect = function ( $position_rules, $effect_attr ) use ( $devices, $attributes, $icon_effect_to_css, $effect_properties ) {
			$dev     = [ 'mobile' => [], 'tablet' => [], 'desktop' => [] ];
			$cascade = [];
			$push    = function ( $device, $property, $value ) use ( &$dev, &$cascade ) {
				$value = axcelersblocks_sanitize_css_value( $value );
				if ( '' === $value ) { return; }
				if ( 'mobile' !== $device && isset( $cascade[ $property ] ) && $cascade[ $property ] === $value ) { return; }
				$cascade[ $property ] = $value;
				$dev[ $device ][]     = $property . ': ' . $value . ';';
			};
			foreach ( $position_rules as $rule ) {
				foreach ( $devices as $device => $config ) {
					$device_value = $rule['value'][ $device ] ?? '';
					if ( isset( $rule['edge'] ) && is_array( $device_value ) ) {
						$device_value = $device_value[ $rule['edge'] ] ?? '';
					}
					$push( $device, $rule['property'], $device_value );
				}
			}
			foreach ( $effect_properties as $property ) {
				foreach ( $devices as $device => $config ) {
					$effect_value = $attributes[ $effect_attr ][ $device ] ?? null;
					$push( $device, $property, $icon_effect_to_css( $effect_value, $property ) );
				}
			}
			return $dev;
		};

		$icon_dev       = $collect( $position_rules, 'iconEffect' );
		$hover_position = [
			[ 'property' => 'position',   'value' => $attributes['iconPosition__hover'] ?? null ],
			[ 'property' => 'top',        'value' => $attributes['iconInset__hover'] ?? null, 'edge' => 'top' ],
			[ 'property' => 'right',      'value' => $attributes['iconInset__hover'] ?? null, 'edge' => 'right' ],
			[ 'property' => 'bottom',     'value' => $attributes['iconInset__hover'] ?? null, 'edge' => 'bottom' ],
			[ 'property' => 'left',       'value' => $attributes['iconInset__hover'] ?? null, 'edge' => 'left' ],
			[ 'property' => 'overflow-x', 'value' => $attributes['iconOverflowX__hover'] ?? null ],
			[ 'property' => 'overflow-y', 'value' => $attributes['iconOverflowY__hover'] ?? null ],
			[ 'property' => 'z-index',    'value' => $attributes['iconZIndex__hover'] ?? null ],
		];
		$icon_hover_dev = $collect( $hover_position, 'iconEffect__hover' );

		foreach ( $devices as $device => $config ) {
			if ( ! empty( $icon_dev[ $device ] ) ) {
				$rule = ".{$class} .icon { " . implode( ' ', $icon_dev[ $device ] ) . ' }';
				$rules[] = ! empty( $config['media'] ) ? $config['media'] . ' { ' . $rule . ' }' : $rule;
			}
		}
		foreach ( $devices as $device => $config ) {
			if ( ! empty( $icon_hover_dev[ $device ] ) ) {
				$rule = ".{$class}:hover .icon { " . implode( ' ', $icon_hover_dev[ $device ] ) . ' }';
				$rules[] = ! empty( $config['media'] ) ? $config['media'] . ' { ' . $rule . ' }' : $rule;
			}
		}

		// ─── Icon colour, hover ───────────────────────────────────────────────────
		$hover_color = axcelersblocks_sanitize_css_value( $attributes['iconColor__hover'] ?? '' );
		if ( '' !== $hover_color ) {
			$rules[] = ".{$class}:hover .icon{color:{$hover_color};}";
			$rules[] = ".{$class}:hover .icon svg{fill:currentColor;}";
		}

		return $rules;
	}
}
