<?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\PersonBundle\Controller;

use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Serializer\Model\Collection;
use Chill\MainBundle\Serializer\Model\Counter;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\SerializerInterface;

class AccompanyingPeriodWorkEvaluationApiController
{
    public function __construct(private readonly AccompanyingPeriodWorkEvaluationRepository $accompanyingPeriodWorkEvaluationRepository, private readonly DocGeneratorTemplateRepository $docGeneratorTemplateRepository, private readonly SerializerInterface $serializer, private readonly PaginatorFactory $paginatorFactory, private readonly Security $security) {}

    #[Route(path: '/api/1.0/person/docgen/template/by-evaluation/{id}.{_format}', requirements: ['format' => 'json'])]
    public function listTemplateByEvaluation(Evaluation $evaluation, string $_format): JsonResponse
    {
        if ('json' !== $_format) {
            throw new BadRequestHttpException('format not supported');
        }

        $evaluations =
            array_filter(
                $this->docGeneratorTemplateRepository
                    ->findByEntity(AccompanyingPeriodWorkEvaluation::class, 0, 500),
                static function (DocGeneratorTemplate $t) use ($evaluation) {
                    $ids = $t->getOptions()['evaluations'] ?? [];

                    return \in_array($evaluation->getId(), $ids, true);
                }
            );

        $paginator = $this->paginatorFactory->create(\count($evaluations));
        $paginator->setItemsPerPage(\count($evaluations));

        return new JsonResponse($this->serializer->serialize(
            new Collection(array_values($evaluations), $paginator),
            'json',
            [
                AbstractNormalizer::GROUPS => ['read'],
            ]
        ), JsonResponse::HTTP_OK, [], true);
    }

    #[Route(path: '/api/1.0/person/accompanying-period/work/evaluation/my-near-end')]
    public function myWorksNearEndDate(Request $request): JsonResponse
    {
        $total = $this->accompanyingPeriodWorkEvaluationRepository
            ->countNearMaxDateByUser($this->security->getUser());

        if ($request->query->getBoolean('countOnly', false)) {
            return new JsonResponse(
                $this->serializer->serialize(new Counter($total), 'json', ['groups' => ['read']]),
                JsonResponse::HTTP_OK,
                [],
                true
            );
        }

        $paginator = $this->paginatorFactory->create($total);
        $works = $this->accompanyingPeriodWorkEvaluationRepository
            ->findNearMaxDateByUser(
                $this->security->getUser(),
                $paginator->getItemsPerPage(),
                $paginator->getCurrentPageFirstItemNumber()
            );

        $collection = new Collection($works, $paginator);

        return new JsonResponse(
            $this->serializer->serialize($collection, 'json', ['groups' => ['read', 'read:evaluation:include-work']]),
            JsonResponse::HTTP_OK,
            [],
            true
        );
    }
}
