<?php declare(strict_types=1);

namespace App\Engine\Inertia;

abstract class BaseInertiaController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
{

    public function __construct(
        protected \Rompetomp\InertiaBundle\Architecture\InertiaInterface $inertia,
        protected \Symfony\Component\HttpFoundation\RequestStack         $requestStack,
    ) {
    }

    public abstract function getVueComponent(): string;

    public abstract function getId(): string;

    protected function createBlank(): \Symfony\Component\HttpFoundation\Response
    {
        return $this->inertia->render(
            component: "Blank",
            props: $this->getInertiaProps(),
        );
    }

    protected function getInertiaProps(?InertiaProps $props = null): array
    {
        $props = $props ?? new InertiaProps();
        $this->prepareProps($props);

        return $this->serializeProps($props);
    }

    protected function prepareProps(InertiaProps $props): void
    {
        $props->messages = $this->processFlashMessages();
    }

    protected function processFlashMessages(): array
    {
        $bag = $this->requestStack->getCurrentRequest()->getSession()->getBag('flashes');
        $messages = [];
        foreach ($bag->all() as $type => $values) {
            foreach ($values as $value) {
                $messages[] = new \App\Engine\Inertia\MessageViewModel($value, $type);
            }
        }

        return $messages;
    }

    protected function serializeProps(InertiaProps $props): array
    {
        $classMetadataFactory = new \Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory(new \Symfony\Component\Serializer\Mapping\Loader\AttributeLoader()); // Použití PHP 8 atributů místo AnnotationReader

        $normalizer = new \Symfony\Component\Serializer\Normalizer\ObjectNormalizer($classMetadataFactory, null, null, null, null, null, [
            \Symfony\Component\Serializer\Normalizer\ObjectNormalizer::ENABLE_MAX_DEPTH => true,
            \Symfony\Component\Serializer\Normalizer\ObjectNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object) {
                return $object->getId(); // Vrátí ID místo serializace celého objektu
            },
        ]);

        $serializer = new \Symfony\Component\Serializer\Serializer([$normalizer], [new \Symfony\Component\Serializer\Encoder\JsonEncoder()]);

        return $serializer->normalize($props, null, [
            \Symfony\Component\Serializer\Normalizer\ObjectNormalizer::ENABLE_MAX_DEPTH => true
        ]);
    }

}
