<?php
namespace SabaiApps\Directories;

use SabaiApps\Directories\Platform\AbstractPlatform;

/**
 * Assets class for managing and registering application assets such as JS, CSS, and images.
 * Provides methods for adding, retrieving, and loading assets into the platform.
 */
class Assets {

	protected $_assets;

	/**
	 * Constructor.
	 *
	 * @param array $assets Initial assets array.
	 */
	public function __construct( array $assets = array() ) {
		$this->_assets = $assets;
	}

	/**
	 * Adds a head element.
	 *
	 * @param string $handle
	 * @param string $head
	 * @param int    $index
	 */
	public function addHead( $handle, $head, $index = 10 ) {
		$this->_assets['head'][ $handle ] = array( $head, $index );
	}

	/**
	 * Adds a JavaScript file.
	 *
	 * @param string      $handle
	 * @param string      $file
	 * @param string|null $dependency
	 * @param string|null $package
	 * @param bool        $inFooter
	 * @param bool        $vendor
	 * @param string|null $version
	 */
	public function addJsFile( $handle, $file, $dependency = null, $package = null, $inFooter = true, $vendor = false, $version = null ) {
		if ( empty( $file ) ) {
			unset( $this->_assets['js_files'][ $handle ] );
		} else {
			$this->_assets['js_files'][ $handle ] = array( $file, $dependency, $package, $inFooter, $vendor, $version );
		}
	}

	/**
	 * Adds a JavaScript module file.
	 *
	 * @param string      $id
	 * @param string      $file
	 * @param string|null $dependency
	 * @param string|null $package
	 * @param bool        $vendor
	 * @param string|null $version
	 */
	public function addJsModuleFile( $id, $file, $dependency = null, $package = null, $vendor = false, $version = null ) {
		if ( empty( $file ) ) {
			unset( $this->_assets['js_modules'][ $id ] );
		} else {
			$this->_assets['js_modules'][ $id ] = array( $file, $dependency, $package, $vendor, $version );
		}
	}

	/**
	 * Adds a JavaScript snippet.
	 *
	 * @param string $js
	 * @param bool   $onDomReady
	 * @param int    $index
	 */
	public function addJs( $js, $onDomReady = true, $index = 10 ) {
		$this->_assets['js'][] = array( $js, $onDomReady, $index );
	}

	/**
	 * Adds an inline JavaScript snippet.
	 *
	 * @param string $dependency
	 * @param string $js
	 * @param bool   $onDomReady
	 * @param string $position
	 */
	public function addJsInline( $dependency, $js, $onDomReady = false, $position = 'after' ) {
		$this->_assets['js_inline'][] = array( $dependency, $js, $onDomReady, $position );
	}

	/**
	 * Adds a CSS file.
	 *
	 * @param string      $handle
	 * @param string      $file
	 * @param string|null $dependency
	 * @param string|null $package
	 * @param string|null $media
	 * @param bool        $vendor
	 * @param string|null $version
	 */
	public function addCssFile( $handle, $file, $dependency = null, $package = null, $media = null, $vendor = false, $version = null ) {
		if ( empty( $file ) ) {
			unset( $this->_assets['css_files'][ $handle ] );
		} else {
			$this->_assets['css_files'][ $handle ] = array( $file, $dependency, $package, $media, $vendor, $version );
		}
	}

	/**
	 * Adds a CSS snippet.
	 *
	 * @param string      $css
	 * @param string|null $targetHandle
	 */
	public function addCss( $css, $targetHandle = null ) {
		$this->_assets['css'][] = array( $css, $targetHandle );
	}

	/**
	 * Gets all registered assets.
	 *
	 * @return array
	 */
	public function getAssets() {
		return $this->_assets;
	}

	/**
	 * Adds jQuery UI JavaScript components.
	 *
	 * @param string|array $component
	 */
	public function addJqueryUiJs( $component ) {
		foreach ( (array) $component as $_component ) {
			$this->_assets['jquery_ui_js_components'][ $_component ] = $_component;
		}
	}

	/**
	 * Adds the imagesLoaded JavaScript library.
	 */
	public function addImagesLoadedJs() {
		$this->_assets['images_loaded_js'] = true;
	}

	/**
	 * Loads all assets into the platform.
	 *
	 * @param AbstractPlatform $platform
	 * @param array            $assets
	 */
	public static function load( AbstractPlatform $platform, array $assets ) {
		if ( ! empty( $assets['head'] ) ) {
			foreach ( $assets['head'] as $handle => $head ) {
				$platform->addHead( $head[0], $handle, $head[1] );
			}
		}
		if ( ! empty( $assets['js_files'] ) ) {
			foreach ( $assets['js_files'] as $handle => $file ) {
				$platform->addJsFile(
					$file[0],
					$handle,
					isset( $file[1] ) ? $file[1] : null,
					isset( $file[2] ) ? $file[2] : null,
					! empty( $file[3] ), // in footer
					! empty( $file[4] ), // vendor
					isset( $file[5] ) ? $file[5] : null // version
				);
			}
		}
		if ( ! empty( $assets['js_modules'] ) ) {
			foreach ( $assets['js_modules'] as $id => $file ) {
				$platform->addJsFile(
					$file[0],
					$id,
					isset( $file[1] ) ? $file[1] : null,
					isset( $file[2] ) ? $file[2] : null,
					! empty( $file[3] ), // vendor
					isset( $file[4] ) ? $file[4] : null // version
				);
			}
		}
		if ( ! empty( $assets['css_files'] ) ) {
			foreach ( $assets['css_files'] as $handle => $file ) {
				$platform->addCssFile(
					$file[0],
					$handle,
					isset( $file[1] ) ? $file[1] : null,
					isset( $file[2] ) ? $file[2] : null,
					isset( $file[3] ) ? $file[3] : null,
					! empty( $file[4] ), // vendor
					isset( $file[5] ) ? $file[5] : null // version
				);
			}
		}
		if ( ! empty( $assets['js_inline'] ) ) {
			foreach ( $assets['js_inline'] as $js ) {
				$platform->addJsInline( $js[0], $js[1], $js[2], $js[3] );
			}
		}
		if ( ! empty( $assets['js'] ) ) {
			foreach ( $assets['js'] as $js ) {
				$platform->addJs(
					$js[0], // js
					$js[1] ?? true, // onDomReady
					$js[2] ?? 10 // index
				);
			}
		}
		if ( ! empty( $assets['css'] ) ) {
			foreach ( $assets['css'] as $css ) {
				$platform->addCss( $css[0], $css[1] );
			}
		}
		if ( ! empty( $assets['jquery_ui_js_components'] ) ) {
			$platform->loadJqueryUiJs( $assets['jquery_ui_js_components'] );
		}
		if ( ! empty( $assets['images_loaded_js'] ) ) {
			$platform->loadImagesLoadedJs();
		}
	}
}
