<?php

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Admin;

use A2lix\TranslationFormBundle\Form\Type\TranslatedEntityType;
use A2lix\TranslationFormBundle\Form\Type\TranslationsType;
use CpCreation\VitiCore\Product\Model\ProductPrice;
use CpCreation\VitiCore\Product\Model\ProductType;
use CpCreation\VitiCore\Product\Model\ProductVariant;
use CpCreation\VitiCore\Product\Repository\ProductPriceGroupRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

/**
 * Created by Colinet Julien
 */
class ProductVariantType extends AbstractType
{
    /**
     * @var array
     */
    private $groups;
    private $authorizationChecker;
    private $requestStack;

    public function __construct(ProductPriceGroupRepository   $productPriceGroupRepository,
                                AuthorizationCheckerInterface $authorizationChecker,
                                RequestStack                  $requestStack
    )
    {
        $this->groups = $productPriceGroupRepository->findByPositionOrder();
        $this->authorizationChecker = $authorizationChecker;
        $this->requestStack = $requestStack;
    }

    public
    function buildForm(FormBuilderInterface $builder,
                       array                $options
    )
    {
        if ($this->authorizationChecker->isGranted('ROLE_ADMIN') || $this->authorizationChecker->isGranted('ROLE_PRODUCT')) {
            $builder
                ->add(
                    'type', TranslatedEntityType::class, [
                        'label' => 'Type',
                        'class' => ProductType::class,
                        'choice_label' => function (ProductType $type) {
                            if (null === ($request = $this->requestStack->getCurrentRequest())) {
                                throw new \RuntimeException('Error while getting request');
                            }
                            if ($type->getInfo()) {
                                return $type->getName() . '(' . $type->getInfo() . ')';
                            } else {
                                return $type->getName();
                            }

                        },
                        'translation_property' => 'name',
                        'required' => true,
                    ]
                )
                ->add(
                    'byDefault', CheckboxType::class, [
                        'label' => 'Défaut',
                        'required' => false,
                    ]
                )
                ->add(
                    'lot', IntegerType::class, [
                        'required' => true,
                        'label' => 'Vendu par',
                    ]
                )
                ->add(
                    'position', HiddenType::class, [
                        'label' => 'position',
                        'attr' => [
                            'class' => 'position-form',
                        ],
                        'required' => false,
                    ]
                );
        }
        $builder
            ->add(
                'unPublished', CheckboxType::class, [
                    'label' => 'Dépublié',
                    'required' => false,
                ]
            )
            ->add(
                'soldOut', CheckboxType::class, [
                    'label' => 'Epuisé',
                    'required' => false,
                ]
            )
            ->add(
                'stockAt', DateTimeType::class, [
                    'required' => false,
                    'label' => 'Date renouvellement de stock',
                    'input' => 'datetime',
                    'format' => 'yyyy-MM-dd HH:mm',
                    'html5' => false,
                    'widget' => 'single_text',
                    'attr' => [
                        'class' => 'datetimepicker',
                    ],
                ]

            )
            ->add('stock', NumberType::class, [
                'required' => false,
                'label' => 'Stock de départ'
            ])
            ->add(
                'prices', PriceCollectionType::class, [
                    'entry_type' => ProductPriceType::class,
                    'label' => false,
                    'allow_add' => true,
                    'allow_delete' => false,
                    'by_reference' => false,
                    'prototype' => true,
                    'entry_options' => [
                        'data_class' => ProductPrice::class,
                        'label' => false,
                    ],
                ]
            );

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            /** @var ProductVariant $variant */
            $variant = $event->getData();
            $form = $event->getForm();
            $data = [];
            $add = false;

            if (!$variant) {
                foreach ($this->groups as $group) {
                    $price = new ProductPrice();
                    $price->setGroup($group);
                    $data[] = $price;
                }
            } else {
                /** @var ProductPrice $price */
                foreach ($this->groups as $group) {
                    foreach ($variant->getPrices() as $price) {
                        if ($price->getGroup() === $group) {
                            $add = false;
                            break;
                        } else {
                            $add = true;
                        }
                    }
                    if ($add) {
                        $price = new ProductPrice();
                        $price->setGroup($group);
                        $data[] = $price;
                    }
                }

                $data = array_merge($data, $variant->getPrices()->toArray());
            }

            $form->add(
                'prices', PriceCollectionType::class, [
                    'entry_type' => ProductPriceType::class,
                    'label' => false,
                    'allow_add' => true,
                    'allow_delete' => false,
                    'prototype' => true,
                    'by_reference' => false,
                    'data' => $data,
                    'entry_options' => [
                        'data_class' => ProductPrice::class,
                        'label' => false,
                    ],
                ]
            );
        }
        );
    }

    public
    function configureOptions(OptionsResolver $resolver
    )
    {
        $resolver->setDefaults(
            [
                'data_class' => ProductVariant::class,
            ]
        );
    }

}
