<?php

declare(strict_types=1);

namespace Inpsyde\MultilingualPress\Module\ExternalSites\Integrations;

use Inpsyde\MultilingualPress\Framework\Integration\Integration;
use Inpsyde\MultilingualPress\Framework\Module\ModuleManager;
use Inpsyde\MultilingualPress\Framework\Service\Container;
use Inpsyde\MultilingualPress\Module\BeaverBuilder\ServiceProvider as BeaverSupportModule;
use Inpsyde\MultilingualPress\Module\Elementor\ServiceProvider as ElementorSupportModule;
use Inpsyde\MultilingualPress\Module\ExternalSites\ExternalSitesRepository\ExternalSitesRepository;
use Inpsyde\MultilingualPress\Module\ExternalSites\Integrations\Flags\ExternalSiteFlagFactory;
use Inpsyde\MultilingualPress\Module\ExternalSites\Integrations\Flags\ExternalSiteFlagFactoryInterface;
use Inpsyde\MultilingualPress\Module\ExternalSites\Integrations\Redirect\ExternalSiteRedirectTargetFactory;
use Inpsyde\MultilingualPress\Module\ExternalSites\Integrations\Redirect\ExternalSiteRedirectTargetFactoryInterface;
use Inpsyde\MultilingualPress\Module\ExternalSites\Integrations\Redirect\Fallback\ExternalRedirectFallbackViewRenderer;
use Inpsyde\MultilingualPress\Module\ExternalSites\Integrations\Redirect\RedirectIntegration;
use Inpsyde\MultilingualPress\Module\ExternalSites\ServiceProvider;
use Inpsyde\MultilingualPress\Module\LanguageSwitcher\ItemFactory as LanguageSwitcherItemFactory;
use Inpsyde\MultilingualPress\Module\Redirect\GeoLocation\GeolocationFinder;
use Inpsyde\MultilingualPress\Module\Redirect\RedirectTarget\LanguageNegotiator;
use Inpsyde\MultilingualPress\Module\Redirect\Settings\Renderers\ViewRenderer;
use Inpsyde\MultilingualPress\Module\Redirect\Settings\Repository\Repository;
use Inpsyde\MultilingualPress\SiteFlags\ServiceProvider as SiteFlagsModule;
use Inpsyde\MultilingualPress\Module\Redirect\ServiceProvider as RedirectModule;

(static function (Container $container) {
    $container->share(
        ExternalSiteRedirectTargetFactory::class,
        static function (): ExternalSiteRedirectTargetFactoryInterface {
            return new ExternalSiteRedirectTargetFactory();
        }
    );

    $container->share(
        ExternalRedirectFallbackViewRenderer::class,
        static function (Container $container): ViewRenderer {
            return new ExternalRedirectFallbackViewRenderer(
                $container->get('multilingualpress.ExternalSites.AllExternalSites'),
                $container->get(Repository::class)
            );
        }
    );

    $container->share(
        ExternalSiteFlagFactory::class,
        static function (Container $container): ExternalSiteFlagFactoryInterface {
            $flagsProperties = $container->get('siteFlagsProperties');
            return new ExternalSiteFlagFactory(
                $flagsProperties['pluginPath'],
                $flagsProperties['pluginUrl'],
                $container->get(ServiceProvider::CONFIGURATION_NAME_FOR_FLAGS_FOLDER_PATH)
            );
        }
    );

    /**
     * Configuration for all external sites module integrations.
     *
     * @return Integration[] The list of all external sites module integrations.
     */
    $container->share(
        'multilingualpress.ExternalSites.Integrations',
        static function (Container $container): array {
            $moduleManager = $container->get(ModuleManager::class);
            return [
                new RedirectIntegration(
                    $container->get('multilingualpress.ExternalSites.AllExternalSites'),
                    $container->get(LanguageNegotiator::class),
                    $container->get(ExternalSiteRedirectTargetFactory::class),
                    $container->get(Repository::class),
                    $container->get(ExternalRedirectFallbackViewRenderer::class),
                    $container->get(ExternalSitesRepository::class),
                    $container->get(RedirectModule::CONFIGURATION_NAME_FOR_REDIRECT_USER_LANGUAGES),
                    $container->get(GeolocationFinder::class)
                ),
                new QuickLinksIntegration(
                    $container->get('multilingualpress.ExternalSites.AllExternalSites')
                ),
                new LanguageSwitcherWidgetIntegration(
                    $container->get('multilingualpress.ExternalSites.AllExternalSites'),
                    $container->get(LanguageSwitcherItemFactory::class),
                    $container->get(ExternalSiteFlagFactory::class),
                    $container->get(ServiceProvider::CONFIGURATION_NAME_FOR_EXTERNAL_SITE_KEYWORD),
                    $moduleManager->isModuleActive(SiteFlagsModule::MODULE_ID)
                ),
                new HreflangIntegration(
                    $container->get('multilingualpress.ExternalSites.AllExternalSites'),
                    [
                        'link' => [
                            'href' => true,
                            'hreflang' => true,
                            'rel' => true,
                        ],
                    ]
                ),
            ];
        }
    );

    /**
     * Configuration for list of post type names, which should not be supported.
     *
     * @return string[] The list of post type names.
     */
    $container->share(
        ServiceProvider::CONFIGURATION_NAME_FOR_UNSUPPORTED_POST_TYPES,
        static function (Container $container): array {
            $unsupportedPostTypes = ['shop_order', 'shop_subscription'];

            if ($container->has(ElementorSupportModule::ELEMENTOR_ENTITIES_TO_REMOVE_SUPPORT)) {
                $unsupportedPostTypes = array_merge($unsupportedPostTypes, $container->get(ElementorSupportModule::ELEMENTOR_ENTITIES_TO_REMOVE_SUPPORT));
            }

            if ($container->has(BeaverSupportModule::CONFIGURATION_NAME_FOR_UNSUPPORTED_POST_TYPES)) {
                $unsupportedPostTypes = array_merge($unsupportedPostTypes, $container->get(BeaverSupportModule::CONFIGURATION_NAME_FOR_UNSUPPORTED_POST_TYPES));
            }

            return $unsupportedPostTypes;
        }
    );
}
)($container); //phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
