<?php
/**
 * Class Loco_Automatic_Translate_Addon_Pro\AI_Translate\Services\Services_Service_Container_Builder
 */

namespace Loco_Automatic_Translate_Addon_Pro\AI_Translate\Services;

use Loco_Automatic_Translate_Addon_Pro\AI_Translate\Services\Options\Option_Encrypter;
use Loco_Automatic_Translate_Addon_Pro\AI_Translate\Services\Util\Data_Encryption;
use Felix_Arntz\WP_OOP_Plugin_Lib\Capabilities\Base_Capability;
use Felix_Arntz\WP_OOP_Plugin_Lib\Capabilities\Capability_Container;
use Felix_Arntz\WP_OOP_Plugin_Lib\Capabilities\Capability_Controller;
use Felix_Arntz\WP_OOP_Plugin_Lib\Capabilities\Capability_Filters;
use Felix_Arntz\WP_OOP_Plugin_Lib\Capabilities\Meta_Capability;
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_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\HTTP\HTTP;

if (!defined('AI_SERVICES_VERSION')) {
    define('AI_SERVICES_VERSION', '0.2.0');
}

final class Services_Service_Container_Builder {
    private $container;

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

    public function get(): Service_Container {
        return $this->container;
    }

    public function build_env(string $main_file): self {
        $this->container['plugin_env'] = function () use ($main_file) {
            return new Plugin_Env($main_file, AI_SERVICES_VERSION);
        };
        return $this;
    }

    public function build_services(): self {
        $this->build_general_services();
        $this->build_capability_services();
        $this->build_http_services();
        $this->build_option_services();

        $this->container['api'] = static function ($cont) {
            return new Services_API(
                $cont['current_user'],
                $cont['option_container'],
                $cont['option_repository'],
                $cont['option_encrypter'],
                $cont['http']
            );
        };

        return $this;
    }

    private function build_general_services(): void {
        $this->container['current_user'] = static function () {
            return new Current_User();
        };
    }

    private function build_capability_services(): void {
        $this->container['capability_container'] = static function () {
            $capabilities = new Capability_Container();
            $capabilities['ais_manage_services'] = static function () {
                return new Base_Capability(
                    'ais_manage_services',
                    array('manage_options')
                );
            };
            $capabilities['ais_access_services'] = static function () {
                return new Base_Capability(
                    'ais_access_services',
                    array('edit_posts')
                );
            };
            $capabilities['ais_access_service'] = static function () {
                return new Meta_Capability(
                    'ais_access_service',
                    static function (int $user_id, string $service_slug) {
                        return array('ais_access_services');
                    }
                );
            };
            return $capabilities;
        };

        $this->container['capability_controller'] = static function ($cont) {
            return new Capability_Controller($cont['capability_container']);
        };
        $this->container['capability_filters'] = static function ($cont) {
            return new Capability_Filters($cont['capability_container']);
        };
    }

    private function build_http_services(): void {
        $this->container['http'] = static function () {
            return new HTTP();
        };
    }

    private function build_option_services(): void {
        $this->container['option_repository'] = static function () {
            return new Option_Repository();
        };
        $this->container['option_container'] = static function () {
            return new Option_Container();
        };
        $this->container['option_registry'] = static function () {
            return new Option_Registry('ais_services');
        };
        $this->container['option_encrypter'] = static function () {
            return new Option_Encrypter(new Data_Encryption());
        };
    }
}
