<?php
/**
 * Bootstrap class.
 *
 * @package DokanKits\Core
 * @since   3.0.0
 */

namespace DokanKits\Core;

use DokanKits\Core\Interfaces\Hookable;
use DokanKits\Core\Interfaces\Initable;
use DokanKits\Setup\Migrator;
use WP_REST_Controller;

/**
 * Bootstrap
 *
 * Handles plugin bootstrapping
 *
 * @package DokanKits\Core
 */
class Bootstrap implements Hookable {

	/**
	 * Register WordPress hooks
	 *
	 * Registers the necessary WordPress hooks for the bootstrap process.
	 * This includes REST API initialization and other core plugin hooks.
	 *
	 * @since 3.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function register_hooks(): void {
		add_action( 'rest_api_init', array( $this, 'boot_rest' ), 10 );
	}

	/**
	 * Bootstrap the plugin
	 *
	 * This method initializes all components of the plugin.
	 *
	 * @since 3.0.0
	 *
	 * @return void
	 */
	public function boot(): void {
		/**
		 * Action fired before bootstrapping the plugin components.
		 *
		 * @since 3.0.0
		 *
		 * @param Bootstrap $this Bootstrap instance.
		 */
		do_action( 'dokan_kits_before_bootstrap', $this );

		$this->boot_core();
		$this->boot_admin();
		$this->boot_settings_setup();
		$this->init_migrations();

		/**
		 * Action fired after bootstrapping all plugin components.
		 *
		 * @since 3.0.0
		 *
		 * @param Bootstrap $this Bootstrap instance.
		 */
		do_action( 'dokan_kits_bootstrap', $this );
	}

	/**
	 * Boot core services
	 *
	 * Initializes core services from the dependency injection container.
	 * This method retrieves core services and initializes them if they
	 * implement the Initable interface.
	 *
	 * @since 3.0.0
	 * @access protected
	 *
	 * @return void
	 */
	protected function boot_core(): void {
		$services = dokan_kits_get_container()->get( 'core-service' );
		if ( $services instanceof Initable ) {
			$services->initialize();
		}
	}

	/**
	 * Boot admin components
	 *
	 * @return void
	 */
	protected function boot_admin(): void {
		if ( is_admin() ) {
			dokan_kits_get_container()->get( 'admin-dashboard-service' );
			dokan_kits_get_container()->get( 'admin-service' );
		}

		$services = dokan_kits_get_container()->get( 'setup-service' );
		foreach ( $services as $service ) {
			if ( $service instanceof Initable ) {
				$service->initialize();
			}
		}

		/**
		 * Fire action after admin bootstrap
		 *
		 * @param Bootstrap $this Bootstrap instance.
		 */
		do_action( 'dokan_kits_after_admin_bootstrap', $this );
	}

	/**
	 * Boot REST API
	 *
	 * @since 3.0.0
	 * @return void
	 */
	public function boot_rest(): void {
		/**
		 * Filter the REST controllers to be registered.
		 *
		 * @since 3.0.0
		 *
		 * @param array     $controllers The REST controllers.
		 * @param Bootstrap $this        The bootstrap instance.
		 */
		$controllers = dokan_kits_get_container()->get( 'rest-service' );

		/**
		 * Action fired before registering REST routes.
		 *
		 * @since 3.0.0
		 *
		 * @param array     $controllers The REST controllers.
		 * @param Bootstrap $this        The bootstrap instance.
		 */
		do_action( 'dokan_kits_before_rest_routes_registration', $controllers, $this );

		foreach ( $controllers as $controller ) {
			if ( ! $controller instanceof WP_REST_Controller ) {
				continue;
			}

			/**
			 * Action fired before registering a specific REST controller's routes.
			 *
			 * @since 3.0.0
			 *
			 * @param WP_REST_Controller $controller The REST controller.
			 * @param Bootstrap          $this       The bootstrap instance.
			 */
			do_action( 'dokan_kits_before_rest_controller_routes', $controller, $this );

			$controller->register_routes();

			/**
			 * Action fired after registering a specific REST controller's routes.
			 *
			 * @since 3.0.0
			 *
			 * @param WP_REST_Controller $controller The REST controller.
			 * @param Bootstrap          $this       The bootstrap instance.
			 */
			do_action( 'dokan_kits_after_rest_controller_routes', $controller, $this );
		}

		/**
		 * Action fired after registering REST routes.
		 *
		 * @since 3.0.0
		 *
		 * @param array     $controllers The REST controllers.
		 * @param Bootstrap $this        The bootstrap instance.
		 */
		do_action( 'dokan_kits_after_rest_routes_registration', $controllers, $this );

		/**
		 * Action fired after REST bootstrap.
		 *
		 * @since 3.0.0
		 *
		 * @param Bootstrap $this Bootstrap instance.
		 */
		do_action( 'dokan_kits_after_rest_bootstrap', $this );
	}

	/**
	 * Boot features setup
	 *
	 * @return void
	 */
	protected function boot_settings_setup(): void {
		dokan_kits_get_container()->get( 'setup-service' );

		/**
		 * Fire action after features setup bootstrap
		 *
		 * @param Bootstrap $this Bootstrap instance.
		 */
		do_action( 'dokan_kits_after_settings_setup_bootstrap', $this );
	}

	/**
	 * Initialize migrations
	 *
	 * @return void
	 */
	public function init_migrations(): void {
		dokan_kits_get_container()->get( 'migration-service' );

		$migrator = dokan_kits_get_container()->get( Migrator::class );
		$migrator->run();
	}
}
