<?php
/**
 * Vite.
 *
 * @package MadeByAura\Prime\Helpers
 * @author  MadeByAura.com
 */

namespace MadeByAura\Prime\Helpers;

use MadeByAura\Prime\Base;

defined( 'ABSPATH' ) || die();

/**
 * Vite.
 */
class Vite {
	/**
	 * Check if the vite dev server is running.
	 *
	 * @return boolean
	 */
	public static function is_dev_running() {
		$remote_address = null;

		if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
			$remote_address = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
		}

		// Do not proceed if the site is not being served form a local server.
		if ( '127.0.0.1' !== $remote_address ) {
			return false;
		}

		// Get path for the dev flag.
		$path = Base::get_info( 'path' ) . '.ignore/vite-dev-flag';

		return file_exists( $path );
	}

	/**
	 * Get manifest data.
	 *
	 * @return array
	 */
	public static function get_manifest() {
		static $json;

		if ( $json ) {
			return $json;
		}

		$file_path    = Base::get_info( 'path' ) . 'dist/manifest.json';
		$file_content = Assorted::get_file_content( $file_path );
		$json         = json_decode( $file_content, true );

		return $json;
	}

	/**
	 * Get scripts data.
	 *
	 * @return array
	 */
	public static function get_scripts() {
		static $json;

		if ( $json ) {
			return $json;
		}

		$file_path    = Base::get_info( 'path' ) . 'scripts.json';
		$file_content = Assorted::get_file_content( $file_path );
		$json         = json_decode( $file_content, true );

		return $json;
	}

	/**
	 * Get asset url.
	 *
	 * @param string $id  File ID.
	 * @return string
	 */
	public static function get_asset_url( $id ) {
		// Return dev server URL for the asset if the dev server is running.
		if ( self::is_dev_running() ) {
			return 'http://localhost:3500/' . $id;
		}

		// Get relative path.
		$relative_path = self::get_manifest()[ $id ]['file'] ?? null;

		// Do not proceed if there is no relative path.
		if ( ! $relative_path ) {
			return;
		}

		return Base::get_info( 'url' ) . 'dist/' . $relative_path;
	}

	/**
	 * Echo asset url.
	 *
	 * @param string $id  File ID.
	 */
	public static function echo_asset_url( $id ) {
		echo esc_url( self::get_asset_url( $id ) );
	}

	/**
	 * Enqueue scripts.
	 *
	 * @param string $id  Script ID.
	 */
	public static function enqueue_scripts( $id ) {
		if ( self::is_dev_running() ) {
			self::enqueue_dev_scripts( $id );
		} else {
			self::enqueue_production_scripts( $id );
		}
	}

	/**
	 * Enqueue dev script.
	 *
	 * @param string $id  Script ID.
	 */
	public static function enqueue_dev_scripts( $id ) {
		$script = self::get_scripts()[ $id ] ?? null;

		if ( ! $script ) {
			return;
		}

		$handle   = Base::get_info( 'slug' ) . '-' . $id;
		$src_path = $script['directory'] . '/' . $id . '.js';
		$url      = 'http://localhost:3500/' . $src_path;

		wp_enqueue_script(
			$handle,
			$url,
			[ 'jquery' ],
			'1.0.0',
			true,
		);

		// Change type attribute to module.
		wp_scripts()->add_data( $handle, 'type', 'module' );
	}

	/**
	 * Enqueue production scripts.
	 *
	 * @param string $id  Script ID.
	 */
	public static function enqueue_production_scripts( $id ) {
		$scripts  = self::get_scripts();
		$manifest = self::get_manifest();

		$script = $scripts[ $id ] ?? null;

		if ( ! $script ) {
			return;
		}

		if ( in_array( 'css', $script['enqueue'], true ) ) {
			$src_path   = $script['directory'] . '/' . $id . '.css';
			$asset_path = $manifest[ $src_path ]['file'] ?? null;

			if ( $asset_path ) {
				$handle = Base::get_info( 'slug' ) . '-' . $id;
				$url    = Base::get_info( 'url' ) . 'dist/' . $asset_path;

				wp_enqueue_style(
					$handle,
					$url,
					[],
					'1.0.0',
				);
			}
		}

		if ( in_array( 'js', $script['enqueue'], true ) ) {
			$src_path   = $script['directory'] . '/' . $id . '.js';
			$asset_path = $manifest[ $src_path ]['file'] ?? null;

			if ( $asset_path ) {
				$handle = Base::get_info( 'slug' ) . '-' . $id;
				$url    = Base::get_info( 'url' ) . 'dist/' . $asset_path;

				wp_enqueue_script(
					$handle,
					$url,
					[ 'jquery' ],
					'1.0.0',
					true,
				);

				// Change type attribute to module.
				wp_scripts()->add_data( $handle, 'type', 'module' );
			}
		}
	}

	/**
	 * Change type attribute, if it is defined in the script data.
	 *
	 * @param string $tag     The <script> tag for the enqueued script.
	 * @param string $handle  The script's registered handle.
	 * @return string
	 */
	public static function script_change_type_attr( $tag, $handle ) {
		$type = wp_scripts()->get_data( $handle, 'type' );

		// Do not do anything if there is no type.
		if ( ! $type ) {
			return $tag;
		}

		// Replace the type attribute and return.
		return str_replace(
			[ 'type="text/javascript"', "type='text/javascript'" ],
			sprintf( 'type="%s"', esc_attr( $type ) ),
			$tag
		);
	}
}
