<?php
/**
 * Class responsible for loading JS and CSS assets.
 */

namespace BoostsiteAIContentGenerator;

/**
 * Scripts and styles helper.
 */
class Assets {

	/**
	 * The application domain.
	 *
	 * @var string
	 */
	private $prefix;

	/**
	 * Initialize this class.
	 *
	 * @param string $prefix Plugin prefix.
	 */
	public function __construct( $prefix ) {
		$this->prefix = $prefix;
		add_action( is_admin() ? 'admin_enqueue_scripts' : 'wp_enqueue_scripts', array( $this, 'register' ) );
	}

	/**
	 * Register our app scripts and styles.
	 *
	 * @return void
	 */
	public function register() {
		$this->register_scripts( $this->get_scripts() );
		$this->register_styles( $this->get_styles() );
	}

	/**
	 * Register scripts.
	 *
	 * @param  array $scripts Scripts to register.
	 *
	 * @return void
	 */
	private function register_scripts( $scripts ) {
		foreach ( $scripts as $handle => $script ) {
			$deps      = isset( $script['deps'] ) ? $script['deps'] : false;
			$in_footer = isset( $script['in_footer'] ) ? $script['in_footer'] : false;

			wp_register_script( $handle, $script['src'], $deps, null, $in_footer );
		}
	}

	/**
	 * Register styles.
	 *
	 * @param  array $styles Styles to register.
	 *
	 * @return void
	 */
	public function register_styles( $styles ) {
		foreach ( $styles as $handle => $style ) {
			$deps = isset( $style['deps'] ) ? $style['deps'] : false;

			wp_register_style( $handle, $style['src'], $deps, null );
		}
	}

	/**
	 * Get all registered scripts.
	 *
	 * @return array
	 */
	public function get_scripts() {
		$assets_url = \BoostsiteAIContentGenerator\Main::$base_url . '/public';
		$plugin_dir = \BoostsiteAIContentGenerator\Main::$plugin_dir . '/public';
		$prefix     = ''; // defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.min' : '';.

		$scripts = array(
			'vuejs'                     => array(
			'src'       => \BoostsiteAIContentGenerator\Main::$base_url . '/assets/js/vue.global.prod.js',
			'in_footer' => true,
		),
			$this->prefix . '-manifest' => array(
				'src'       => $assets_url . $this->mix( '/js/manifest.js' ),
				'in_footer' => true,
			),
			$this->prefix . '-vendor'   => array(
				'src'       => $assets_url . $this->mix( '/js/vendor.js' ),
				'deps'      => array( 'vuejs', $this->prefix . '-manifest' ),
				'in_footer' => true,
			),
			$this->prefix . '-admin'    => array(
				'src'       => $assets_url . $this->mix( '/js/admin.js' ),
				'deps'      => array( $this->prefix . '-vendor' ),
				'in_footer' => true,
			),
			$this->prefix . '-auth-callback' => array(
				'src'       => \BoostsiteAIContentGenerator\Main::$base_url . '/assets/js/authorization-callback.js',
				'in_footer' => true,
			),
		);

		return $scripts;
	}

	/**
	 * Get registered styles.
	 *
	 * @return array
	 */
	public function get_styles() {
		$assets_url = \BoostsiteAIContentGenerator\Main::$base_url . '/public';

		$styles = array(
			$this->prefix . '-admin'     => array(
				'src' => $assets_url . $this->mix( '/css/admin.css' ),
			),
		);

		return $styles;
	}

	/**
	 * Get the path to a versioned Mix file.
	 *
	 * @param  string $path Path.
	 * @param  string $manifest_directory Directory with the manifest.
	 * @return string
	 * @throws \Exception Error if mix file is not found.
	 */
	public function mix( $path, $manifest_directory = '' ) {
		static $manifests = array();

		if ( empty( $manifest_directory ) ) {
			$manifest_directory = \BoostsiteAIContentGenerator\Main::$plugin_dir . '/public';
		}

		$manifest_path = $manifest_directory . '/mix-manifest.json';

		if ( ! isset( $manifests[ $manifest_path ] ) ) {
			if ( ! is_file( $manifest_path ) ) {
				throw new \Exception( 'The Mix manifest does not exist in: ' . esc_attr( $manifest_path ) );
			}

			$manifests[ $manifest_path ] = json_decode( file_get_contents( $manifest_path ), true );
		}

		$manifest = $manifests[ $manifest_path ];

		if ( ! isset( $manifest[ $path ] ) ) {
			throw new \Exception( 'Unable to locate Mix file: ' . esc_attr( $manifest_path ) );
		}

		return $manifest[ $path ];
	}
}
