<?php
/**
 * Class Loco_Automatic_Translate_Addon_Pro\AI_Translate\Plugin_Service_Container_Builder
 */

namespace Loco_Automatic_Translate_Addon_Pro\AI_Translate;

use Felix_Arntz\WP_OOP_Plugin_Lib\Dependencies\Script_Registry;
use Felix_Arntz\WP_OOP_Plugin_Lib\Dependencies\Style_Registry;
use Felix_Arntz\WP_OOP_Plugin_Lib\General\Current_User;
use Felix_Arntz\WP_OOP_Plugin_Lib\General\Plugin_Env;
use Felix_Arntz\WP_OOP_Plugin_Lib\General\Service_Container;
use Felix_Arntz\WP_OOP_Plugin_Lib\Options\Option;
use Felix_Arntz\WP_OOP_Plugin_Lib\Options\Option_Container;
use Felix_Arntz\WP_OOP_Plugin_Lib\Options\Option_Registry;
use Felix_Arntz\WP_OOP_Plugin_Lib\Options\Option_Repository;
use Felix_Arntz\WP_OOP_Plugin_Lib\Validation\General_Validation_Rule_Builder;
use Felix_Arntz\WP_OOP_Plugin_Lib\Assets\Script_Style_Loader;

final class Plugin_Service_Container_Builder {

	/**
	 * Service container.
	 *
	 * @var Service_Container
	 */
	private $container;

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->container = new Service_Container();
	}

	/**
	 * Gets the service container.
	 *
	 * @return Service_Container Service container for the plugin.
	 */
	public function get(): Service_Container {
		return $this->container;
	}

	/**
	 * Builds the plugin environment service for the service container.
	 *
	 * @param string $main_file Absolute path to the plugin main file.
	 * @return self The builder instance, for chaining.
	 */
	public function build_env( string $main_file ): self {
		$this->container['plugin_env'] = function () use ( $main_file ) {
			return new Plugin_Env( $main_file, ATLT_PRO_VERSION );
		};

		$this->container['plugin_basename'] = static function() use ($main_file) {
			return plugin_basename($main_file);
		};

		$this->container['plugin_url'] = static function() use ($main_file) {
			return plugin_dir_url($main_file);
		};

		return $this;
	}

	/**
	 * Builds the services for the service container.
	 *
	 * @return self The builder instance, for chaining.
	 */
	public function build_services(): self {
		$this->build_general_services();
		$this->build_option_services();

		return $this;
	}

	/**
	 * Builds the general services for the service container.
	 */
	private function build_general_services(): void {
		$this->container['current_user'] = static function () {
			return new Current_User();
		};
	}

	/**
	 * Builds the option services for the service container.
	 */
	private function build_option_services(): void {
		$this->container['option_repository'] = static function () {
			return new Option_Repository();
		};
		$this->container['option_container']  = function () {
			$options = new Option_Container();
			$this->add_options_to_container( $options );
			return $options;
		};
		$this->container['option_registry']   = static function () {
			return new Option_Registry( 'ai_services' );
		};
	}

	/**
	 * Adds the option definitions to the given option container.
	 *
	 * @param Option_Container $options Option container instance.
	 */
	private function add_options_to_container( Option_Container $options ): void {
		// Core options only
		$options['ais_version'] = function () {
			$sanitize_callback = ( new General_Validation_Rule_Builder() )
				->require_string()
				->format_version()
				->get_option_sanitize_callback();

			return new Option(
				$this->container['option_repository'],
				'ais_version',
				array(
					'type'              => 'string',
					'sanitize_callback' => $sanitize_callback,
					'default'           => '',
					'autoload'          => true,
				)
			);
		};

		$options['ais_options'] = function () {
			return new Option(
				$this->container['option_repository'],
				'ais_options',
				array(
					'type'     => 'object',
					'default'  => array(),
					'autoload' => true,
				)
			);
		};
	}
}
