<?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\MainBundle\Entity\User;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepository;
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;

class UserAccompanyingPeriodController extends AbstractController
{
    public function __construct(
        private readonly AccompanyingPeriodRepository $accompanyingPeriodRepository,
        private readonly PaginatorFactory $paginatorFactory,
        private readonly AccompanyingPeriodACLAwareRepository $accompanyingPeriodACLAwareRepository,
        private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory,
        private readonly TranslatorInterface $translator,
    ) {}

    /**
     * @throws NonUniqueResultException
     * @throws NoResultException
     */
    #[Route(path: '/{_locale}/person/accompanying-periods/my', name: 'chill_person_accompanying_period_user')]
    public function listAction(Request $request): Response
    {
        $filter = (int) $request->query->get('filter', 2);
        $user = $this->getUser();

        if (!$user instanceof User) {
            throw new \LogicException('Expected an instance of Chill\MainBundle\Entity\User.');
        }

        $activeTab = match ($filter) {
            2 => 'referrer',
            4 => 'referrer_to_works',
            6 => 'both',
            8 => 'intervening',
            default => 'referrer',
        };

        $statusAndDateFilter = $this->buildStatusAndDateFilter($filter);

        $status = $statusAndDateFilter->getCheckboxData('statusFilter');
        $from = null;
        $to = null;

        if ('intervening' === $activeTab) {
            $interventionBetweenDates = $statusAndDateFilter->getDateRangeData('interventionBetweenDates');
            $from = $interventionBetweenDates['from'];
            $to = $interventionBetweenDates['to'];
        }

        $steps = [];

        if (in_array('is_open', $status, true)) {
            $steps[] = [
                ...$steps,
                AccompanyingPeriod::STEP_CONFIRMED,
                AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_LONG,
                AccompanyingPeriod::STEP_CONFIRMED_INACTIVE_SHORT,
            ];
        }

        if (in_array('is_closed', $status, true)) {
            $steps[] = AccompanyingPeriod::STEP_CLOSED;
        }

        $total = $this->accompanyingPeriodACLAwareRepository->countByUserAssociation($user, $steps, $from, $to, $filter);
        $paginator = $this->paginatorFactory->create($total);
        $accompanyingPeriods = $this->accompanyingPeriodACLAwareRepository->findByUserAssociation(
            $user,
            $steps,
            $from,
            $to,
            $filter,
            $paginator->getCurrentPageFirstItemNumber(),
            $paginator->getItemsPerPage(),
        );

        return $this->render('@ChillPerson/AccompanyingPeriod/user_periods_list.html.twig', [
            'accompanyingPeriods' => $accompanyingPeriods,
            'pagination' => $paginator,
            'activeTab' => $activeTab,
            'filter' => $filter,
            'statusFilter' => $statusAndDateFilter,
        ]);
    }

    #[Route(path: '/{_locale}/person/accompanying-periods/my/drafts', name: 'chill_person_accompanying_period_draft_user')]
    public function listDraftsAction(): Response
    {
        $total = $this->accompanyingPeriodRepository->countBy(['user' => $this->getUser(), 'step' => 'DRAFT']);
        $pagination = $this->paginatorFactory->create($total);
        $accompanyingPeriods = $this->accompanyingPeriodRepository->findBy(
            ['createdBy' => $this->getUser(), 'step' => 'DRAFT'],
            ['id' => 'DESC'],
            $pagination->getItemsPerPage(),
            $pagination->getCurrentPageFirstItemNumber()
        );

        return $this->render('@ChillPerson/AccompanyingPeriod/user_draft_periods_list.html.twig', [
            'accompanyingPeriods' => $accompanyingPeriods,
            'pagination' => $pagination,
        ]);
    }

    public function buildStatusAndDateFilter(int $filter)
    {
        $filterBuilder = $this->filterOrderHelperFactory
            ->create(self::class)
            ->addCheckbox(
                'statusFilter',
                ['is_open', 'is_closed'],
                ['is_open'],
                array_map(
                    static fn (string $s) => 'my_parcours_filters.'.$s,
                    ['is_open', 'is_closed']
                )
            );

        if (8 === $filter) {
            $filterBuilder->addDateRange(
                'interventionBetweenDates',
                $this->translator->trans('Since'),
                new \DateTimeImmutable('-6 months'),
            );
        }

        return $filterBuilder->build();
    }
}
