<?php
namespace Newland\NeosMetaTags\Extractor;

/*
 * This file is part of the "neos-meta-tags" package.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 */

use Neos\Media\Domain\Model\ImageVariant;
use Newland\NeosMetaTags\Domain\Model\MetaData;
use Neos\ContentRepository\Domain\Model\Node;
use Neos\Flow\Mvc\ActionRequest;

class PageExtractor extends BaseExtractor
{
    public function extractAll(Node $node, ActionRequest $request): MetaData
    {
        $metaData = new MetaData();

        $title = $this->nodeService->getPropertyWithFallback($node, $this->configuration['fallback']['title'] ?? []);
        $metaData->setTitle($this->appendWebsite($title, $node));
        $metaData->setDescription(
            strip_tags(
                $this->nodeService->getPropertyWithFallback(
                    $node,
                    $this->configuration['fallback']['description'] ?? []
                )
            )
        );
        $metaData->setUrl((string) $request->getHttpRequest()->getUri());

        $metaData->setOgType(
            $this->nodeService->getPropertyWithFallback(
                $node,
                $this->configuration['fallback']['og']['type'],
                MetaData::OG_TYPE_DEFAULT
            )
        );
        $metaData->setOgTitle(
            $this->nodeService->getPropertyWithFallback($node, $this->configuration['fallback']['og']['title'] ?? [])
        );
        $metaData->setOgDescription(
            strip_tags(
                $this->nodeService->getPropertyWithFallback(
                    $node,
                    $this->configuration['fallback']['og']['description'] ?? []
                )
            )
        );
        /** @var ImageVariant $image */
        $image = $this->nodeService->getPropertyWithFallback(
            $node,
            $this->configuration['fallback']['og']['image'] ?? []
        );
        if ($image !== null) {
            $ogImagePreset = $this->getOgImagePresetFromAsset($image);
            $metaData->setOgThumbnail(
                $this->thumbnailService->getThumbnailDataFromAsset($image, $ogImagePreset, $request)
            );
            $metaData->setOgImageAltText($image->getCaption() ?: $image->getLabel());
        }

        $metaData->setTwitterType(
            $this->nodeService->getPropertyWithFallback(
                $node,
                $this->configuration['fallback']['twitter']['type'] ?? [],
                MetaData::TWITTER_CARD_TYPE_DEFAULT
            )
        );
        $metaData->setTwitterTitle(
            $this->nodeService->getPropertyWithFallback(
                $node,
                $this->configuration['fallback']['twitter']['title'] ?? []
            )
        );
        $metaData->setTwitterDescription(
            strip_tags(
                $this->nodeService->getPropertyWithFallback(
                    $node,
                    $this->configuration['fallback']['twitter']['description'] ?? []
                )
            )
        );
        $metaData->setTwitterImage($this->getTwitterImageUriFromPage($node, $request));

        $metaData->setTwitterCreator(
            $this->nodeService->getPropertyWithFallback(
                $node,
                $this->configuration['fallback']['twitter']['creator'] ?? [],
                $this->twitterHandle
            )
        );

        return $metaData;
    }

    public function extractTitle(Node $node, bool $appendWebsite = false): ?string
    {
        $pageTitle = $this->nodeService->getPropertyWithFallback(
            $node,
            $this->configuration['fallback']['title'] ?? []
        );

        if ($appendWebsite) {
            $pageTitle = $this->appendWebsite($pageTitle, $node);
        }

        return $pageTitle;
    }

    public function extractDescription(Node $node): ?string
    {
        $description = $this->nodeService->getPropertyWithFallback(
            $node,
            $this->configuration['fallback']['description'] ?? []
        );

        $metaData = new MetaData();
        $metaData->setDescription($description);

        return $metaData->getDescriptionTrimmed();
    }

    protected function getTwitterImageUriFromPage(Node $node, ActionRequest $request): ?string
    {
        $image = $this->nodeService->getPropertyWithFallback(
            $node,
            $this->configuration['fallback']['twitter']['image'] ?? []
        );
        if (!$image) {
            return null;
        }

        $preset = $this->getPresetFromTwitterCardType((string) $node->getProperty('twitterCardType'));
        $thumbnailData = $this->thumbnailService->getThumbnailDataFromAsset($image, $preset, $request);

        return $thumbnailData['src'];
    }
}
