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

namespace MOWCPS\Common\Services\Authorization;

use WP_Error;
use MOWCPS\Common\Constants\Constants;
use MOWCPS\Common\Interfaces\Auth_Strategy_Interface;
use MOWCPS\Common\Strategies\Authentication\No_Auth_Strategy;
use MOWCPS\Common\Strategies\Authentication\Basic_Auth_Strategy;
use MOWCPS\Common\Strategies\Authentication\Bearer_Auth_Strategy;
use MOWCPS\Common\Strategies\Authentication\Api_Key_Auth_Strategy;
use MOWCPS\Common\Strategies\Authentication\OAuth2_Auth_Strategy;
use MOWCPS\Common\Strategies\Authentication\Custom_Auth_Strategy;

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

/**
 * Class Authorization_Service
 *
 * Main authorization service that delegates to specific auth strategies
 */
class Authorization_Service {
	/**
	 * Auth strategies registry
	 *
	 * @var array
	 */
	private $strategies = array();

	/**
	 * Constructor
	 */
	public function __construct() {
		$this->register_strategies();
	}

	/**
	 * Generate authorization headers from auth configuration
	 *
	 * @param int   $supplier_id Supplier ID.
	 * @param array $auth_config Authorization configuration.
	 * @return array|WP_Error Headers array or error
	 */
	public function generate_headers( $auth_config, $supplier_id = Constants::TEST_SUPPLIER ) {
		if ( ! $auth_config ) {
			return new WP_Error(
				'auth_config_not_found',
				'Authorization configuration not found for supplier',
				array( 'status' => 404 )
			);
		}

		$auth_type = $auth_config['auth_type'];

		$auth_settings = null;

		if ( ! empty( $auth_config['auth_settings'] ) ) {
			$auth_settings = is_array( $auth_config['auth_settings'] ) ? $auth_config['auth_settings'] : json_decode( $auth_config['auth_settings'], true );
		}

		// Get the appropriate strategy.
		if ( ! isset( $this->strategies[ $auth_type ] ) ) {
			return new WP_Error(
				Constants::ERROR_INVALID_AUTH_TYPE,
				Constants::MSG_INVALID_AUTH_TYPE,
				array( 'status' => Constants::HTTP_BAD_REQUEST )
			);
		}

		$strategy = $this->strategies[ $auth_type ];
		return $strategy->generate_headers( $auth_settings, $supplier_id );
	}

	/**
	 * Register all authorization strategies
	 */
	private function register_strategies() {
		$this->strategies = array(
			Constants::AUTH_TYPE_NO_AUTH  => new No_Auth_Strategy(),
			Constants::AUTH_TYPE_BASIC    => new Basic_Auth_Strategy(),
			Constants::AUTH_TYPE_BEARER   => new Bearer_Auth_Strategy(),
			Constants::AUTH_TYPE_API_KEY  => new Api_Key_Auth_Strategy(),
			Constants::AUTH_TYPE_OAUTH2   => new OAuth2_Auth_Strategy(),
			Constants::AUTH_TYPE_CUSTOM   => new Custom_Auth_Strategy(),
		);
	}

	/**
	 * Get a specific auth strategy
	 *
	 * @param string $auth_type Auth type.
	 * @return Auth_Strategy_Interface|null Strategy instance or null if not found
	 */
	public function get_strategy( $auth_type ) {
		return $this->strategies[ $auth_type ] ?? null;
	}

	/**
	 * Register a custom auth strategy
	 *
	 * @param string                  $auth_type Auth type.
	 * @param Auth_Strategy_Interface $strategy Strategy instance.
	 */
	public function register_strategy( $auth_type, Auth_Strategy_Interface $strategy ) {
		$this->strategies[ $auth_type ] = $strategy;
	}
}
