<?php

/**
 * Form Type for Form
 *
 * @author Elze Kool <info@visualmedia.nl>
 */

namespace VisualM\FormBundle\Form\Type;

use Datetime;
use RuntimeException;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use VisualM\FormBundle\Entity\FormField;
use VisualM\FormBundle\Form\Data\GeneratedFormData;
use VisualM\FormBundle\Form\TypeHandler\CheckboxListTypeHandler;
use VisualM\FormBundle\Form\TypeHandler\DateTypeHandler;
use VisualM\FormBundle\Form\TypeHandler\EmailTypeHandler;
use VisualM\FormBundle\Form\TypeHandler\FormTypeHandlerInterface;
use VisualM\FormBundle\Form\TypeHandler\HiddenTypeHandler;
use VisualM\FormBundle\Form\TypeHandler\NumberTypeHandler;
use VisualM\FormBundle\Form\TypeHandler\OptionListTypeHandler;
use VisualM\FormBundle\Form\TypeHandler\PhoneTypeHandler;
use VisualM\FormBundle\Form\TypeHandler\SelectListTypeHandler;
use VisualM\FormBundle\Form\TypeHandler\SelectTypeHandler;
use VisualM\FormBundle\Form\TypeHandler\TextareaTypeHandler;
use VisualM\FormBundle\Form\TypeHandler\TextTypeHandler;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;

/**
 * Form Type for Form
 *
 * @author Elze Kool <info@visualmedia.nl>
 */
class GeneratedFormType extends AbstractType
{
      
    /**
     * {@inhertDoc@}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        foreach ($options['fields'] as $formField) {

            if (!isset($options['type_handlers'][$formField->getType()])) {
                throw new RuntimeException(sprintf(
                    'Unkown form field type "%s" in %s',
                    $formField->getType(), get_class($this))
                );
            }

            $typeHandler = $options['type_handlers'][$formField->getType()];

            $builder->add(
                $formField->getReferentie(),
                $typeHandler->getSymfonyType($formField),
                array_merge($typeHandler->getOptions($formField), [ 'mapped' => false ])
            );   
      
        }
        
        $builder->add('accept', CheckboxType::class, array(
            'label' => false,
            'required' => false,
            'mapped' => false,
            'attr'   =>  array(
                'class'   => 'hidden'
            ),
        ));
       

        $builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) use ($options) {
            $form = $event->getForm();
            $data = $event->getData();
          
            foreach ($options['fields'] as $formField) {
                $name = $formField->getReferentie();
                $typeHandler = $options['type_handlers'][$formField->getType()];

                if (!$form->has($name)) {
                    continue;
                }
                 
                $value = $typeHandler->normalizeValue($formField, $form->get($name)->getData());
                $data->set($name, $value);
            }
        });

    }
    
    /**
     * {@inhertDoc@}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver
            ->setDefault('class', GeneratedFormData::class)
            ->setRequired(['fields'])
            ->setDefault('type_handlers', $this->getDefaultHandlers())
            ->setAllowedTypes('type_handlers', 'array')
            ->setAllowedValues('type_handlers', function (array $typeHandlers) {
                foreach ($typeHandlers as $typeHandler) {
                    if (!($typeHandler instanceof FormTypeHandlerInterface)) {
                        return false;
                    }
                }
                return true;
            });            
    }


    private function getDefaultHandlers()
    {
        return [
            FormField::HIDDEN => new HiddenTypeHandler(),
            FormField::TEXT => new TextTypeHandler(),
            FormField::NUMBER => new NumberTypeHandler(),
            FormField::PHONE => new PhoneTypeHandler(),
            FormField::EMAIL => new EmailTypeHandler(),
            FormField::DATE => new DateTypeHandler(),
            FormField::TEXTAREA => new TextareaTypeHandler(),
            FormField::SELECT => new SelectTypeHandler(),
            FormField::SELECTLIST => new SelectListTypeHandler(),
            FormField::CHECKBOXLIST => new CheckboxListTypeHandler(),
            FormField::OPTIONLIST => new OptionListTypeHandler(),
        ];

        /* Todo
          // Kijk of we een subform moeten includen
          foreach($this->formManager->getIndex() as $formEntity) {
          if ($formField->getType() == sprintf('form#%d[]', $formEntity->getId())) {

          $collectionType = new SubformGeneratorType(
          'vm_form_' . $formField->getReferentie() . '_' . $formEntity->getReferentie(),
          function(FormBuilderInterface $subFormBuilder) use ($formEntity) {
          foreach($formEntity->getFields() as $subFormField) {
          $this->addField($subFormBuilder, $subFormField);
          }
          }
          );
          $this->addFieldToBuilder($formBuilder, $formField, $formField->getReferentie(), CollectionType::class, [
          'label' => false,
          'allow_add' => true,
          'allow_delete' => true,
          'entry_type' => $collectionType,
          'mapped' => false
          ]);

          return;
          }
          }
         */
    }

}
