<?php
/**
 * Main Plugin Bootstrap Class
 *
 * @package AmbassadorHub
 */

namespace AmbassadorHub;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Main plugin class that handles initialization and coordination.
 */
final class Plugin {
	/**
	 * Plugin instance.
	 *
	 * @var Plugin|null
	 */
	private static ?Plugin $instance = null;

	/**
	 * Get plugin instance (singleton).
	 *
	 * @return Plugin
	 */
	public static function instance(): Plugin {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Constructor.
	 * Private to enforce singleton pattern.
	 */
	private function __construct() {
		$this->load_components();
	}

	/**
	 * Load plugin components.
	 *
	 * @return void
	 */
	private function load_components(): void {
		// Initialize core components in order of dependency.

		// Migrations - coordinate database schema updates across modules.
		Migrations\Manager::init();

		// Field types - register field type implementations into FieldFactory.
		Fields\FieldsModule::init();

		// Custom fields (user-defined fields on signup/donation forms) ship in
		// the AmbassadorHub Premium add-on, not here.

		// REST API - REST endpoints and authentication.
		Api\ApiModule::init();

		// Admin interface - WordPress admin UI.
		Admin\AdminModule::init();

		// Frontend components (blocks, forms).
		Frontend\FrontendModule::init();

		// Query Loop integrations.
		QueryLoop\HierarchyFilter::init();

		// Consent system (GDPR, marketing opt-in, etc)
		Consent\ConsentModule::init();

		// Accounts system (roles, capabilities, authentication).
		Accounts\AccountsModule::init();

		// Automations trigger-dispatch primitive. Free modules fire triggers
		// through this; the rule-builder/engine that actually matches triggers
		// against configured rules ships in the AmbassadorHub Premium add-on,
		// which hooks into the `ambh_automation_trigger_matched` action.
		Automations\ScheduleEngine::init();

		// Fundraisers - fundraiser CPT, REST API, and blocks.
		Fundraisers\FundraisersModule::init();

		// Donors - donor profiles (personal information) linked to donations.
		Donors\DonorsModule::init();

		// Donations - donation CPT, REST API, migrations, and automations.
		Donations\DonationsModule::init();

		// Petitions, Signers, and Signatures ship in the separate, optional
		// AmbassadorHub Petitions add-on, not here.

		// Transactional mail - lifecycle emails for fundraiser and donation events.
		Mail\TransactionalMailer::init();

		// Tracking - server-side analytics event dispatching (GA4 + extensible providers).
		Tracking\TrackingModule::init();

		// Connector registry - eager-instantiate so it is available before
		// ambh_loaded fires and connector plugins self-register.
		Connectors\ConnectorRegistry::instance();

		// Built-in payment connectors — each checks its own enabled toggle.

		// Register the connector with the registry. Mollie ships in the
		// AmbassadorHub Premium add-on, which self-registers via the
		// `ambh_loaded` hook below (see ConnectorRegistry docblock).
		Connectors\PayPal\PayPalPspConnector::init();
		Connectors\Stripe\StripePspConnector::init();
		Connectors\Free\FreePspConnector::init();

		// Boot the connector-automations bridge at priority 30, after connector
		// plugins have self-registered at priority 20 on the same action.
		add_action( 'ambh_loaded', array( Connectors\ConnectorRegistry::class, 'boot' ), 30 );

		/**
		 * Fires after all AmbassadorHub components are loaded.
		 *
		 * Connector plugins should self-register here at priority 20:
		 *   add_action( 'ambh_loaded', fn() =>
		 *       ConnectorRegistry::register( new MyConnector() ), 20
		 *   );
		 *
		 * ConnectorRegistry::boot() (priority 30) then wires the automations
		 * bridge after all connectors have registered.
		 *
		 * @since 0.1.0
		 */
		do_action( 'ambh_loaded' );
	}

	/**
	 * Get plugin version.
	 *
	 * @return string
	 */
	public function get_version(): string {
		return AMBASSADOR_HUB_VERSION;
	}

	/**
	 * Get plugin path.
	 *
	 * @return string
	 */
	public function get_path(): string {
		return AMBASSADOR_HUB_PATH;
	}

	/**
	 * Get plugin URL.
	 *
	 * @return string
	 */
	public function get_url(): string {
		return AMBASSADOR_HUB_URL;
	}
}
