<?php

namespace RebelCode\Spotlight\Instagram\Modules\Pro;

use Dhii\Services\Extension;
use Dhii\Services\Factories\Constructor;
use Dhii\Services\Factory;
use Elementor\Plugin as ElementorPlugin;
use Psr\Container\ContainerInterface;
use RebelCode\Spotlight\Instagram\Module;
use RebelCode\Spotlight\Instagram\Modules\ElementorEditFeedControl;
use RebelCode\Spotlight\Instagram\Pro\Elementor\ElementorSelectFeedControl;
use RebelCode\Spotlight\Instagram\Pro\Elementor\ElementorWidget;
use RebelCode\Spotlight\Instagram\Utils\Arrays;
use RebelCode\Spotlight\Instagram\Wp\Asset;

/**
 * The module that adds integration with the Elementor page builder.
 *
 * @since 0.4
 */
class ElementorModule extends Module
{
    /**
     * @inheritDoc
     *
     * @since 0.4
     */
    public function run(ContainerInterface $c)
    {
        // Set the widget to render using the shortcode's callback
        add_action('elementor/init', function () use ($c) {
            ElementorWidget::setRenderAction($c->get('shortcode/callback'));
        });

        // Register the main assets on the elementor editor page
        add_action('elementor/editor/before_enqueue_scripts', $c->get('ui/register_assets_fn'));

        // Register the widgets
        add_action('elementor/widgets/widgets_registered', function () use ($c) {
            /* @var $plugin ElementorPlugin */
            /* @var $widget ElementorWidget */
            $plugin = $c->get('plugin');
            $widget = $c->get('widget');

            $plugin->widgets_manager->register_widget_type($widget);
        });

        // Register the widget controls
        add_action('elementor/controls/controls_registered', function () use ($c) {
            /* @var $plugin ElementorPlugin */
            /* @var $control ElementorEditFeedControl */
            $plugin = $c->get('plugin');
            $controls = $c->get('controls');

            Arrays::eachAssoc($controls, function ($id, $control) use ($plugin) {
                $plugin->controls_manager->register_control($id, $control);
            });
        });
    }

    /**
     * @inheritDoc
     *
     * @since 0.4
     */
    public function getFactories()
    {
        return class_exists(ElementorPlugin::class) ? [
            // The Elementor singleton instance
            'plugin' => new Factory([], function () {
                return ElementorPlugin::instance();
            }),
            // The Spotlight Instagram widget for Elementor
            'widget' => new Constructor(ElementorWidget::class),
            // The controls to add to Elementor
            'controls' => new Factory([], function () {
                return [
                    'sli-select-feed' => new ElementorSelectFeedControl(),
                ];
            }),
            // App scripts added by this module
            'scripts' => new Factory(['@ui/scripts_url', '@ui/assets_ver'], function ($url, $ver) {
                return [
                    'sli-elementor-editor' => Asset::script("{$url}/elementor-editor.js", $ver, [
                        'sli-admin-pro',
                    ]),
                    'sli-elementor-widget' => Asset::script("{$url}/elementor-widget.js", $ver, [
                        'elementor-frontend',
                        'sli-common-pro',
                        'sli-front',
                    ]),
                ];
            }),
            // App styles added by this module
            'styles' => new Factory(['@ui/styles_url', '@ui/assets_ver'], function ($url, $ver) {
                return [
                    'sli-elementor-editor' => Asset::style("{$url}/elementor-editor.css", $ver, [
                        'sli-editor',
                        'sli-common-pro',
                    ]),
                ];
            }),
        ] : [];
    }

    /**
     * @inheritDoc
     *
     * @since 0.4
     */
    public function getExtensions()
    {
        return class_exists(ElementorPlugin::class) ? [
            // Register the module's scripts
            'ui/scripts' => new Extension(['scripts'], function ($all, $new) {
                return array_merge($all, $new);
            }),
            // Register the module's styles
            'ui/styles' => new Extension(['styles'], function ($all, $new) {
                return array_merge($all, $new);
            }),
        ] : [];
    }
}
