<?php
/**
 * Integration Service Provider
 *
 * Loads bundled packages from the packages/ directory.
 *
 * @package Sequensy
 * @since 1.0.0
 */

declare(strict_types=1);

namespace Sequensy\Providers;

use Sequensy\Container;
use Sequensy\Packages\PackageLoader;

if ( ! defined( 'WPINC' ) ) {
	die;
}

/**
 * Loads bundled and installed integration packages.
 */
class IntegrationServiceProvider implements ServiceProvider {

	/**
	 * Register package loader in the container.
	 *
	 * @param Container $container Service container.
	 */
	public function register( Container $container ): void {
		$container->register(
			'package_loader',
			function () {
				return new PackageLoader();
			}
		);
	}

	/**
	 * Boot packages and register integration hooks.
	 *
	 * @param Container $container Service container.
	 */
	public function boot( Container $container ): void {
		$this->boot_packages( $container );

		/**
		 * Fires when integrations should be registered.
		 * Pro and add-on plugins hook here.
		 */
		do_action( 'sequensy_register_integrations' );

		add_action( 'activated_plugin', array( $this, 'clear_metadata_cache' ) );
		add_action( 'deactivated_plugin', array( $this, 'clear_metadata_cache' ) );
	}

	/**
	 * Discover, autoload, and initialize all packages.
	 *
	 * @param Container $container Service container.
	 */
	private function boot_packages( Container $container ): void {
		// phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- Inline type hint for IDE support.
		/* @var PackageLoader $loader */
		$loader = $container->get( 'package_loader' );

		$loader->register_autoloaders();
		$loader->register_credentials();
		$loader->initialize();

		add_action( 'sequensy_before_execute_action', array( $loader, 'ensure_loaded' ), 10, 2 );

		// Defer metadata and route registration to rest_api_init — only needed for REST endpoints.
		add_action(
			'rest_api_init',
			function () use ( $loader ) {
				$loader->register_metadata();
				$loader->register_routes();
			}
		);
	}

	/**
	 * Delete cached trigger and action metadata transients.
	 */
	public function clear_metadata_cache(): void {
		delete_transient( 'sequensy_trigger_metadata' );
		delete_transient( 'sequensy_action_metadata' );
	}
}
