<?php
/**
 * CSS Output Builder
 *
 * @package Brandy\DynamicCss
 */

namespace Brandy\DynamicCss;

/**
 * Builds and outputs CSS from variable data
 */
class CssOutputBuilder {

	/**
	 * Responsive helper instance
	 *
	 * @var ResponsiveHelper
	 */
	private ResponsiveHelper $responsive_helper;

	/**
	 * Tracked rendered elements to prevent duplicates
	 *
	 * @var array
	 */
	private array $rendered_elements = [];

	/**
	 * Constructor
	 *
	 * @param ResponsiveHelper $responsive_helper Responsive helper instance.
	 */
	public function __construct( ResponsiveHelper $responsive_helper ) {
		$this->responsive_helper = $responsive_helper;
	}

	/**
	 * Reset rendered elements state
	 *
	 * @return void
	 */
	public function reset_state(): void {
		$this->rendered_elements = [];
	}

	/**
	 * Build device CSS from variables
	 *
	 * @param array  $variables Variables by device.
	 * @param string $selector  Base selector.
	 * @return array Device CSS strings
	 */
	public function build_device_css( array $variables, string $selector ): array {
		$device_css = [
			'desktop' => '',
			'tablet'  => '',
			'mobile'  => '',
		];

		foreach ( $variables as $device => $data ) {
			$with_selector_css = [];

			foreach ( $data as $sel => $css_data ) {
				$key = 'root';
				if ( ! empty( $sel ) && is_string( $sel ) ) {
					$key      = $sel;
					$css_data = implode( ';', $css_data );
				}
				if ( ! isset( $with_selector_css[ $key ] ) ) {
					$with_selector_css[ $key ] = [];
				}
				$with_selector_css[ $key ][] = $css_data;
			}

			if ( ! empty( $with_selector_css ) ) {
				foreach ( $with_selector_css as $sel => $css_data ) {
					$full_selector           = ( 'root' === $sel ) ? $selector : ( $selector . ' ' . $sel );
					$device_css[ $device ] .= $full_selector . '{' . implode( ';', $css_data ) . '}';
				}
			}
		}

		return $device_css;
	}

	/**
	 * Output device CSS with deduplication and media queries
	 *
	 * @param array $device_css        Device CSS strings.
	 * @param array $input_data        Element configuration.
	 * @param array $available_devices Available devices.
	 * @return string Combined CSS output
	 */
	public function output_device_css( array $device_css, array $input_data, array $available_devices ): string {
		$result = '';

		foreach ( $device_css as $device => $css ) {
			if ( empty( $css ) ) {
				continue;
			}

			$passed_id = $input_data['id'] . '-' . $input_data['builder'] . '-' . $device;

			if ( ! empty( $this->rendered_elements[ $passed_id ] ) ) {
				continue;
			}

			if ( 'desktop' === $device ) {
				$result                               .= $css;
				$this->rendered_elements[ $passed_id ] = true;
				continue;
			}

			if ( ! in_array( $device, $available_devices, true ) ) {
				continue;
			}

			if ( ! in_array( $device, brandy_get_devices(), true ) ) {
				continue;
			}

			if ( 'tablet' === $device ) {
				$css = $this->responsive_helper->wrap_tablet_responsive( $css );
			}
			if ( 'mobile' === $device ) {
				$css = $this->responsive_helper->wrap_mobile_responsive( $css );
			}

			$this->rendered_elements[ $passed_id ] = true;
			$result                               .= $css;
		}

		return $result;
	}
}
