<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\CustomFieldsBundle\Tests\CustomFields;

use Chill\CustomFieldsBundle\Entity\CustomField;
use Symfony\Component\Form\FormBuilderInterface;

/**
 * Test CustomFieldsNumber.
 *
 * @internal
 *
 * @coversNothing
 */
final class CustomFieldsNumberTest extends \Symfony\Bundle\FrameworkBundle\Test\WebTestCase
{
    private ?object $customFieldNumber = null;

    /**
     * @var FormBuilderInterface
     */
    private $formBuilder;

    protected function setUp(): void
    {
        self::bootKernel();

        $this->customFieldNumber = self::$kernel->getContainer()
            ->get('chill.custom_field.number');

        $this->formBuilder = self::$kernel->getContainer()
            ->get('form.factory')
            ->createBuilder('form', null, [
                'csrf_protection' => false,
                'csrf_field_name' => '_token',
            ]);

        $request = new \Symfony\Component\HttpFoundation\Request();
        $request->setLocale('fr');

        self::$kernel->getContainer()
            ->get('request_stack')
            ->push($request);
    }

    public function testCreateInvalidFormValueGreaterThanMaximum()
    {
        $cf = $this->createCustomFieldNumber([
            'min' => null,
            'max' => 10,
            'scale' => null,
            'post_text' => null,
        ]);

        $this->customFieldNumber->buildForm($this->formBuilder, $cf);

        $form = $this->formBuilder->getForm();

        $form->submit(['default' => 100]);

        $this->assertTrue($form->isSynchronized());
        $this->assertFalse($form->isValid());
        $this->assertEquals(1, \count($form['default']->getErrors()));
    }

    public function testCreateInvalidFormValueLowerThanMinimum()
    {
        $cf = $this->createCustomFieldNumber([
            'min' => 1000,
            'max' => null,
            'scale' => null,
            'post_text' => null,
        ]);

        $this->customFieldNumber->buildForm($this->formBuilder, $cf);

        $form = $this->formBuilder->getForm();

        $form->submit(['default' => 100]);

        $this->assertTrue($form->isSynchronized());
        $this->assertFalse($form->isValid());
        $this->assertEquals(1, \count($form['default']->getErrors()));
    }

    public function testCreateValidForm()
    {
        $cf = $this->createCustomFieldNumber([
            'min' => null,
            'max' => null,
            'scale' => null,
            'post_text' => null,
        ]);

        $this->customFieldNumber->buildForm($this->formBuilder, $cf);

        $form = $this->formBuilder->getForm();

        $form->submit(['default' => 10]);

        $this->assertTrue($form->isSynchronized());
        $this->assertEquals(10, $form['default']->getData());
    }

    public function testRequiredFieldIsFalse()
    {
        $cf = $this->createCustomFieldNumber([
            'min' => 1000,
            'max' => null,
            'scale' => null,
            'post_text' => null,
        ]);
        $cf->setRequired(false);

        $cfGroup = (new \Chill\CustomFieldsBundle\Entity\CustomFieldsGroup())
            ->addCustomField($cf);

        $form = self::$kernel->getContainer()->get('form.factory')
            ->createBuilder(\Chill\CustomFieldsBundle\Form\Type\CustomFieldType::class, [], [
                'group' => $cfGroup,
            ])
            ->getForm();

        $this->assertFalse(
            $form['default']->isRequired(),
            'The field should not be required'
        );
    }

    public function testRequiredFieldIsTrue()
    {
        $cf = $this->createCustomFieldNumber([
            'min' => 1000,
            'max' => null,
            'scale' => null,
            'post_text' => null,
        ]);
        $cf->setRequired(true);

        $cfGroup = (new \Chill\CustomFieldsBundle\Entity\CustomFieldsGroup())
            ->addCustomField($cf);

        $form = self::$kernel->getContainer()->get('form.factory')
            ->createBuilder(\Chill\CustomFieldsBundle\Form\Type\CustomFieldType::class, [], [
                'group' => $cfGroup,
            ])
            ->getForm();

        $this->assertTrue(
            $form['default']->isRequired(),
            'The field should be required'
        );
    }

    /**
     * @param mixed[] $options
     *
     * @return CustomField
     */
    private function createCustomFieldNumber($options)
    {
        return (new CustomField())
            ->setType('number')
            ->setActive(true)
            ->setOrdering(10)
            ->setSlug('default')
            ->setName(['fr' => 'default'])
            ->setOptions($options);
    }
}
