<?php
/**
 * Global helper functions for Firevert.
 *
 * Provides shortcuts for accessing services, paths, views and logging.
 *
 * @package Ilabs\Firevert\Core
 */

use Ilabs\Firevert\Core\Exceptions\MissingServiceContainerException;
use Ilabs\Firevert\Core\Exceptions\ViewNotFoundException;
use Ilabs\Firevert\Core\ServiceContainer;
use Ilabs\Firevert\Core\Services\Helper\Integration\LanguageHelper;
use Ilabs\Firevert\Core\Services\LoggerService;
use Ilabs\Firevert\Core\Services\Resolver\PathResolver;

if ( ! function_exists( 'firevert_container' ) ) {
	/**
	 * Global accessor for the Firevert DI container.
	 *
	 * @param ServiceContainer|null $set Optional: set container instance.
	 * @param bool                  $throw_if_missing Whether to throw exception if container is not set.
	 *
	 * @return ServiceContainer The service container instance.
	 * @throws MissingServiceContainerException When container is not set and $throw_if_missing is true.
	 */
	function firevert_container( ?ServiceContainer $set = null, bool $throw_if_missing = true ): ServiceContainer {
		static $container = null;

		if ( $set instanceof ServiceContainer ) {
			$container = $set;
		}

		if ( null === $container && $throw_if_missing ) {
			throw new MissingServiceContainerException(
				'Service Container does not exists. Please check your config and Service Container registration.'
			);
		}

		return $container;
	}
}

if ( ! function_exists( 'firevert_path' ) ) {
	/**
	 * Returns a resolved path using the PathResolver service.
	 *
	 * @param string $subpath Optional subpath inside the selected type.
	 * @param string $type One of: core, modules, module, module_view, resources.
	 * @param string $module_slug Optional module slug (for type 'module' or 'module_view').
	 *
	 * @return string Absolute resolved path.
	 */
	function firevert_path( string $subpath = '', string $type = '', string $module_slug = '' ): string {
		/**
		 * Get from DI container.
		 *
		 * @var PathResolver $resolver
		 */
		$resolver = firevert_container()->get( 'path_resolver' );

		switch ( $type ) {
			case 'core':
				return $resolver->get_core_path( $subpath );
			case 'modules':
				return $resolver->get_modules_path( $subpath );
			case 'module':
				return $resolver->get_module_path( $module_slug, $subpath );
			case 'module_view':
				return $resolver->get_module_view_path( $module_slug, $subpath );
			case 'resources':
				return $resolver->get_resources_path( $subpath );
			default:
				return $resolver->get_base_path() . '/' . $subpath;
		}
	}
}

if ( ! function_exists( 'firevert_view' ) ) {
	/**
	 * Renders and immediately outputs a view file with provided variables.
	 *
	 * @param string $relative_path Relative path to the view file (inside /resources/views/).
	 * @param array  $variables Associative array of variables to be extracted in the view.
	 *
	 * @return void
	 * @throws ViewNotFoundException If the view file does not exist.
	 */
	function firevert_view( string $relative_path, array $variables = array() ): void {
		$full_path = firevert_path( 'resources/views/' . ltrim( $relative_path, '/' ) );

		if ( ! file_exists( $full_path ) ) {
			throw new ViewNotFoundException(
				sprintf( 'View not found: %s', esc_html( $full_path ) )
			);
		}

		call_user_func(
			static function () use ( $full_path, $variables ) {
				foreach ( $variables as $__var_name => $__value ) {
					$$__var_name = $__value;
				}

				require $full_path;
			}
		);
	}
}

if ( ! function_exists( 'firevert_module_view' ) ) {
	/**
	 * Renders and immediately outputs a view from a specific module.
	 *
	 * @param string $module_folder Module slug (e.g. 'power_widget').
	 * @param string $relative_path Relative path to the view file inside module /resources/views/.
	 * @param array  $variables Associative array of variables to extract in view.
	 *
	 * @return void
	 * @throws ViewNotFoundException If the view file does not exist.
	 */
	function firevert_module_view( string $module_folder, string $relative_path, array $variables = array() ): void {
		$full_path = firevert_path(
			ltrim( $relative_path, '/' ),
			'module_view',
			$module_folder
		);

		if ( ! file_exists( $full_path ) ) {
			throw new ViewNotFoundException(
				sprintf( 'Module view not found: %s', esc_html( $full_path ) )
			);
		}

		call_user_func(
			static function () use ( $full_path, $variables ) {
				foreach ( $variables as $__var_name => $__value ) {
					$$__var_name = $__value;
				}

				require $full_path;
			}
		);
	}
}

if ( ! function_exists( 'firevert_log' ) ) {
	/**
	 * Returns the logger service from the container.
	 *
	 * @return LoggerService|null Logger service or null if not available.
	 */
	function firevert_log(): ?LoggerService {
		return firevert_container()->get( 'logger' );
	}
}

if ( ! function_exists( 'firevert_url' ) ) {
	/**
	 * Returns a resolved URL relative to the plugin base directory.
	 *
	 * @param string $relative_path Relative path inside the plugin directory.
	 *
	 * @return string Fully resolved URL.
	 */
	function firevert_url( string $relative_path = '' ): string {
		$base_url = plugins_url( '/', dirname( __DIR__, 2 ) . '/firevert.php' );

		return trailingslashit( $base_url ) . ltrim( $relative_path, '/' );
	}
}

if ( ! function_exists( 'firevert_label_with_lang' ) ) {
	/**
	 * Appends active language suffix (e.g. (PL)) to label if multi-language is active.
	 *
	 * @param string $label Raw label text.
	 *
	 * @return string Modified label with language suffix or original.
	 */
	function firevert_label_with_lang( string $label ): string {
		$active = LanguageHelper::get_active_region_code() ?? get_locale();

		return sprintf( '%s (%s)', $label, $active );
	}
}
