<?php
/**
 * Vendor Hook Factory
 *
 * Factory class for creating vendor hook instances using Strategy pattern.
 *
 * @category   WordPress_Plugin
 * @package    Common
 * @subpackage Factories
 * @author     miniOrange <info@miniorange.com>
 * @link       https://miniorange.com
 */

namespace MOWCPS\Common\Factories;

use MOWCPS\Common\Constants\Constants;
use MOWCPS\Common\Interfaces\Hookable_Interface;

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

/**
 * Class Vendor_Hook_Factory
 *
 * Factory for creating vendor hook strategy instances
 */
class Vendor_Hook_Factory {

	/**
	 * Registry of vendor hook strategies
	 *
	 * Maps vendor names to their hook class names.
	 *
	 * @var array<string, string>
	 */
	private static $strategies = array();

	/**
	 * Initialize default vendor hook strategies
	 *
	 * @return void
	 */
	private static function initialize_strategies() {
		if ( ! empty( self::$strategies ) ) {
			return;
		}

		self::$strategies = array(
			Constants::SUPPLIER_APP_TYPE_SHOPIFY         => \MOWCPS\Common\Hooks\Shopify::class,
			Constants::SUPPLIER_APP_TYPE_WOOCOMMERCE     => \MOWCPS\Common\Hooks\suppliers\Woocommerce::class,
			Constants::SUPPLIER_APP_TYPE_SNS_ACTIVEWEAR  => \MOWCPS\Common\Hooks\Sns_Activewear::class,
			Constants::SUPPLIER_APP_TYPE_AMROD           => \MOWCPS\Common\Hooks\Amrod::class,
			Constants::SUPPLIER_APP_TYPE_MIDOCEAN        => \MOWCPS\Common\Hooks\Midocean::class,
			Constants::SUPPLIER_APP_TYPE_BARRON          => \MOWCPS\Common\Hooks\Barron::class,
			Constants::SUPPLIER_APP_TYPE_PARTS_UNLIMITED => \MOWCPS\Premium\Hooks\Suppliers\Parts_Unlimited::class,
			Constants::SUPPLIER_APP_TYPE_SANMAR          => \MOWCPS\Common\Hooks\Sanmar::class,
			Constants::SUPPLIER_APP_TYPE_TURN14          => \MOWCPS\Common\Hooks\Turn14::class,
			Constants::SUPPLIER_APP_TYPE_PARTS_EUROPE    => \MOWCPS\Common\Hooks\Parts_Europe::class,
			Constants::SUPPLIER_APP_TYPE_TOPTEX          => \MOWCPS\Common\Hooks\Toptex::class,
			Constants::SUPPLIER_APP_TYPE_TRENDS          => \MOWCPS\Common\Hooks\Trends::class,
			Constants::SUPPLIER_APP_TYPE_KMQ             => \MOWCPS\Common\Hooks\Kmq::class,
			Constants::SUPPLIER_APP_TYPE_JASANI          => \MOWCPS\Common\Hooks\Jasani::class,
			Constants::SUPPLIER_APP_TYPE_PROMOSTANDARDS  => \MOWCPS\Common\Hooks\Promostandards::class,
			Constants::SUPPLIER_APP_TYPE_INGRAM_MICRO    => \MOWCPS\Common\Hooks\Ingram_Micro::class,
			Constants::SUPPLIER_APP_TYPE_PROMOSTANDARDS_SANMAR_CA => \MOWCPS\Common\Hooks\Promostandards_Sanmar_Ca::class,
			Constants::SUPPLIER_APP_TYPE_INTEX_GLOBAL    => \MOWCPS\Common\Hooks\Intex_Global::class,
		);
	}

	/**
	 * Register a vendor hook strategy
	 *
	 * Allows extending the factory without modifying the core class
	 *
	 * @param string $vendor_name The vendor name constant.
	 * @param string $hook_class  The fully qualified class name implementing Hookable_Interface.
	 *
	 * @return void
	 */
	public static function register_strategy( $vendor_name, $hook_class ) {
		self::initialize_strategies();

		if ( ! is_string( $vendor_name ) || empty( $vendor_name ) ) {
			return;
		}

		if ( ! is_string( $hook_class ) || empty( $hook_class ) ) {
			return;
		}

		if ( ! class_exists( $hook_class ) ) {
			return;
		}

		// Verify the class implements Hookable_Interface.
		$reflection = new \ReflectionClass( $hook_class );
		if ( ! $reflection->implementsInterface( Hookable_Interface::class ) ) {
			return;
		}

		self::$strategies[ $vendor_name ] = $hook_class;
	}

	/**
	 * Create vendor hook instance based on vendor name
	 *
	 * @param string $vendor_name The vendor name for which we need to perform operations.
	 *
	 * @return Hookable_Interface|null Vendor hook instance or null if not found.
	 */
	public static function create( $vendor_name ) {
		self::initialize_strategies();

		if ( empty( $vendor_name ) || ! is_string( $vendor_name ) ) {
			return null;
		}

		if ( ! isset( self::$strategies[ $vendor_name ] ) ) {
			return null;
		}

		$hook_class = self::$strategies[ $vendor_name ];

		if ( ! class_exists( $hook_class ) ) {
			return null;
		}

		try {
			$instance = new $hook_class();

			// Verify the instance implements Hookable_Interface.
			if ( ! $instance instanceof Hookable_Interface ) {
				return null;
			}

			return $instance;
		} catch ( \Exception $e ) {
			return null;
		}
	}

	/**
	 * Get all registered vendor names
	 *
	 * @return array<string> Array of registered vendor names.
	 */
	public static function get_registered_vendors() {
		self::initialize_strategies();
		return array_keys( self::$strategies );
	}
}
