<?php

namespace Velis\Test\Mvc\Validators;

use Velis\Mvc\Validators\FormValidator;
use Velis\Mvc\Validators\Rules\AllowedValues;
use Velis\Mvc\Validators\Rules\Callback;
use Velis\Mvc\Validators\Rules\Date;
use Velis\Mvc\Validators\Rules\Required;
use Velis\Mvc\Validators\Rules\Type;
use PHPUnit\Framework\TestCase;

class FormValidatorTest extends TestCase
{
    public function testValidate()
    {
        $data = [
            'field' => 'Ala ma kota',
            'timestamp' => '2012-10-04T10:10:34+00:00'
        ];
        $validator = new class () extends FormValidator {
            protected function rules(): array
            {
                return [
                    'field' => [
                        new Required(),
                        new Type(Type::STRING),
                        new AllowedValues(['Ala ma kota']),
                        new Callback(fn ($data) => strlen($data['field']) == 11)
                    ],
                    'timestamp' => [
                        new Date('Y-m-d\TH:i:sP')
                    ]
                ];
            }
        };
        $validator->validate($data);
        $this->assertFalse($validator->hasErrors());
    }

    public function testGetErrors()
    {
        $data = [
            'field' => 10
        ];
        $validator = new class () extends FormValidator {
            protected function rules(): array
            {
                return [
                    'field' => [
                        new Type(Type::STRING), // -> fail
                        new AllowedValues(['Ala ma kota']), // -> fail
                        new Callback(fn ($data) => strlen($data['field']) == 11) // -> fail
                    ],
                    'field2' => [
                        new Required(), // -> fail
                        new Type(Type::INT)
                    ]
                ];
            }
        };
        $validator->validate($data);
        $this->assertCount(4, $validator->getErrors());
    }

    public function testCustomMessages()
    {
        $customMsg1 = 'Please provide a field';
        $customMsg2 = 'The field2 should be provided in order to save the page';

        $validator = new class ($customMsg1, $customMsg2) extends FormValidator {
            private $customMsg1;
            private $customMsg2;

            public function __construct($customMsg1, $customMsg2)
            {
                $this->customMsg1 = $customMsg1;
                $this->customMsg2 = $customMsg2;
            }

            protected function rules(): array
            {
                return [
                    'field' => [new Required()],
                    'field2' => [new Required()]
                ];
            }

            protected function messages(): array
            {
                return [
                    'field' => $this->customMsg1, // Custom message for any error
                    'field2' => [
                        'required' => $this->customMsg2 // Custom message for a required rule only
                    ]
                ];
            }
        };
        $validator->validate([]);
        $this->assertContains($customMsg1, $validator->getErrors());
        $this->assertContains($customMsg2, $validator->getErrors());
    }
}
