<?php
/**
 * Plugin bootstrap singleton.
 *
 * @package EmberPrice
 */

namespace EmberPrice\Core;

defined( 'ABSPATH' ) || exit;

/**
 * Instantiated on `plugins_loaded`; actual boot logic runs on `init` once
 * requirements are confirmed met.
 */
final class Plugin {

	/**
	 * Singleton instance.
	 *
	 * @var self|null
	 */
	private static ?self $instance = null;

	/**
	 * Returns the singleton instance, creating it on first call.
	 */
	public static function instance(): self {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Private constructor: use {@see self::instance()}.
	 */
	private function __construct() {
		// Deferred to `init`: `Activator::get_missing_requirements()` calls
		// __(), and translating this early (still at `plugins_loaded`)
		// triggers a WordPress core "translation loaded too early" notice.
		add_action( 'init', array( $this, 'boot' ) );
	}

	/**
	 * Checks requirements are still met and initializes the plugin. Hooked
	 * to `init`, so that WooCommerce being deactivated after this plugin was
	 * activated doesn't fatal on WC-dependent code (there is none yet).
	 */
	public function boot(): void {
		$missing = Activator::get_missing_requirements();

		if ( ! empty( $missing ) ) {
			add_action(
				'admin_notices',
				static function () use ( $missing ) {
					Activator::render_requirements_notice( $missing );
				}
			);
			return;
		}

		// Catches schema upgrades that don't go through a fresh activation,
		// e.g. the plugin files being updated in place.
		Migrations::maybe_upgrade();

		/**
		 * Fires once requirements are confirmed met and the schema is up to
		 * date. The Core layer cannot import Admin/Rest/etc (see CLAUDE.md's
		 * dependency matrix), so those layers are wired up from the main
		 * plugin file listening for this action instead.
		 */
		do_action( 'embp_loaded' );
	}

	/**
	 * Declares HPOS (custom order tables) compatibility. Hooked directly to
	 * `before_woocommerce_init` from the main plugin file, since that hook
	 * can fire before `plugins_loaded` depending on plugin load order.
	 */
	public static function declare_hpos_compatibility(): void {
		if ( ! class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
			return;
		}

		\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
			'custom_order_tables',
			EMBP_PLUGIN_FILE,
			true
		);
	}
}
