<?php
/**
 * Color Variable Processor
 *
 * @package Brandy\DynamicCss\Processors
 */

namespace Brandy\DynamicCss\Processors;

use Brandy\Utils\Helpers;
use Brandy\Utils\StylesDataHelpers;

/**
 * Processor for color group CSS variables
 */
class ColorVariableProcessor extends AbstractVariableProcessor {

	/**
	 * Check if this processor supports the given type
	 *
	 * @param string $type Variable type.
	 * @return bool
	 */
	public function supports( string $type ): bool {
		return 'color' === $type;
	}

	/**
	 * Process color group variable data
	 *
	 * @param array $variable_data Variable configuration.
	 * @return array Device-keyed CSS variables
	 */
	public function process( array $variable_data ): array {
		$result = $this->responsive_helper->get_empty_device_result();

		if ( empty( $variable_data['value'] ) ) {
			return $result;
		}

		$selector = $variable_data['selector'] ?? '';

		foreach ( $variable_data['value'] as $color_type => $color_value ) {
			if ( 'enabled_gradient' === $color_type ) {
				continue;
			}

			if ( StylesDataHelpers::is_responsive_data( $color_value ) ) {
				$this->process_responsive_color( $result, $variable_data, $color_type, $color_value, $selector );
			} else {
				$this->process_non_responsive_color( $result, $variable_data, $color_type, $color_value, $selector );
			}
		}

		return $result;
	}

	/**
	 * Process responsive color value
	 *
	 * @param array  $result        Result array (passed by reference).
	 * @param array  $variable_data Variable configuration.
	 * @param string $color_type    Color type (normal, hover, etc).
	 * @param array  $color_value   Responsive color value.
	 * @param string $selector      CSS selector.
	 * @return void
	 */
	private function process_responsive_color( array &$result, array $variable_data, string $color_type, array $color_value, string $selector ): void {
		foreach ( $color_value as $device => $variable_value ) {
			if ( ! in_array( $device, brandy_get_devices(), true ) ) {
				continue;
			}

			$variable_value = Helpers::get_device_value( $color_value, $device );
			$variable_value = $this->resolve_color_fallback( $variable_value, $color_type, $variable_data, $device );

			$css_var = StylesDataHelpers::get_css_variable( $variable_data['name'] . '-' . $color_type, $variable_value );
			$this->responsive_helper->add_to_result( $result, $device, $selector, $css_var );
		}
	}

	/**
	 * Process non-responsive color value
	 *
	 * @param array  $result        Result array (passed by reference).
	 * @param array  $variable_data Variable configuration.
	 * @param string $color_type    Color type (normal, hover, etc).
	 * @param mixed  $color_value   Color value.
	 * @param string $selector      CSS selector.
	 * @return void
	 */
	private function process_non_responsive_color( array &$result, array $variable_data, string $color_type, $color_value, string $selector ): void {
		$resolved_value = $this->resolve_non_responsive_fallback( $color_value, $color_type, $variable_data );

		$css_var = StylesDataHelpers::get_css_variable( $variable_data['name'] . '-' . $color_type, $resolved_value );
		$this->responsive_helper->add_to_result( $result, 'desktop', $selector, $css_var );
	}

	/**
	 * Resolve color fallback for responsive values
	 *
	 * @param mixed  $value         Current color value.
	 * @param string $color_type    Color type.
	 * @param array  $variable_data Variable configuration.
	 * @param string $device        Current device.
	 * @return string Resolved color value
	 */
	private function resolve_color_fallback( $value, string $color_type, array $variable_data, string $device ): string {
		$hover_value  = Helpers::get_device_value( $variable_data['value']['hover'] ?? [], $device );
		$normal_value = Helpers::get_device_value( $variable_data['value']['normal'] ?? [], $device );

		if ( empty( $value ) && 'normal' !== $color_type ) {
			$value = $hover_value;
		}
		if ( empty( $value ) ) {
			$value = $normal_value;
		}
		if ( empty( $value ) ) {
			$value = 'currentColor';
		}

		return $value;
	}

	/**
	 * Resolve color fallback for non-responsive values
	 *
	 * @param mixed  $value         Current color value.
	 * @param string $color_type    Color type.
	 * @param array  $variable_data Variable configuration.
	 * @return string Resolved color value
	 */
	private function resolve_non_responsive_fallback( $value, string $color_type, array $variable_data ): string {
		if ( empty( $value ) && 'normal' !== $color_type ) {
			$value = $variable_data['value']['hover'] ?? '';
		}
		if ( empty( $value ) ) {
			$value = $variable_data['value']['normal'] ?? '';
		}
		if ( empty( $value ) ) {
			$value = 'currentColor';
		}

		return $value;
	}
}
