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

use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Form\Type\ChillTextareaType;
use Chill\MainBundle\Form\Type\UserPickerType;
use Chill\PersonBundle\Form\Type\ClosingMotivePickerType;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * Class AccompanyingPeriodType.
 */
class AccompanyingPeriodType extends AbstractType
{
    /**
     * array of configuration for accompanying_periods.
     *
     * Contains whether we should add fields some optional fields (optional per
     * instance)
     *
     * @var string[]
     */
    protected $config = [];

    /**
     * @param string[] $config configuration of visibility of some fields
     */
    public function __construct(array $config)
    {
        $this->config = $config;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // if the period_action is close, date opening should not be seen
        if ('close' !== $options['period_action']) {
            $builder
                ->add('openingDate', DateType::class, [
                    'required' => true,
                    'widget' => 'single_text',
                    'format' => 'dd-MM-yyyy',
                ]);
        }

        // closingDate should be seen only if
        // period_action = close
        // OR ( period_action = update AND accompanying period is already closed )
        $accompanyingPeriod = $options['data'];

        if (
            ('close' === $options['period_action'])
            || ('create' === $options['period_action'])
            || ('update' === $options['period_action'] && !$accompanyingPeriod->isOpen())
        ) {
            $builder->add('closingDate', DateType::class, [
                'required' => true,
                'widget' => 'single_text',
                'format' => 'dd-MM-yyyy',
            ]);

            $builder->add('closingMotive', ClosingMotivePickerType::class);
        }

        if ('visible' === $this->config['user']) {
            $builder->add('user', UserPickerType::class, [
                'center' => $options['center'],
                'role' => PersonVoter::SEE,
            ]);
        }

        $builder->add('remark', ChillTextareaType::class, [
            'required' => false,
        ]);
    }

    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['action'] = $options['period_action'];
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => \Chill\PersonBundle\Entity\AccompanyingPeriod::class,
        ]);

        $resolver
            ->setRequired(['period_action'])
            ->addAllowedTypes('period_action', 'string')
            ->addAllowedValues('period_action', ['update', 'open', 'close', 'create'])
            ->setRequired('center')
            ->setAllowedTypes('center', Center::class);
    }

    /**
     * @return string
     */
    public function getBlockPrefix()
    {
        return 'chill_personbundle_accompanyingperiod';
    }
}
