<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Controller;

use Chill\MainBundle\Entity\SavedExport;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\ExportManager;
use Chill\MainBundle\Export\GroupedExportInterface;
use Chill\MainBundle\Repository\ExportGenerationRepository;
use Chill\MainBundle\Repository\SavedExportRepositoryInterface;
use Chill\MainBundle\Security\Authorization\ChillExportVoter;
use Chill\MainBundle\Security\Authorization\SavedExportVoter;
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;

final readonly class SavedExportIndexController
{
    public function __construct(
        private \Twig\Environment $templating,
        private ExportManager $exportManager,
        private SavedExportRepositoryInterface $savedExportRepository,
        private Security $security,
        private TranslatorInterface $translator,
        private ExportGenerationRepository $exportGenerationRepository,
        private FilterOrderHelperFactoryInterface $filterOrderHelperFactory,
    ) {}

    #[Route(path: '/{_locale}/exports/saved/my', name: 'chill_main_export_saved_list_my')]
    public function list(): Response
    {
        $user = $this->security->getUser();

        if (!$this->security->isGranted(ChillExportVoter::GENERATE_SAVED_EXPORT) || !$user instanceof User) {
            throw new AccessDeniedHttpException(sprintf('Missing role: %s', ChillExportVoter::GENERATE_SAVED_EXPORT));
        }

        $filter = $this->buildFilter();

        $filterParams = [];
        if ('' !== $filter->getQueryString() && null !== $filter->getQueryString()) {
            $filterParams[SavedExportRepositoryInterface::FILTER_DESCRIPTION | SavedExportRepositoryInterface::FILTER_TITLE] = $filter->getQueryString();
        }

        $exports = array_filter(
            $this->savedExportRepository->findSharedWithUser($user, ['exportAlias' => 'ASC', 'title' => 'ASC'], filters: $filterParams),
            fn (SavedExport $savedExport): bool => $this->security->isGranted(SavedExportVoter::GENERATE, $savedExport),
        );

        // group by center
        /** @var array<string, array{saved: SavedExport, export: ExportInterface}> $exportsGrouped */
        $exportsGrouped = [];

        foreach ($exports as $savedExport) {
            $export = $this->exportManager->getExport($savedExport->getExportAlias());

            $exportsGrouped[$export instanceof GroupedExportInterface
                ? $this->translator->trans($export->getGroup()) : '_'][] = ['saved' => $savedExport, 'export' => $export];
        }

        ksort($exportsGrouped);

        // get last executions
        $lastExecutions = [];
        foreach ($exports as $savedExport) {
            $lastExecutions[$savedExport->getId()->toString()] = $this->exportGenerationRepository
                ->findExportGenerationBySavedExportAndUser($savedExport, $user, 5);
        }

        return new Response(
            $this->templating->render(
                '@ChillMain/SavedExport/index.html.twig',
                [
                    'grouped_exports' => $exportsGrouped,
                    'total' => \count($exports),
                    'last_executions' => $lastExecutions,
                    'filter' => $filter,
                ],
            ),
        );
    }

    private function buildFilter(): FilterOrderHelper
    {
        $filter = $this->filterOrderHelperFactory->create('saved-export-index-filter');
        $filter->addSearchBox();

        return $filter->build();
    }
}
