<?php
/**
 * Vite Asset Loader for Replyan AI.
 *
 * Resolves entry points and chunk dependencies from the Vite manifest
 * to ensure all assets are hashed and cache-immune in production.
 *
 * @package Replyan_AI
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class Replyan_AI_Assets {

	/**
	 * Cached manifest array.
	 *
	 * @var array<string, mixed>|null
	 */
	private static ?array $manifest = null;

	/**
	 * Retrieve and parse the Vite build manifest.
	 *
	 * @return array<string, mixed>
	 */
	public static function get_manifest(): array {
		if ( null !== self::$manifest ) {
			return self::$manifest;
		}

		$manifest_path = REPLYAN_AI_DIR . 'dist/.vite/manifest.json';

		// Fallback for setups outputting manifest directly into dist/
		if ( ! file_exists( $manifest_path ) ) {
			$manifest_path = REPLYAN_AI_DIR . 'dist/manifest.json';
		}

		if ( file_exists( $manifest_path ) ) {
			$content = file_get_contents( $manifest_path );
			if ( false !== $content ) {
				$data = json_decode( $content, true );
				if ( is_array( $data ) ) {
					self::$manifest = $data;
					return self::$manifest;
				}
			}
		}

		self::$manifest = array();
		return self::$manifest;
	}

	/**
	 * Enqueue a Vite entrypoint and its associated stylesheets.
	 *
	 * @param string $handle    The script and style handle.
	 * @param string $entry     The Vite input entry key (e.g., 'src/admin/main.jsx').
	 * @param array  $deps      Script dependencies (e.g. array('wp-element')).
	 * @param bool   $in_footer Whether to enqueue the script in the footer.
	 * @return void
	 */
	public static function enqueue( string $handle, string $entry, array $deps = array(), bool $in_footer = true ): void {
		$manifest = self::get_manifest();

		if ( isset( $manifest[ $entry ] ) ) {
			$item = $manifest[ $entry ];

			// Enqueue CSS files generated for this entry
			if ( ! empty( $item['css'] ) && is_array( $item['css'] ) ) {
				foreach ( $item['css'] as $index => $css_file ) {
					$css_handle = 0 === $index ? $handle : "{$handle}-{$index}";
					wp_enqueue_style(
						$css_handle,
						REPLYAN_AI_URL . 'dist/' . $css_file,
						array(),
						null
					);
				}
			}

			// Enqueue main JS entry file
			if ( ! empty( $item['file'] ) ) {
				wp_enqueue_script(
					$handle,
					REPLYAN_AI_URL . 'dist/' . $item['file'],
					$deps,
					null,
					$in_footer
				);
				wp_script_add_data( $handle, 'type', 'module' );
			}

			return;
		}

		// Fallback for unmanifested / legacy builds
		$fallback_name = str_contains( $entry, 'admin' ) ? 'admin' : 'frontend';
		$css_path      = REPLYAN_AI_DIR . "dist/{$fallback_name}.css";
		$js_path       = REPLYAN_AI_DIR . "dist/{$fallback_name}.js";

		if ( file_exists( $css_path ) ) {
			wp_enqueue_style(
				$handle,
				REPLYAN_AI_URL . "dist/{$fallback_name}.css",
				array(),
				filemtime( $css_path )
			);
		}

		if ( file_exists( $js_path ) ) {
			wp_enqueue_script(
				$handle,
				REPLYAN_AI_URL . "dist/{$fallback_name}.js",
				$deps,
				filemtime( $js_path ),
				$in_footer
			);
			wp_script_add_data( $handle, 'type', 'module' );
		}
	}
}
