<?php
/**
 * Options factory for creating option instances.
 *
 * @package Awesomemotive\Rewardswp\Factories
 * @since 1.0.0
 */

namespace Awesomemotive\Rewardswp\Factories;

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

use Awesomemotive\Rewardswp\Abstracts\AbstractOption;
use DI\Container;
use Exception;
use function Awesomemotive\Rewardswp\Helpers\str_snake_to_pascal_case;

class OptionsFactory {
	/**
	 * Dependency injection container.
	 *
	 * @since 1.0.0
	 *
	 * @var Container
	 */
	private Container $container;

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

	/**
	 * Retrieves an instance of an Option object based on the option name.
	 *
	 * @since 1.0.0
	 *
	 * @param string|AbstractOption $name_or_class The snake_case name of the option or the class name.
	 * @param string                $group                        The option group. Default is an empty string. Not necessary when passing the class name.
	 * @return AbstractOption|null                 The Option object instance, or null if not found.
	 */
	function get_option( $name_or_class, string $group = '' ): ?AbstractOption {
		try {

			// Check if it is the class name, if so, return right away.
			if ( class_exists( $name_or_class ) && is_subclass_of( $name_or_class, AbstractOption::class ) ) {
				return $this->container->get( $name_or_class );
			}

			$class_name = sprintf( '%sOption', str_snake_to_pascal_case( $name_or_class ) );

			$full_class_name = '' === $group
				? sprintf( 'Awesomemotive\\Rewardswp\\Settings\\Options\\%s', $class_name )
				: sprintf( 'Awesomemotive\\Rewardswp\\Settings\\Options\\%s\\%s', str_snake_to_pascal_case( $group ), $class_name );

			if ( class_exists( $full_class_name ) && is_subclass_of( $full_class_name, AbstractOption::class ) ) {
				return $this->container->get( $full_class_name );
			}

			return null;
		} catch ( Exception $exception ) {
			return null;
		}
	}
}
