<?php

namespace Tests\Feature;

use App\Models\Report;
use App\Rules\SettingTypeRule;
use App\Rules\StringContainsStringRule;
use App\Rules\ValidVehicleRegistrationNumber;
use App\Rules\VehicleExistsByIdentifier;
use App\Schedule\BiWeekly;
use App\Schedule\Daily;
use App\Schedule\Monthly;
use App\Schedule\Weekly;
use Carbon\Carbon;
use Database\Seeders\Global\CountrySeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Mtc\MercuryDataModels\Vehicle;
use Tests\TestCase;
use Tests\UserForTenant;

class RuleTest extends TestCase
{
    use RefreshDatabase;
    use UserForTenant;

    protected $tenancy = true;

    public function testSettingTypeRule()
    {
        $tests = [
            'boolean' => true,
            'image' => true,
            'secret' => true,
            'string' => true,
            'int' => true,
            'verify' => true,
            'foo' => false,
            'lorem' => false,
            'test' => false,
        ];
        foreach ($tests as $type => $value) {
            $this->assertEquals($value, (new SettingTypeRule())->passes('field', $type));
        }

        $this->assertStringContainsString('valid setting type', (new SettingTypeRule())->message());
    }

    public function testStringContainsString()
    {
        $this->assertTrue((new StringContainsStringRule('foo'))->passes('field', 'foo baz bar'));
        $this->assertTrue((new StringContainsStringRule('baz'))->passes('field', 'foo baz bar'));
        $this->assertFalse((new StringContainsStringRule('hello'))->passes('field', 'foo baz bar'));
        $this->assertFalse((new StringContainsStringRule('lorem'))->passes('field', 'foo baz bar'));
        $this->assertStringContainsString('must contain', (new StringContainsStringRule('foo'))->message());
        $this->assertStringContainsString('foo', (new StringContainsStringRule('foo'))->message());
    }

    public function testValidVehicleRegistrationNumber()
    {
        $this->seed(CountrySeeder::class);
        $this->assertTrue((new ValidVehicleRegistrationNumber(true))->passes('reg', 'HELLO WORLD'));
        $this->assertFalse((new ValidVehicleRegistrationNumber(false))->passes('reg', 'HELLO WORLD'));

        $this->assertTrue((new ValidVehicleRegistrationNumber(false))->passes('reg', 'AB10DEL'));
        $this->assertTrue((new ValidVehicleRegistrationNumber(false))->passes('reg', 'ZZ44CES'));
        $this->assertTrue((new ValidVehicleRegistrationNumber(false))->passes('reg', 'YY91XYX'));
        $this->assertFalse((new ValidVehicleRegistrationNumber(false))->passes('reg', '1A2B'));
        $this->assertFalse((new ValidVehicleRegistrationNumber(false))->passes('reg', '1AA3VVV'));
        $this->assertFalse((new ValidVehicleRegistrationNumber(false))->passes('reg', '1AAVV3'));
        $this->assertStringContainsString('is not valid', (new ValidVehicleRegistrationNumber())->message());
        $this->assertTrue((new ValidVehicleRegistrationNumber(false, true))->passes('registration_number', null));
        $this->assertTrue((new ValidVehicleRegistrationNumber(false, true))->passes('registration_number', ''));
        $this->assertTrue((new ValidVehicleRegistrationNumber(false, true))->passes('registration_number', 'AB59 DAC'));
        $this->assertFalse(
            (new ValidVehicleRegistrationNumber(false, true))->passes('registration_number', 'INVALID123')
        );
        $this->assertTrue(
            (new ValidVehicleRegistrationNumber(true, true))->passes('registration_number', 'HELLO WORLD')
        );
    }

    public function testVehicleExistsByIdentifier()
    {
        Vehicle::factory()->create([
            'registration_number' => 'AB10DEL',
            'vin' => 'ABC123',
        ]);

        $this->assertTrue((new VehicleExistsByIdentifier())->passes('slug', 'AB10 DEL'));
        $this->assertTrue((new VehicleExistsByIdentifier())->passes('slug', 'AB10DEL'));
        $this->assertTrue((new VehicleExistsByIdentifier())->passes('slug', 'ABC123'));
        $this->assertFalse((new VehicleExistsByIdentifier())->passes('slug', 'lorem-ipsum'));
        $this->assertStringContainsString('not found', (new VehicleExistsByIdentifier())->message());
    }
}
