<?php

/*
 * This file is part of the VITICORE2 package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Tests\Altcha;

use CpCreation\AltchaBundle\Form\AltchaType;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Site\ContactFormType;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Site\PaymentType;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Site\ProductReviewReportType;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Site\Security\RegisterConfirmType;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Site\Security\ResetPasswordType;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Site\Withdrawal\WithdrawalRequestType;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

final class VitiCoreAltchaFormIntegrationTest extends TestCase
{
    #[DataProvider('protectedForms')]
    public function testProtectedFormsUseTheGenericBundleType(
        AbstractType $type,
        array $buildOptions,
        string $expectedScope,
        ?array $expectedPartialActions,
        ?array $expectedFinalActions,
    ): void {
        $fields = [];
        $builder = $this->createMock(FormBuilderInterface::class);
        $builder
            ->method('add')
            ->willReturnCallback(static function (string $name, ?string $type = null, array $options = []) use (&$fields, $builder): FormBuilderInterface {
                $fields[$name] = ['type' => $type, 'options' => $options];

                return $builder;
            });

        $type->buildForm($builder, $buildOptions);

        self::assertArrayHasKey('captcha', $fields);
        self::assertSame(AltchaType::class, $fields['captcha']['type']);
        self::assertSame($expectedScope, $fields['captcha']['options']['scope'] ?? null);
        self::assertArrayNotHasKey('captcha_scope', $fields['captcha']['options']);
        self::assertArrayNotHasKey('subject_path', $fields['captcha']['options']);
        self::assertArrayNotHasKey('subject_limits_enabled', $fields['captcha']['options']);
        if (null === $expectedPartialActions) {
            self::assertArrayNotHasKey('partial_live_actions', $fields['captcha']['options']);
        } else {
            self::assertSame($expectedPartialActions, $fields['captcha']['options']['partial_live_actions'] ?? null);
        }
        if (null === $expectedFinalActions) {
            self::assertArrayNotHasKey('final_live_actions', $fields['captcha']['options']);
        } else {
            self::assertSame($expectedFinalActions, $fields['captcha']['options']['final_live_actions'] ?? null);
        }
    }

    public static function protectedForms(): iterable
    {
        yield 'contact' => [new ContactFormType(), [], 'site.contact', null, ['submitContact']];
        yield 'paiement en ligne' => [new PaymentType(), [], 'payment.online', null, ['submitPayment']];
        yield 'confirmation inscription' => [
            new RegisterConfirmType(),
            [],
            'security.registration_confirm',
            ['validatePasswords'],
            ['submitRegisterConfirm'],
        ];
        yield 'reset mot de passe' => [
            new ResetPasswordType(),
            ['include_captcha' => true],
            'security.password_reset',
            ['validatePasswords'],
            ['submitResetPassword'],
        ];
        yield 'signalement avis' => [
            new ProductReviewReportType(),
            [],
            'marketing.product_review_report',
            null,
            null,
        ];
        yield 'rétractation' => [
            new WithdrawalRequestType(),
            ['include_captcha' => true],
            'shop.withdrawal',
            null,
            null,
        ];
    }
}
