<?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\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
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\IntegerTypeHandler;
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 VisualM\FormBundle\Form\TypeHandler\FileTypeHandler;

/**
 * Form Type for Form
 *
 * @author Elze Kool <info@visualmedia.nl>
 */
class GeneratedFormType extends AbstractType
{

    /**
     * Container
     * @var mixed
     */
    protected $container;

    /**
     * Set Container
     */
    public function setContainer($container)
    {
        $this->container = $container;
    }

    /**
     * {@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('spamcheck', HiddenType::class, array(
            'label' => false,
            'required' => false,
            'mapped' => false,
        ));

        $builder->add('accept', CheckboxType::class, array(
            'label' => false,
            'required' => false,
            'mapped' => false,
            'attr' =>  array(
                'style' => 'margin-left:-1234em;',
                'tabindex' => '-1',
            ),
        ));

        $builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) use ($options) {
            $form = $event->getForm();
            $data = $event->getData();
            $datenow = new DateTime();

            foreach ($options['fields'] as $formField) {
                $name = $formField->getReferentie();
                $typeHandler = $options['type_handlers'][$formField->getType()];

                if (!$form->has($name)) {
                    continue;
                }

                if($formField->getType() == 'file'){
                    $file = $form->get($name)->getData();

                    if (!empty($file) AND  $form->isValid()) {
                        preg_match('/(.*?)([\/.].*)/'  ,$file->getClientOriginalName(), $match);
                        $filename = $match[1];
                        $extention = $match[2];

                        $newfilename = $filename . '-' . $datenow->format('d-m-Y') . $extention;
                        $file->move('userfiles/form/uploads/', $newfilename);
                    }
                }

                $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($this->container))
            ->setAllowedTypes('type_handlers', 'array')
            ->setAllowedValues('type_handlers', function (array $typeHandlers) {
                foreach ($typeHandlers as $typeHandler) {
                    if (!($typeHandler instanceof FormTypeHandlerInterface)) {
                        return false;
                    }
                }
                return true;
            });
    }

    /**
     * Get Default Handlers
     *
     * @param mixed $container
     */

    public static function getDefaultHandlers($container = null)
    {
        $fieldhandelers = array(
            FormField::HIDDEN => new HiddenTypeHandler(),
            FormField::TEXT => new TextTypeHandler(),
            FormField::NUMBER => new NumberTypeHandler(),
            Formfield::INTEGER => new IntegerTypeHandler(),
            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(),
        );

        if (!empty($container)){
            $fieldhandelers[FormField::FILE] = new FileTypeHandler($container);
        }

        return $fieldhandelers;
        


        /* 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;
          }
          }
         */
    }

}
