<?php declare(strict_types=1);

namespace App\Engine\Admin\Inertia;

abstract class BaseInertiaAdminController extends \App\Engine\Inertia\BaseInertiaController
{

    public function __construct(
        \Rompetomp\InertiaBundle\Architecture\InertiaInterface                                   $inertia,
        \Symfony\Component\HttpFoundation\RequestStack                                           $requestStack,
        protected \App\Engine\Admin\Paginator                                                    $paginator,
        protected \App\Engine\Admin\Storage\StorageUploader                                      $storageUploader,
        protected \App\Engine\Admin\Inertia\SystemConfiguration\AdminSystemConfigurationProvider $adminSystemConfigurationProvider,
    ) {
        parent::__construct($inertia, $requestStack);
    }

    public function createList(\App\Engine\Admin\AdminRepositoryInterface $repository, ?array $records = null): \Symfony\Component\HttpFoundation\Response
    {
        if ($records === null) {
            $records = $this->provideListRecords($repository);
        }

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

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

    public function getVueComponent(): string
    {
        return "Admin/{$this->getId()}";
    }

    public function createDelete(
        object                                             $entity,
        string                                             $redirectRoute,
        \Doctrine\ORM\EntityManagerInterface               $entityManager,
        \Symfony\Contracts\Translation\TranslatorInterface $translator,
    ): \Symfony\Component\HttpFoundation\RedirectResponse {
        if (method_exists($entity, "getChildren")) {
            $children = $entity->getChildren();
            foreach ($children as $child) {
                $child->setParent($entity->getParent());
                $entityManager->persist($entity);
            }
            if (!$children->isEmpty()) {
                $this->addFlash("warning", $translator->trans("admin.action.delete.children-moved-under-parent"));
            }
        }

        $entityManager->remove($entity);
        $entityManager->flush();

        $this->addFlash("success", $translator->trans("admin.action.delete.record-deleted"));
        return $this->redirectToRoute($redirectRoute);
    }

    protected function provideListRecords(\App\Engine\Admin\AdminRepositoryInterface $repository): array
    {
        return $repository->loadAll();
    }

    protected function createListViewModel(array $records, int $pageSize = 25): \App\Engine\Inertia\Admin\List\ListViewModel
    {
        $currentPage = $this->paginator->getCurrentPageFromRequest();
        $totalRecords = count($records);
        if ($currentPage < 1 || $currentPage > ceil($totalRecords / $pageSize)) {
            $currentPage = 1; // Pokud někdo pošle do URL nějaký nesmysl, tak nastavíme na výchozí hodnotu.
        }
        $records = array_slice($records, offset: ($currentPage - 1) * $pageSize, length: $pageSize);

        return new \App\Engine\Inertia\Admin\List\ListViewModel(
            items: $records,
            pageSize: $pageSize,
            totalRecords: $totalRecords,
            pagination: $totalRecords > $pageSize
                ? $this->paginator->createPagination(
                    totalRecords: $totalRecords,
                    currentPage: $currentPage,
                    pageSize: $pageSize,
                )
                : null,
        );
    }

    protected function getInertiaProps(?\App\Engine\Inertia\InertiaProps $props = null): array
    {
        $props = $props ?? new \App\Engine\Inertia\Admin\Props\AdministrationProps();
        $props->configuration = $this->adminSystemConfigurationProvider->getConfiguration();

        return parent::getInertiaProps($props);
    }

    /**
     * @param callable(string $path): void $setImage
     */
    protected function processImageFile(\Symfony\Component\Form\FormInterface $form, string $fieldName, string $recordTitle, callable $setImage): void
    {
        $this->storageUploader->processFile($form, $fieldName, $recordTitle, $setImage);
    }

    protected function createEditResponse(\Twig\Environment $twig, \Symfony\Component\Form\FormInterface $form, \App\Engine\Inertia\Admin\ViewModels\EditViewModel $edit): \Symfony\Component\HttpFoundation\Response
    {
        $renderedForm = $twig->render('form/form.html.twig', ['form' => $form->createView()]);

        $props = new \App\Engine\Inertia\Admin\Props\DetailProps();
        $props->form = new \App\Engine\Inertia\ViewModels\Form\FormViewModel(
            renderedForm: $renderedForm,
        );
        $props->edit = $edit;

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

}
