<?php
/**
 * Supplier App Factory
 *
 * @category   WordPress_Plugin
 * @package    Common
 * @subpackage Factories
 * @author     miniOrange <info@miniorange.com>
 * @license    MIT/Expat
 * @link       https://plugins.miniorange.com/woocommerce-api-product-sync-with-woocommerce-rest-apis
 */

namespace MOWCPS\Common\Factories;

use WP_Error;
use MOWCPS\Common\Interfaces\Supplier_App_Interface;
use MOWCPS\Common\Constants\Constants;

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

/**
 * Class Supplier_App_Factory
 *
 * Factory class for creating supplier app instances
 */
class Supplier_App_Factory {
	/**
	 * Supported app types for common plan
	 *
	 * @var array
	 */
	public static $supported_app_types = array(
		Constants::SUPPLIER_APP_TYPE_AMROD,
		Constants::SUPPLIER_APP_TYPE_BARRON,
		Constants::SUPPLIER_APP_TYPE_SNS_ACTIVEWEAR,
		Constants::SUPPLIER_APP_TYPE_SHOPIFY,
		Constants::SUPPLIER_APP_TYPE_TOPTEX,
		Constants::SUPPLIER_APP_TYPE_WOOCOMMERCE,
		Constants::SUPPLIER_APP_TYPE_MIDOCEAN,
		Constants::SUPPLIER_APP_TYPE_TURN14,
		Constants::SUPPLIER_APP_TYPE_PARTS_EUROPE,
		Constants::SUPPLIER_APP_TYPE_SANMAR,
		Constants::SUPPLIER_APP_TYPE_UTTEAM,
		Constants::SUPPLIER_APP_TYPE_TRENDS,
		Constants::SUPPLIER_APP_TYPE_INTEX_GLOBAL,
		Constants::SUPPLIER_APP_TYPE_KMQ,
		Constants::SUPPLIER_APP_TYPE_SYSCOM,
		Constants::SUPPLIER_APP_TYPE_JASANI,
		Constants::SUPPLIER_APP_TYPE_PROMOSTANDARDS,
		Constants::SUPPLIER_APP_TYPE_PROMOSTANDARDS_SANMAR,
		Constants::SUPPLIER_APP_TYPE_PROMOSTANDARDS_SANMAR_CA,
		Constants::SUPPLIER_APP_TYPE_PROMOSTANDARDS_SAINTREGIS,
		Constants::SUPPLIER_APP_TYPE_INGRAM_MICRO,
		Constants::SUPPLIER_APP_TYPE_MALFINI,
	);

	/**
	 * Create supplier app instance based on app type
	 *
	 * @param string $app_type The supplier app type.
	 * @param array  $supported_app_types The supported app types.
	 * @return Supplier_App_Interface|WP_Error Supplier app instance or error.
	 */
	public static function create_supplier_app( $app_type, $supported_app_types = array() ) {
		// Validate app type.
		if ( empty( $app_type ) ) {
			return new WP_Error(
				Constants::ERROR_MISSING_REQUIRED_FIELD,
				'App type is required.',
				array( 'status' => Constants::HTTP_BAD_REQUEST )
			);
		}

		$supported_app_types = empty( $supported_app_types ) ? self::$supported_app_types : $supported_app_types;

		// Check if app type is supported.
		if ( ! in_array( $app_type, $supported_app_types, true ) ) {
			return new WP_Error(
				Constants::ERROR_INVALID_SUPPLIER_TYPE,
				sprintf( 'Unsupported app type: %s', $app_type ),
				array( 'status' => Constants::HTTP_BAD_REQUEST )
			);
		}

		// Generate class name dynamically.
		$class_name = self::get_class_name_for_app_type( $app_type );
		// Check if class exists (automatic loading will handle plan-based classes).
		if ( ! class_exists( $class_name ) ) {
			return new WP_Error(
				Constants::ERROR_INVALID_SUPPLIER_TYPE,
				sprintf( 'App class not found: %s', $class_name ),
				array( 'status' => Constants::HTTP_INTERNAL_SERVER_ERROR )
			);
		}

		// Create and return the app instance.
		try {
			$app_instance = new $class_name();

			// Verify the instance implements the required interface.
			if ( ! $app_instance instanceof Supplier_App_Interface ) {
				return new WP_Error(
					Constants::ERROR_INVALID_SUPPLIER_TYPE,
					sprintf( 'App class does not implement Supplier_App_Interface: %s', $class_name ),
					array( 'status' => Constants::HTTP_INTERNAL_SERVER_ERROR )
				);
			}

			return $app_instance;
		} catch ( \Exception $e ) {
			return new WP_Error(
				Constants::ERROR_INVALID_SUPPLIER_TYPE,
				sprintf( 'Failed to instantiate app class: %s', $e->getMessage() ),
				array( 'status' => Constants::HTTP_INTERNAL_SERVER_ERROR )
			);
		}
	}

	/**
	 * Get class name for app type
	 *
	 * @param string $app_type The app type.
	 * @return string The class name.
	 */
	public static function get_class_name_for_app_type( $app_type ) {
		$class_name = str_replace( array( '-', '_' ), ' ', $app_type );
		$class_name = ucwords( strtolower( $class_name ) );
		$class_name = str_replace( ' ', '_', $class_name );

		$namespace = in_array( $app_type, self::$supported_app_types, true ) ? 'Common' : MOWCPS_PLAN_NAMESPACE;

		return 'MOWCPS\\' . $namespace . '\\Suppliers\\' . $class_name;
	}
}
