<?php
/**
 * PromoTimeWidget module initializer.
 *
 * Registers module settings, assets, and admin rendering logic.
 *
 * @package Ilabs\Firevert\Modules\PromoTimeWidget
 */

declare( strict_types=1 );

namespace Ilabs\Firevert\Modules\PromoTimeWidget;

use Ilabs\Firevert\Core\Repository\Cache\CacheRepository;
use Ilabs\Firevert\Core\Form\FormHandler;
use Ilabs\Firevert\Core\ModuleInterface;
use Ilabs\Firevert\Core\ServiceContainer;
use Ilabs\Firevert\Core\Services\Loader\AssetLoader;
use Ilabs\Firevert\Core\Settings\Registry\SettingsRegistry;
use Ilabs\Firevert\Modules\PromoTimeWidget\Api\RenderController;
use Ilabs\Firevert\Modules\PromoTimeWidget\Hooks\Admin\AdminCptHook;
use Ilabs\Firevert\Modules\PromoTimeWidget\Hooks\Admin\AdminSaveHook;
use Ilabs\Firevert\Modules\PromoTimeWidget\Hooks\Frontend\FrontendRenderHook;
use Ilabs\Firevert\Modules\PromoTimeWidget\Services\Form\AppearanceFormHandler;
use Ilabs\Firevert\Modules\PromoTimeWidget\Services\Form\ProductsFormHandler;
use Ilabs\Firevert\Modules\PromoTimeWidget\Services\Form\SettingsFormHandler;
use Ilabs\Firevert\Modules\PromoTimeWidget\Services\Render\SettingsRenderer;
use Ilabs\Firevert\Modules\PromoTimeWidget\Services\Repository\PromoTimeWidgetRepository;
use Ilabs\Firevert\Modules\PromoTimeWidget\Services\Type\ModuleType;
use Ilabs\Firevert\Modules\PromoTimeWidget\Widget\PromoTimeWidget;

/**
 * Module initialization for PromoTimeWidget.
 */
final class ModuleInit implements ModuleInterface {

	/**
	 * Returns the module slug.
	 *
	 * @return string Module identifier (machine-readable).
	 */
	public function get_slug(): string {
		return ModuleType::MODULE_SLUG;
	}

	/**
	 * Returns the module slug.
	 *
	 * @return string Module identifier (machine-readable).
	 */
	public function get_cpt_slug(): string {
		return \Ilabs\Firevert\Modules\PowerWidget\Services\Type\ModuleType::MODULE_CPT;
	}

	/**
	 * Returns the physical folder name for the module.
	 *
	 * @return string Folder name of the module.
	 */
	public function get_folder_name(): string {
		return ModuleType::get_module_folder_name_from_slug();
	}

	/**
	 * Installs default settings for the module.
	 *
	 * @param ServiceContainer $container Dependency injection container.
	 *
	 * @return void
	 */
	public function install_default_settings( ServiceContainer $container ): void {
		/**
		 * Get from DI container.
		 *
		 * @var SettingsRenderer $renderer
		 */
		$renderer = $container->get( 'settings_renderer', ModuleType::MODULE_SLUG );
		$post     = $renderer->get_or_create_post();

		$form_handlers = array(
			new AppearanceFormHandler( $post ),
			new ProductsFormHandler( $post ),
			new SettingsFormHandler( $post ),
		);

		/**
		 * Form handler.
		 *
		 * @var FormHandler $handler
		 */
		foreach ( $form_handlers as $handler ) {
			$handler->save_defaults_if_missing( ModuleType::MODULE_SLUG );
		}
	}

	/**
	 * Indicates whether the module requires a license.
	 *
	 * @return bool True if license required, false otherwise.
	 */
	public function requires_licence(): bool {
		return false;
	}

	/**
	 * Registers module-specific settings.
	 *
	 * @param ServiceContainer $container Get from DI container.
	 * @param bool             $is_enabled Whether the module is enabled.
	 *
	 * @return void
	 */
	public function register_settings( ServiceContainer $container, bool $is_enabled ): void {
		/**
		 * Get from DI container.
		 *
		 * @var SettingsRegistry $registry
		 */
		$registry = $container->get( 'settings_registry' );

		$registry->register_group(
			ModuleType::MODULE_SLUG,
			array(
				'title'       => ModuleType::get_module_title_from_slug(),
				'description' => 'Example settings for Promo Time Widget.',
				'is_module'   => true,
				'is_enabled'  => $is_enabled,
				'fields'      => array(
					array(
						'id'    => 'enabled',
						'label' => 'Enable Promo Time Widget',
						'type'  => 'checkbox',
						'slug'  => ModuleType::MODULE_SLUG,
					),
				),
			)
		);
	}

	/**
	 * Registers WordPress hooks.
	 *
	 * @param ServiceContainer $container Service container instance.
	 *
	 * @return void
	 */
	public function register_hooks( ServiceContainer $container ): void {
		( new AdminCptHook() )->register();
		( new AdminSaveHook() )->register();

		/**
		 * Get from container DI.
		 *
		 * @var RenderController $render_controller
		 */
		$render_controller = $container->get( 'render_controller', ModuleType::MODULE_SLUG );
		$render_controller->register_routes();
		$this->register_widget_placeholder( $container );
	}

	/**
	 * Registers module services into DI container.
	 *
	 * @param ServiceContainer $container Get from DI container.
	 *
	 * @return void
	 */
	public function register_services( ServiceContainer $container ): void {
		/**
		 * Get from DI container.
		 *
		 * @var CacheRepository $cache
		 */
		$cache = $container->get( 'cache_repository' );

		$repository        = new PromoTimeWidgetRepository( $cache );
		$settings_renderer = new SettingsRenderer();
		$render_controller = new RenderController( $repository );

		$container->set( 'repository', $repository, ModuleType::MODULE_SLUG );
		$container->set( 'settings_renderer', $settings_renderer, ModuleType::MODULE_SLUG );
		$container->set( 'render_controller', $render_controller, ModuleType::MODULE_SLUG );
	}

	/**
	 * Renders the settings view for the module.
	 *
	 * @return void
	 */
	public function render_settings_view(): void {
		/**
		 * Get from container DI.
		 *
		 * @var SettingsRenderer $settings_renderer
		 */
		$settings_renderer = firevert_container()->get( 'settings_renderer', ModuleType::MODULE_SLUG );
		$settings_renderer->render();
	}

	/**
	 * Registers frontend and admin assets for the module.
	 *
	 * @param ServiceContainer $container Get from DI container.
	 *
	 * @return void
	 */
	public function enqueue_assets( ServiceContainer $container ): void {
		/**
		 * Get from DI container.
		 *
		 * @var AssetLoader $loader
		 */
		$loader = $container->get( 'asset_loader' );

		$loader->register_module_assets(
			ModuleType::MODULE_SLUG,
			array(
				array(
					'type'     => 'css',
					'filename' => 'css/admin.min.css',
					'context'  => 'admin',
				),
				array(
					'type'     => 'js',
					'filename' => 'js/admin.min.js',
					'deps'     => array( 'jquery' ),
					'context'  => 'admin',
				),
				array(
					'type'     => 'css',
					'filename' => 'css/frontend.min.css',
					'context'  => 'frontend',
				),
				array(
					'type'     => 'js',
					'filename' => 'js/frontend.min.js',
					'deps'     => array( 'jquery' ),
					'context'  => 'frontend',
				),
			),
			firevert_path( 'resources/dist', 'module', $this->get_folder_name() ),
			firevert_url( sprintf( 'src/Modules/%s/resources/dist', $this->get_folder_name() ) ),
		);
	}

	/**
	 * Registers PromoTimeWidget placeholder.
	 *
	 * @param ServiceContainer $container Get from DI container.
	 *
	 * @return void
	 */
	private function register_widget_placeholder( ServiceContainer $container ): void {
		$repository    = $container->get( 'repository', ModuleType::MODULE_SLUG );
		$path_resolver = $container->get( 'path_resolver' );

		$promo_time_widget = new PromoTimeWidget( $repository, $path_resolver );
		( new FrontendRenderHook( $promo_time_widget ) )->register();
	}
}
