<?php

/**
 * 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.
 */

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\CalendarBundle\Export\Filter;

use Chill\CalendarBundle\Export\Declarations;
use Chill\MainBundle\Export\ExportGenerationContext;
use Chill\MainBundle\Export\FilterInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

class CalendarRangeFilter implements FilterInterface
{
    private const CHOICES = [
        'Not made within a calendar range' => 'true',
        'Made within a calendar range' => 'false',
    ];

    private const DEFAULT_CHOICE = 'false';

    public function __construct(private readonly TranslatorInterface $translator) {}

    public function addRole(): ?string
    {
        return null;
    }

    public function alterQuery(QueryBuilder $qb, $data, ExportGenerationContext $exportGenerationContext): void
    {
        if (null !== $data['hasCalendarRange']) {
            $qb->andWhere($qb->expr()->isNotNull('cal.calendarRange'));
        } else {
            $qb->andWhere($qb->expr()->isNull('cal.calendarRange'));
        }
    }

    public function applyOn(): string
    {
        return Declarations::CALENDAR_TYPE;
    }

    public function buildForm(FormBuilderInterface $builder): void
    {
        $builder->add('hasCalendarRange', ChoiceType::class, [
            'choices' => self::CHOICES,
            'label' => 'has calendar range',
            'multiple' => false,
            'expanded' => true,
            'empty_data' => self::DEFAULT_CHOICE,
        ]);
    }

    public function getNormalizationVersion(): int
    {
        return 1;
    }

    public function normalizeFormData(array $formData): array
    {
        return ['hasCalendarRange' => $formData['hasCalendarRange']];
    }

    public function denormalizeFormData(array $formData, int $fromVersion): array
    {
        return ['hasCalendarRange' => $formData['hasCalendarRange']];
    }

    public function getFormDefaultData(): array
    {
        return ['hasCalendarRange' => self::DEFAULT_CHOICE];
    }

    public function describeAction($data, ExportGenerationContext $context): array
    {
        $choice = '';

        foreach (self::CHOICES as $k => $v) {
            if ($v === $data['hasCalendarRange']) {
                $choice = $k;
            } else {
                $choice = 'Not made within a calendar range';
            }
        }

        return [
            'Filtered by calendar range: only %calendarRange%', [
                '%calendarRange%' => $this->translator->trans($choice),
            ],
        ];
    }

    public function getTitle(): string
    {
        return 'Filter by calendar range';
    }
}
