<?php
namespace Newland\Toubiz\Services\Neos\Sitemap;

use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Neos\Domain\Model\Domain;
use Neos\Neos\Domain\Model\Site;
use Neos\Neos\Domain\Service\ContentContext;
use Newland\NeosCommon\Sitemap\SitemapProvider;
use Neos\Flow\Annotations as Flow;
use Newland\NeosCommon\Sitemap\SitemapUrl;
use Newland\NeosCommon\Service\ControllerContextFactory;
use Newland\Toubiz\Services\Neos\Service\ServiceUrlService;
use Newland\Toubiz\Sync\Neos\Domain\Model\Service;
use Newland\Toubiz\Sync\Neos\Domain\Repository\ServiceRepository;

/**
 * @Flow\Scope("singleton")
 */
class ServiceDetailSitemapProvider implements SitemapProvider
{

    /**
     * @var ServiceRepository
     * @Flow\Inject()
     */
    protected $serviceRepository;

    /**
     * @var ServiceUrlService
     * @Flow\Inject()
     */
    protected $serviceUrlService;

    /**
     * @Flow\Inject()
     * @var ControllerContextFactory
     */
    protected $contextFactory;

    /**
     * @param NodeInterface $site
     * @return SitemapUrl[]
     */
    public function getPages(NodeInterface $site): array
    {
        $pages = [];

        foreach ($this->serviceRepository->findAll() as $service) {
            $url = $this->serviceToSitemapUrl($service, $this->domain($site));
            if ($url) {
                $pages[] = $url;
            }
        }

        return $pages;
    }

    private function serviceToSitemapUrl(Service $service, Domain $domain): ?SitemapUrl
    {
        $url = $this->serviceUrlService->generateUrl($service);
        if (!$url) {
            return null;
        }

        $url = $this->prependDomainIfRelative($url, $domain);
        return new SitemapUrl($url);
    }

    private function prependDomainIfRelative(string $url, Domain $domain): string
    {
        if (str_contains($url, 'http')) {
            return $url;
        }

        $domainWithScheme = clone $domain;
        $domainWithScheme->setScheme($domain->getScheme() ?? 'http');
        return ((string) $domainWithScheme) . '/' . ltrim($url, '/');
    }


    /**
     * @param NodeInterface $site
     * @return Domain
     */
    private function domain(NodeInterface $site): Domain
    {
        $contentContext = $site->getContext();
        if (!($contentContext instanceof ContentContext)) {
            return new Domain();
        }

        $domain = null;
        /** @var ?Site $currentSite */
        $currentSite = $contentContext->getCurrentSite();
        if ($currentSite) {
            $domain = $currentSite->getPrimaryDomain();
        }

        return $domain ?? new Domain();
    }
}
