<?php declare(strict_types=1);

namespace App\Engine\Navigation;

class NavigationController extends \App\Engine\Admin\Inertia\BaseInertiaAdminController
{

    public function list(
        NavigationRepository                                                           $repository,
        \Symfony\Contracts\Translation\TranslatorInterface                             $translator,
        \Symfony\Component\HttpFoundation\Request                                      $request,
        \App\Engine\Admin\Inertia\SystemConfiguration\AdminSystemConfigurationProvider $adminSystemConfigurationProvider,
    ): \Symfony\Component\HttpFoundation\Response {
        $parentEntity = $this->loadParentEntityFromRequest($repository);
        $adminSystemConfigurationProvider->getConfiguration()->pageMeta->title = $translator->trans("admin.menu.navigation") . ($parentEntity ? " - " . $parentEntity?->getTitle() : "");

        $records = $repository->findByParentId($parentEntity?->getId());
        return $this->createList($repository, $records);
    }

    protected function loadParentEntityFromRequest(NavigationRepository $repository): Navigation|false|null
    {
        $request = $this->requestStack->getCurrentRequest();
        $parentId = $request->attributes->get("parentId");
        if ($parentId === null) {
            return null;
        }

        return $repository->findOneBy(["id" => $parentId]) ?? false; // Pokud není nalezen žádný záznam, tak vracíme false, protože se jedná o nekonzistenci a měl by být
    }

    public function getId(): string
    {
        return "Navigation";
    }

    public function createList(\App\Engine\Admin\AdminRepositoryInterface $repository, ?array $records = null): \Symfony\Component\HttpFoundation\Response
    {
        if ($records === null) {
            $records = $this->provideListRecords($repository);
        }
        if (!$repository instanceof NavigationRepository) {
            throw new \LogicException("Zde by mělo být předané NavigationRepository! Předáno bylo " . get_class($repository));
        }

        $parentEntity = $this->loadParentEntityFromRequest($repository);
        $parentEntityViewModel = $parentEntity ? new \App\Engine\Inertia\Admin\ViewModels\ParentEntityViewModel($parentEntity) : null;

        $props = new \App\Engine\Inertia\Admin\Props\ListProps();
        $props->list = $this->createListViewModel($records);
        $props->parentEntity = $parentEntityViewModel;

        return $this->inertia->render(
            component: "{$this->getVueComponent()}/List",
            props: $this->getInertiaProps($props),
        );
    }

    public function edit(
        NavigationRepository                               $repository,
        \Twig\Environment                                  $twig,
        \Symfony\Component\HttpFoundation\Request          $request,
        \Symfony\Contracts\Translation\TranslatorInterface $translator,
        \Doctrine\ORM\EntityManagerInterface               $entityManager,
    ): \Symfony\Component\HttpFoundation\Response {
        $record = $repository->findOneBy(["id" => $request->attributes->get("id")]);
        $this->adminSystemConfigurationProvider->getConfiguration()->pageMeta->title = $translator->trans("admin.action.list.edit") . ": " . $record->getTitle();
        $edit = new \App\Engine\Inertia\Admin\ViewModels\EditViewModel(
            record: $record,
        );

        $page = $record->getPage();
        $form = $this->createEditForm($translator, $record);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $refreshForm = false;
            if ($record->getPage() === null && $page !== null && !$record->getUrl()) { // Pokud se odebrala stránka a nenastavila se ručně nová URL tak se použije ta ze stránky
                $refreshForm = true;
                $record->setUrl($page->getUrl());
            }
            $refreshForm = $refreshForm || $this->resetUrlIfPageIsSet($record);

            $form = $this->createEditForm($translator, $record); // Pokud došlo ke změnám, vygenerujeme nový form s aktuálními daty

            $entityManager->flush();
            $this->addFlash("success", $translator->trans("admin.action.edit.successfully-updated"));
        }

        return $this->createEditResponse($twig, $form, $edit);
    }

    private function createEditForm(\Symfony\Contracts\Translation\TranslatorInterface $translator, ?Navigation $navigation = null): \Symfony\Component\Form\FormInterface
    {
        return $this->createFormBuilder($navigation, ["attr" => ["class" => "row"]])
            ->add("title", \Symfony\Component\Form\Extension\Core\Type\TextType::class, [
                "row_attr" => ["class" => "col-md-6 mb-3"],
                "label" => $translator->trans("admin.navigation.title"),
                "required" => true,
            ])
            ->add("parent", \Symfony\Bridge\Doctrine\Form\Type\EntityType::class, [
                "row_attr" => ["class" => "col-md-6 mb-3"],
                "class" => Navigation::class,
                "choice_label" => "title",
                "label" => $translator->trans("admin.navigation.parent"),
                "help" => $translator->trans("admin.navigation.parent-help"),
                "placeholder" => $translator->trans("admin.action.edit.select-value-not-selected"),
                "required" => false,
                "query_builder" => function (\Doctrine\ORM\EntityRepository $repository) use ($navigation) {
                    $query = $repository->createQueryBuilder('navigation')->orderBy('navigation.title', 'ASC');
                    return $navigation->getId() ? $query
                        ->where('navigation.id != :selfId')
                        ->setParameter('selfId', $navigation->getId()) : $query;
                },
            ])
            ->add("url", \Symfony\Component\Form\Extension\Core\Type\TextType::class, [
                "row_attr" => ["class" => "col-md-6 mb-3"],
                "label" => $translator->trans("admin.navigation.url"),
                "required" => false,
            ])
            ->add("page", \Symfony\Bridge\Doctrine\Form\Type\EntityType::class, [
                "row_attr" => ["class" => "col-md-6 mb-3"],
                "class" => \App\Engine\Page\Page::class,
                "choice_label" => "title",
                "label" => $translator->trans("admin.navigation.page"),
                "help" => $translator->trans("admin.navigation.page-help"),
                "placeholder" => $translator->trans("admin.action.edit.select-value-not-selected"),
                "required" => false,
                "query_builder" => function (\Doctrine\ORM\EntityRepository $repository) {
                    return $repository->createQueryBuilder('page')
                        ->where('page.enabled = :active')
                        ->setParameter('active', true)
                        ->orderBy('page.title', 'ASC');
                },
            ])
            ->add("section", \Symfony\Component\Form\Extension\Core\Type\EnumType::class, [
                "class" => NavigationSection::class,
                "row_attr" => ["class" => "col-md-4 mb-3"],
                "label" => $translator->trans("admin.navigation.section"),
                "choice_label" => fn(?NavigationSection $choice) => $translator->trans("admin.navigation.sectionValues.$choice->value"),
                "required" => true,
            ])
            ->add("priority", \Symfony\Component\Form\Extension\Core\Type\TextType::class, [
                "row_attr" => ["class" => "col-md-2 mb-3"],
                "label" => $translator->trans("admin.navigation.priority"),
                "required" => true,
            ])
            ->add("enabled", \Symfony\Component\Form\Extension\Core\Type\CheckboxType::class, [
                "row_attr" => ["class" => "col-md-2 mb-3 pt-4"],
                "label" => $translator->trans("admin.navigation.enabled"),
                "required" => false,
            ])
            ->add("targetBlank", \Symfony\Component\Form\Extension\Core\Type\CheckboxType::class, [
                "row_attr" => ["class" => "col-md-3 mb-3 pt-4"],
                "label" => $translator->trans("admin.navigation.target-blank"),
                "required" => false,
            ])
            ->add("submit", \Symfony\Component\Form\Extension\Core\Type\SubmitType::class, [
                "label" => $translator->trans("admin.action.edit.save"),
            ])
            ->getForm();
    }

    private function resetUrlIfPageIsSet(Navigation $record): bool
    {
        if (!$record->getPage()) {
            return false;
        }

        $record->setUrl(null);
        return true;
    }

    public function new(
        NavigationRepository                               $repository,
        \Twig\Environment                                  $twig,
        \Symfony\Component\HttpFoundation\Request          $request,
        \Symfony\Contracts\Translation\TranslatorInterface $translator,
        \Doctrine\ORM\EntityManagerInterface               $entityManager,
    ): \Symfony\Component\HttpFoundation\Response {
        $this->adminSystemConfigurationProvider->getConfiguration()->pageMeta->title = $translator->trans("admin.action.list.new");
        $parentRecord = $this->loadParentEntityFromRequest($repository);
        if ($parentRecord === false) {
            $this->addFlash("danger", $translator->trans("admin.action.new.unable-to-load-parent"));
        }

        $record = new Navigation();
        $record->setParent($parentRecord);
        $edit = new \App\Engine\Inertia\Admin\ViewModels\EditViewModel(
            record: $record,
        );

        $form = $this->createEditForm($translator, $record)
            ->remove("submit")
            ->add("submit", \Symfony\Component\Form\Extension\Core\Type\SubmitType::class, [
                "label" => $translator->trans("admin.action.edit.create"),
            ]);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->resetUrlIfPageIsSet($record);
            $entityManager->persist($record);
            $entityManager->flush();
            $this->addFlash("success", $translator->trans("admin.action.new.successfully-created"));
            return $this->redirectToRoute("AdminNavigationList", ["parentId" => $parentRecord?->getId()]);
        }

        return $this->createEditResponse($twig, $form, $edit);
    }

    public function delete(
        NavigationRepository                               $repository,
        \Doctrine\ORM\EntityManagerInterface               $entityManager,
        \Symfony\Contracts\Translation\TranslatorInterface $translator,
        \Symfony\Component\HttpFoundation\Request          $request,
    ) {
        $recordId = $request->attributes->get("id");
        $entity = $repository->findOneBy(["id" => $recordId]);
        if (!$entity) {
            $this->addFlash("danger", $translator->trans("admin.action.delete.unable-to-delete-record"));
            return $this->redirectToRoute("AdminNavigationList");
        }

        return $this->createDelete(
            entity: $entity,
            redirectRoute: "AdminNavigationList",
            entityManager: $entityManager,
            translator: $translator
        );
    }

}
