<?php

namespace AutoAdmin\Bundle\Content\Twig\Extension;

use AutoAdmin\Bundle\Content\ContentReference\ContentReferenceResolver;
use AutoAdmin\Bundle\Content\Entity\ContentReference;
use AutoAdmin\Bundle\Content\Model\NameInterface;
use AutoAdmin\Bundle\Content\Model\TitleInterface;
use AutoAdmin\Bundle\Content\Model\TranslatableInterface;
use AutoAdmin\Bundle\Content\Routing\ContentRouter;
use AutoAdmin\Bundle\Content\Service\ContentService;
use AutoAdmin\Bundle\Content\Service\ObfuscatorService;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

class ContentExtension extends AbstractExtension
{
    public function __construct(
        private readonly ContentRouter $contentRouter,
        private readonly ContentReferenceResolver $referenceResolver,
        private readonly ContentService $contentService,
    ) {
    }

    public function getFunctions(): array
    {
        return [
            new TwigFunction('aa_content_path', $this->getPath(...)),
            new TwigFunction('aa_content_path_safe', $this->getPath(...), [
                'deprecated' => true,
                'alternative' => 'aa_content_path',
            ]),
            new TwigFunction('aa_content_title', [$this, 'getContentTitle']),
            new TwigFunction('aa_content_ref_path', [$this, 'getContentReferencePath']),
            new TwigFunction('aa_content_has_brick_type', [$this, 'hasBrickType']),
        ];
    }

    public function getFilters(): array
    {
        return [
            new TwigFilter('aa_raw', [$this, 'handleRaw']),
        ];
    }

    public function getPath($content, array $parameters = [], ?string $action = null, array $options = []): ?string
    {
        if ($content === null) {
            return '#nullcontent';
        }

        $path = $this->contentRouter->generateSafe($content, $action, $parameters, $options);

        if ($path === null) {
            return '#nullpath';
        } elseif ($path === '') {
            return '#emptypath';
        }

        return $path;
    }

    public function getContentTitle(?object $content = null)
    {
        $title = null;

        if (empty($content)) {
            return $title;
        }

        if ($content instanceof TranslatableInterface) {
            $content = $content->getCurrentTranslation();
        }

        if ($content instanceof NameInterface) {
            $title = $content->getName();
        } elseif ($content instanceof TitleInterface) {
            $title = $content->getTitle();
        }

        return $title;
    }

    public function getContentReferencePath($var): ?string
    {
        if (!$var instanceof ContentReference) {
            return null;
        }

        $resolved = $this->referenceResolver->resolve($var);
        if (empty($resolved)) {
            return null;
        }

        return $this->getPath($resolved);
    }

    public function handleRaw($content): string
    {
        return ObfuscatorService::obfuscate($content);
    }

    public function hasBrickType($content, string $type): bool
    {
        return $this->contentService->hasBrickTypeOf($content, $type);
    }
}
