<?php

defined('ABSPATH') || exit;

use MemberPress\GroundLevel\Container\Concerns\HasStaticContainer;
use MemberPress\GroundLevel\Container\Container;
use MemberPress\GroundLevel\Container\Contracts\StaticContainerAwareness;
use MemberPress\GroundLevel\InProductNotifications\Service as IPNService;
use MemberPress\GroundLevel\Insights\Insights;
use MemberPress\GroundLevel\Mothership\Service as MoshService;
use MemberPress\GroundLevel\Support\Concerns\Hookable;
use MemberPress\GroundLevel\Support\Models\Hook;

/**
 * Initializes a GroundLevel container and dependent services.
 */
class MeprGrdLvlCtrl extends MeprBaseCtrl implements StaticContainerAwareness
{
    use HasStaticContainer;
    use Hookable;

    /**
     * Returns an array of Hooks that should be added by the class.
     *
     * @return array
     */
    protected function configureHooks(): array
    {
        return [
            new Hook(Hook::TYPE_ACTION, 'init', __CLASS__ . '::init', 5),
        ];
    }

    /**
     * Loads the hooks for the controller.
     */
    public function load_hooks()
    {
        $this->addHooks();
    }

    /**
     * Initializes a GroundLevel container and dependent services.
     *
     * @param boolean $force_init_ipn If true, forces notifications to load even if notifications are disabled.
     *                                Used during database migrations when we cannot determine if the current
     *                                user has access to notifications.
     */
    public static function init(bool $force_init_ipn = false): void
    {
        // Always create a fresh container.
        self::setContainer(new Container());

        // Always initialize mothership.
        self::init_mothership();

        // Initialize IPNs only when any of these conditions are met:
        // - Database migrations are being run (force_init_ipn)
        // - User has access to mepr notifications
        // - Performing cronjobs.
        if ($force_init_ipn || MeprNotifications::has_access() || wp_doing_cron()) {
            self::init_ipn();
            self::init_insights(); // Insights depends on IPN.
        }
    }

    /**
     * Initializes and configures the IPN Service.
     */
    private static function init_ipn(): void
    {
        // Set IPN Service parameters.
        self::$container->addParameter(IPNService::PRODUCT_SLUG, MEPR_EDITION);
        self::$container->addParameter(IPNService::PREFIX, 'mepr');
        self::$container->addParameter(IPNService::MENU_SLUG, 'memberpress');
        self::$container->addParameter(
            IPNService::USER_CAPABILITY,
            MeprUtils::get_mepr_admin_capability()
        );
        self::$container->addParameter(
            IPNService::RENDER_HOOK,
            'mepr_admin_header_actions'
        );
        self::$container->addParameter(
            IPNService::THEME,
            [
                'primaryColor'       => '#2271b1',
                'primaryColorDarker' => '#0a4b78',
            ]
        );

        self::$container->addService(
            IPNService::class,
            static function (Container $container): IPNService {
                return new IPNService($container);
            },
            true
        );
    }

    /**
     * Initializes the Insights Service.
     */
    private static function init_insights(): void
    {
        self::$container->addParameter(Insights::PRODUCT_NAME, MEPR_DISPLAY_NAME);
        self::$container->addParameter(Insights::PREFIX, 'mepr_insights_');
        self::$container->addParameter(Insights::REST_NAMESPACE, 'mepr/insights');
        self::$container->addService(
            Insights::class,
            static function (Container $container): Insights {
                return new Insights($container);
            },
            true
        );
    }

    /**
     * Initializes the Mothership Service.
     */
    private static function init_mothership(): void
    {
        self::$container->addService(
            MoshService::class,
            static function (Container $container): MoshService {
                return new MoshService(
                    $container,
                    new MeprMothershipPluginConnector()
                );
            },
            true
        );
    }
}
