<?php
declare( strict_types=1 );

namespace FiboFilters\Integrations;

use FiboFilters\DI\ContainerWrapper;

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

/**
 * Class Plugins
 */
class Plugins {
	/** @var ContainerWrapper */
	private $container;
	/**
	 * @var array|array[]
	 */
	private array $plugins_data;

	private const PHASE_EARLY = 'early_init';
	private const PHASE_INIT  = 'init';
	private const PHASE_LATE  = 'late_init';

	public function __construct( ContainerWrapper $container ) {
		$this->container = $container;

		$this->plugins_data = [
			'breakdance'                                 => [
				'name'          => 'Breakdance',
				'active'        => static fn (): bool => defined( '__BREAKDANCE_VERSION' ),
				'version_const' => '__BREAKDANCE_VERSION',
				'early_init'    => true,
			],
			'elementor'                                  => [
				'name'          => 'Elementor',
				'active'        => static fn (): bool => defined( 'ELEMENTOR_VERSION' ),
				'version_const' => 'ELEMENTOR_VERSION',
			],
			'litespeed_cache'                            => [
				'name'          => 'LiteSpeed Cache',
				'active'        => static fn (): bool => function_exists( 'run_litespeed_cache' ),
				'version_const' => '',
			],
			'variation_swatches_for_woocommerce_pro'     => [
				'name'          => 'Variation Swatches for WooCommerce Pro',
				'active'        => static fn (): bool => defined( 'WOO_VARIATION_SWATCHES_PRO_PLUGIN_VERSION' ),
				'version_const' => 'WOO_VARIATION_SWATCHES_PRO_PLUGIN_VERSION',
			],
			'woocommerce'                                => [
				'name'          => 'WooCommerce',
				'active'        => static fn (): bool => defined( 'WOOCOMMERCE_VERSION' ),
				'version_const' => 'WOOCOMMERCE_VERSION',
			],
			'yith_woocommerce_wishlist'                  => [
				'name'          => 'YITH WooCommerce Wishlist',
				'active'        => static fn (): bool => defined( 'YITH_WCWL' ),
				'version_const' => '',
			],
			'pixel_manager_pro_for_woocommerce'          => [
				'name'          => 'Pixel Manager Pro for WooCommerce',
				'active'        => static fn (): bool => defined( 'PMW_CURRENT_VERSION' ),
				'version_const' => 'PMW_CURRENT_VERSION',
			],
			'wp_rocket'                                  => [
				'name'          => 'WP Rocket',
				'active'        => static fn (): bool => defined( 'WP_ROCKET_VERSION' ),
				'version_const' => 'WP_ROCKET_VERSION',
			],
			'flying_press'                               => [
				'name'          => 'FlyingPress',
				'active'        => static fn (): bool => defined( 'FLYING_PRESS_VERSION' ),
				'version_const' => 'FLYING_PRESS_VERSION',
			],
			'kinsta_mu_plugins'                          => [
				'name'          => 'Kinsta MU Plugins',
				'active'        => static fn (): bool => defined( 'KINSTAMU_VERSION' ),
				'version_const' => 'KINSTAMU_VERSION',
			],
			'hide_categories_products_wc'                => [
				'name'   => 'Hide Categories Products for WooCommerce',
				'active' => static fn (): bool => function_exists( 'Hide_Categories_Products_WC' ),
			],
			'iconic_woo_image_swap'                      => [
				'name'          => 'Iconic Woo Image Swap',
				'active'        => static fn (): bool => defined( 'ICONIC_WIS_VERSION' ),
				'version_const' => 'ICONIC_WIS_VERSION',
			],
			'advanced_custom_fields'                     => [
				'name'          => 'Advanced Custom Fields',
				'active'        => static fn (): bool => defined( 'ACF_VERSION' ),
				'version_const' => 'ACF_VERSION',
			],
			'jvm_woocommerce_wishlist'                   => [
				'name'          => 'JVM WooCommerce Wishlist',
				'active'        => static fn (): bool => defined( 'CIXWW_PLUGIN_VER' ),
				'version_const' => 'CIXWW_PLUGIN_VER',
			],
			'woo_composite_products'                     => [
				'name'          => 'WooCommerce Composite Products',
				'active'        => static fn (): bool => defined( 'WC_CP_VERSION' ),
				'version_const' => 'WC_CP_VERSION',
			],
			'pw_woocommerce_gift_cards'                  => [
				'name'          => 'PW WooCommerce Gift Cards',
				'active'        => static fn (): bool => defined( 'PWGC_VERSION' ),
				'version_const' => 'PWGC_VERSION',
			],
			'perfmatters'                                => [
				'name'          => 'Perfmatters',
				'active'        => static fn (): bool => defined( 'PERFMATTERS_VERSION' ),
				'version_const' => 'PERFMATTERS_VERSION',
			],
			'woocommerce_aelia_currencyswitcher'         => [
				'name'          => 'Aelia Currency Switcher for WooCommerce',
				'active'        => static fn (): bool => class_exists( '\Aelia\WC\CurrencySwitcher\WC_Aelia_CurrencySwitcher' ),
				'version_const' => '',
			],
			'imagify'                                    => [
				'name'          => 'Imagify',
				'active'        => static fn (): bool => defined( 'IMAGIFY_VERSION' ),
				'version_const' => 'IMAGIFY_VERSION',
			],
			'essential_addons_for_elementor'             => [
				'name'          => 'Essential Addons for Elementor',
				'active'        => static fn (): bool => defined( 'EAEL_PLUGIN_VERSION' ),
				'version_const' => 'EAEL_PLUGIN_VERSION',
			],
			'product_variation_swatches_for_woocommerce' => [
				'name'          => 'Product Variation Swatches for WooCommerce',
				'active'        => static fn (): bool => defined( 'THWVS_VERSION' ),
				'version_const' => 'THWVS_VERSION',
			],
			'breeze'                                     => [
				'name'          => 'Breeze',
				'active'        => static fn (): bool => defined( 'BREEZE_VERSION' ),
				'version_const' => 'BREEZE_VERSION',
			],
			'relevanssi'                                 => [
				'name'          => 'Relevanssi',
				'active'        => static function (): bool {
					global $relevanssi_variables;
					return isset( $relevanssi_variables['plugin_version'] );
				},
				'version_const' => '',
			],
			'wp_all_import'                              => [
				'name'          => 'WP All Import',
				'active'        => static fn (): bool => defined( 'PMXI_VERSION' ),
				'version_const' => 'PMXI_VERSION',
			],
			'fibosearch_pro'                             => [
				'name'          => 'FiboSearch Pro',
				'active'        => static fn (): bool => defined( 'DGWT_WCAS_NAME' ) && DGWT_WCAS_NAME === 'FiboSearch Pro' && function_exists( 'DGWT_WCAS' ) && version_compare( DGWT_WCAS_VERSION, '1.31.0.8', '>=' ),
				'version_const' => 'DGWT_WCAS_VERSION',
				'late_init'     => true,
			],
			'wpc_product_bundles_for_wooCommerce'        => [
				'name'          => 'WPC Product Bundles for WooCommerce',
				'active'        => static fn (): bool => defined( 'WOOSB_VERSION' ),
				'version_const' => 'WOOSB_VERSION',
			],
		];
	}

	public function early_init(): void {
		// Break early if "nofibofilters" = 1 || 2.
		if (
			isset( $_GET['nofibofilters'] ) && in_array( $_GET['nofibofilters'], [ '1', '2' ], true ) || // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			in_array( apply_filters( 'fibofilters/nofibofilters', '' ), [ '1', '2' ], true )
		) {
			return;
		}

		$this->try_load_plugin_integrations( self::PHASE_EARLY );
	}

	public function init(): void {
		// Break early if "nofibofilters" = 1 || 2.
		if (
			isset( $_GET['nofibofilters'] ) && in_array( $_GET['nofibofilters'], [ '1', '2' ], true ) || // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			in_array( apply_filters( 'fibofilters/nofibofilters', '' ), [ '1', '2' ], true )
		) {
			return;
		}

		$this->try_load_plugin_integrations();
	}

	public function late_init(): void {
		// Break early if "nofibofilters" = 1 || 2.
		if (
			isset( $_GET['nofibofilters'] ) && in_array( $_GET['nofibofilters'], [ '1', '2' ], true ) || // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			in_array( apply_filters( 'fibofilters/nofibofilters', '' ), [ '1', '2' ], true )
		) {
			return;
		}

		$this->try_load_plugin_integrations( self::PHASE_LATE );
	}

	public function get_active_plugins(): array {
		return array_filter(
			$this->plugins_data,
			function ( $plugin ) {
				return $this->is_plugin_active( $plugin );
			}
		);
	}

	private function try_load_plugin_integrations( string $method = self::PHASE_INIT ) {
		$plugins = $this->get_plugins_for_phase( $method );

		foreach ( $plugins as $plugin => $plugin_data ) {
			if ( $this->is_plugin_active( $plugin_data ) ) {
				$this->container->dich()->add_action( // @phpstan-ignore-line
					"fibofilters/integrations/plugin/{$method}/{$plugin}",
					[ "plugins.{$plugin}", $method ]
				);
				do_action( "fibofilters/integrations/plugin/{$method}/{$plugin}" );
			}
		}
	}

	private function get_plugins_for_phase( string $method ): array {
		if ( $method === self::PHASE_EARLY ) {
			return array_filter(
				$this->plugins_data,
				static fn ( array $plugin ): bool => ! empty( $plugin['early_init'] )
			);
		} elseif ( $method === self::PHASE_LATE ) {
			return array_filter(
				$this->plugins_data,
				static fn ( array $plugin ): bool => ! empty( $plugin['late_init'] )
			);
		}

		return $this->plugins_data;
	}

	private function is_plugin_active( array $plugin ): bool {
		return isset( $plugin['active'] ) && is_callable( $plugin['active'] ) && call_user_func( $plugin['active'] );
	}
}
