<?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\Form\Type;

use Chill\MainBundle\Form\Type\DataTransformer\DateIntervalTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\GreaterThan;

/**
 * Show a dateInterval type.
 *
 * Options:
 *
 * - `unit_choices`: an array of available units choices.
 *
 * The oiriginal `unit_choices` are :
 * ```
 * [
 *      'Days' => 'D',
 *      'Weeks' => 'W',
 *      'Months' => 'M',
 *      'Years' => 'Y'
 * ]
 * ```
 *
 * You can remove one or more entries:
 *
 * ```
 * $builder
 *      ->add('duration', DateIntervalType::class, array(
 *          'unit_choices' => [
 *              'Years' => 'Y',
 *              'Months' => 'M',
 *      ]
 * ));
 * ```
 */
class DateIntervalType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('n', IntegerType::class, [
                'attr' => [
                    'min' => 0,
                    'step' => 1,
                ],
                'constraints' => [
                    new GreaterThan([
                        'value' => 0,
                    ]),
                ],
            ])
            ->add('unit', ChoiceType::class, [
                'choices' => $options['unit_choices'],
            ]);

        $builder->addModelTransformer(new DateIntervalTransformer());
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver
            ->setDefined('unit_choices')
            ->setDefault('unit_choices', [
                'Days' => 'D',
                'Weeks' => 'W',
                'Months' => 'M',
                'Years' => 'Y',
            ])
            ->setAllowedValues('unit_choices', static function ($values) {
                if (false === \is_array($values)) {
                    throw new InvalidOptionsException('The value `unit_choice` should be an array');
                }

                $diff = \array_diff(\array_values($values), ['D', 'W', 'M', 'Y']);

                if (0 === \count($diff)) {
                    return true;
                }

                throw new InvalidOptionsException(sprintf('The values of the '."units should be 'D', 'W', 'M', 'Y', those are invalid: %s", \implode(', ', $diff)));
            });
    }
}
