<?php
/**
 * For the full copyright and license information, please view the
 * docs/licenses/LICENSE.txt file that was distributed with this source code.
 */

declare(strict_types=1);

namespace Tests\Integration\PrestaShopBundle\Form\Admin\Sell\Product\EventListener;

use Generator;
use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\RedirectType;
use PrestaShopBundle\Form\Admin\Sell\Product\EventListener\RedirectOptionListener;
use PrestaShopBundle\Form\Admin\Type\CommonAbstractType;
use PrestaShopBundle\Form\Admin\Type\EntitySearchInputType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Tests\Integration\PrestaShopBundle\Form\FormListenerTestCase;

class RedirectOptionListenerTest extends FormListenerTestCase
{
    public function testSubscribedEvents(): void
    {
        // Only events are relevant, the matching function is up to implementation
        $expectedSubscribedEvents = [
            FormEvents::PRE_SET_DATA,
            FormEvents::PRE_SUBMIT,
        ];
        $subscribedEvents = RedirectOptionListener::getSubscribedEvents();
        $this->assertSame($expectedSubscribedEvents, array_keys($subscribedEvents));
    }

    /**
     * @dataProvider getExpectedOptionsBasedOnData
     */
    public function testTargetOptionsBasedOnData(string $redirectionType, array $expectedOptions): void
    {
        $form = $this->createForm(SimpleTargetFormTest::class);
        $this->adaptRedirectOptions($form, ['type' => $redirectionType]);

        $targetForm = $form->get('target');
        foreach ($expectedOptions as $optionName => $expectedValue) {
            $this->assertEquals($expectedValue, $targetForm->getConfig()->getOption($optionName));
        }
    }

    public function getExpectedOptionsBasedOnData(): Generator
    {
        yield [
            RedirectType::TYPE_CATEGORY_PERMANENT,
            [
                'label' => SimpleTargetFormTest::CATEGORY_LABEL,
                'placeholder' => SimpleTargetFormTest::CATEGORY_PLACEHOLDER,
                'help' => SimpleTargetFormTest::CATEGORY_HELP,
                'remote_url' => SimpleTargetFormTest::CATEGORY_SEARCH_URL,
                'filtered_identities' => SimpleTargetFormTest::CATEGORY_FILTERED,
            ],
        ];

        yield [
            RedirectType::TYPE_CATEGORY_TEMPORARY,
            [
                'label' => SimpleTargetFormTest::CATEGORY_LABEL,
                'placeholder' => SimpleTargetFormTest::CATEGORY_PLACEHOLDER,
                'help' => SimpleTargetFormTest::CATEGORY_HELP,
                'remote_url' => SimpleTargetFormTest::CATEGORY_SEARCH_URL,
                'filtered_identities' => SimpleTargetFormTest::CATEGORY_FILTERED,
            ],
        ];

        yield [
            RedirectType::TYPE_PRODUCT_PERMANENT,
            [
                'label' => SimpleTargetFormTest::PRODUCT_LABEL,
                'placeholder' => SimpleTargetFormTest::PRODUCT_PLACEHOLDER,
                'help' => SimpleTargetFormTest::PRODUCT_HELP,
                'remote_url' => SimpleTargetFormTest::PRODUCT_SEARCH_URL,
                'filtered_identities' => SimpleTargetFormTest::PRODUCT_FILTERED,
            ],
        ];

        yield [
            RedirectType::TYPE_PRODUCT_TEMPORARY,
            [
                'label' => SimpleTargetFormTest::PRODUCT_LABEL,
                'placeholder' => SimpleTargetFormTest::PRODUCT_PLACEHOLDER,
                'help' => SimpleTargetFormTest::PRODUCT_HELP,
                'remote_url' => SimpleTargetFormTest::PRODUCT_SEARCH_URL,
                'filtered_identities' => SimpleTargetFormTest::PRODUCT_FILTERED,
            ],
        ];

        // Default is product
        yield [
            RedirectType::TYPE_NOT_FOUND,
            [
                'label' => SimpleTargetFormTest::PRODUCT_LABEL,
                'placeholder' => SimpleTargetFormTest::PRODUCT_PLACEHOLDER,
                'help' => SimpleTargetFormTest::PRODUCT_HELP,
                'remote_url' => SimpleTargetFormTest::PRODUCT_SEARCH_URL,
                'filtered_identities' => SimpleTargetFormTest::PRODUCT_FILTERED,
                'row_attr' => [
                    'class' => 'd-none',
                ],
            ],
        ];
    }

    /**
     * @param FormInterface $form
     * @param array $formData
     */
    private function adaptRedirectOptions(FormInterface $form, array $formData): void
    {
        $listener = new RedirectOptionListener();

        $eventMock = $this->createEventMock($formData, $form);
        $listener->updateRedirectionOptions($eventMock);
    }
}

class SimpleTargetFormTest extends CommonAbstractType
{
    public const PRODUCT_LABEL = 'Product label';
    public const PRODUCT_PLACEHOLDER = 'Product placeholder';
    public const PRODUCT_SEARCH_URL = 'Product search url';
    public const PRODUCT_HELP = 'Product help';
    public const PRODUCT_FILTERED = [42];

    public const CATEGORY_LABEL = 'Category label';
    public const CATEGORY_PLACEHOLDER = 'Category placeholder';
    public const CATEGORY_SEARCH_URL = 'Category search url';
    public const CATEGORY_HELP = 'Category help';
    public const CATEGORY_FILTERED = [51];

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('type', FormType::class)
            ->add('target', EntitySearchInputType::class, [
                'attr' => [
                    'data-product-label' => static::PRODUCT_LABEL,
                    'data-product-placeholder' => static::PRODUCT_PLACEHOLDER,
                    'data-product-search-url' => static::PRODUCT_SEARCH_URL,
                    'data-product-help' => static::PRODUCT_HELP,
                    'data-product-filtered' => json_encode(static::PRODUCT_FILTERED),
                    'data-category-label' => static::CATEGORY_LABEL,
                    'data-category-placeholder' => static::CATEGORY_PLACEHOLDER,
                    'data-category-help' => static::CATEGORY_HELP,
                    'data-category-search-url' => static::CATEGORY_SEARCH_URL,
                    'data-category-filtered' => json_encode(static::CATEGORY_FILTERED),
                ],
            ])
        ;
    }
}
