<?php


namespace AutoAdmin\Bundle\Seo\Extractor;


use AutoAdmin\Bundle\Content\Configuration\ConfigManager;
use AutoAdmin\Bundle\Content\Entity\Page;
use AutoAdmin\Bundle\Content\Routing\ContentRouter;
use AutoAdmin\Bundle\Content\Site\SiteContextHelper;
use AutoAdmin\Bundle\Media\Library\MediaResolver;
use AutoAdmin\Bundle\Seo\Entity\SeoMetadata;
use AutoAdmin\Bundle\Seo\Model\Alternate;
use AutoAdmin\Bundle\Seo\Model\Meta;
use AutoAdmin\Bundle\Seo\Model\OpenGraphContentInterface;
use AutoAdmin\Bundle\Seo\Model\SeoPage;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;

class OpenGraphExtractor extends AbstractExtractor
{
    public function __construct(
        protected ConfigManager $config,
        protected ContentRouter $contentRouter,
        protected SiteContextHelper $contextHelper,
        protected EntityManagerInterface $em,
        protected MediaResolver $mediaResolver,
    ) {
    }

    public function supports($subject, $route): bool
    {
        return $this->isTranslatable($subject)
            || $this->isTranslation($subject)
            || $this->isUntranslatedContent($subject);
    }

    public function extract(Request $request, $subject, $seo): SeoPage
    {
        list($translatable, $translation) = $this->getTranslatableTranslationObjects($subject);

        /** @var Page $homepage */
        $homepage = $this->em->getRepository('App\\Entity\\Page')->contentFindOneBy(['_.homepage' => true,]);
        $homeSeo = $homepage->getTranslationSeoMetadata();

        $this->addOpenGraphTitle($homeSeo, $seo);
        $this->addOpenGraphDescription($homeSeo, $seo);
        $this->addOpenGraphLocales($seo, $seo->getAlternates());
        $seo->addOpenGraphMeta(new Meta('og:type', 'website'));
        $seo->addOpenGraphMeta(new Meta('og:url', $seo->getCanonical()));
        $this->addOpenGraphImage($seo, $translatable, $homepage);

        return $seo;
    }

    private function addOpenGraphLocales(SeoPage $seo, array $locales)
    {
        /** @var Alternate $alternate */
        foreach ($locales as $index => $alternate) {
            $localeFull = $alternate->getHrefLang().'_'.strtoupper($alternate->getHrefLang());
            if ($localeFull === 'en_EN') {
                $localeFull = 'en_UK';
            }
            $seo->addOpenGraphMeta(new Meta('og:locale'.($index > 0 ? ':alternate' : ''), $localeFull));
        }
    }

    private function addOpenGraphTitle(SeoMetadata $homepageSeo, SeoPage $seo)
    {
        if ($title = $seo->getTitle()) {
            $seo->addOpenGraphMeta(new Meta('og:title', $title));
        } else {
            $seo->addOpenGraphMeta(new Meta('og:title', $homepageSeo->getTitle()));
        }
    }

    private function addOpenGraphDescription(?SeoMetadata $homeSeo, SeoPage $seo)
    {
        $meta = new Meta('og:description', '');
        /** @var Meta $item */
        foreach ($seo->getMetas() as $item) {
            if ($item->getName() === 'description') {
                $meta->setValue($item->getValue());
            }
        }

        if ($meta->getValue() === '' && $desc = $homeSeo->getDescription()) {
            $meta->setValue($desc);
        }

        if ($meta->getValue()) {
            $seo->addOpenGraphMeta($meta);
        }
    }

    private function addOpenGraphImage(SeoPage $seo, $subject, Page $homepage)
    {
        $fallback = [$subject, $homepage];
        foreach ($fallback as $content) {
            if ($content instanceof OpenGraphContentInterface) {
                $og = $content->getTranslationOpenGraph();
                if ($stringMedia = $og->getImage()) {
                    $url = $this->mediaResolver->resolveUrl($stringMedia);
                    if ($url) {
                        $parse = parse_url($seo->getCanonical());
                        $host = $parse['host'];

                        $seo->addOpenGraphMeta(new Meta('og:image', 'https://'.$host.$url));
                        break;
                    }
                }
            }
        }
    }
}