<?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\Core\Util\LocaleCode;
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 Symfony\Component\HttpFoundation\Request;

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

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

    public function extract(Request $request, object $subject, SeoPage $seoPage): SeoPage
    {
        [$translatable, $translation] = $this->getTranslatableTranslationObjects($subject);

        $homepage = $this->getHomepage();
        $homeSeo = $homepage->getTranslationSeoMetadata();

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

        return $seoPage;
    }

    private function addOpenGraphTitle(SeoMetadata $homepageSeo, SeoPage $seo): void
    {
        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): void
    {
        $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 addOpenGraphLocales(SeoPage $seo, array $alternates): void
    {
        /** @var Alternate $alternate */
        foreach ($alternates as $index => $alternate) {
            $code = substr($alternate->getHrefLang(), 0, 2);
            $localeFull = LocaleCode::getFirstCountryFromCode($code, true);
            $seo->addOpenGraphMeta(new Meta('og:locale'.($index > 0 ? ':alternate' : ''), $localeFull));
        }
    }

    private function addOpenGraphImage(SeoPage $seo, $subject, Page $homepage): void
    {
        $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;
                    }
                }
            }
        }
    }
}
