<?php

namespace Tests\Unit\App\Models\Informacia;

use App\Models\Informacia\Enums\StavInformacieEnum;
use App\Models\Informacia\Informacia;
use App\Models\Pouzivatel\Pouzivatel;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

/**
 *
 */
class InformaciaTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function it_can_create_an_informacia()
    {
        $informaciaData = [
            'vytvoril_id' => factory(Pouzivatel::class)->create(['pracovisko_id' => 1])->getKey(),
            'titulok' => 'Testovací titulok',
            'obsah' => 'Toto je testovací obsah.',
            'stav' => collect(StavInformacieEnum::cases())->random(1)->first(),
            'zverejnit_pre_pouzivatelov_podla_role' => ['admin', 'editor'],
            'planovany_cas_zverejnenia' => now()->addDays(rand(1, 30)),
            'odoslat_email_pouzivatelom' =>boolval(rand(0, 1)),
            'odoslat_push_notifikacie_pouzivatelom' => boolval(rand(0, 1)),
            'odoslane' => rand(0, 1) ? now()->addDays(rand(30, 35)) : null,
            'odporucane' =>boolval(rand(0, 1)),
        ];

        $informacia = Informacia::create($informaciaData);

        $this->assertNotNull($informacia->id);
        $this->assertEquals($informaciaData['vytvoril_id'], $informacia->vytvoril_id);
        $this->assertEquals($informaciaData['titulok'], $informacia->titulok);
        $this->assertEquals($informaciaData['obsah'], $informacia->obsah);
        $this->assertEquals($informaciaData['stav'], $informacia->stav);
        $this->assertEquals($informaciaData['zverejnit_pre_pouzivatelov_podla_role'], $informacia->zverejnit_pre_pouzivatelov_podla_role);
        $this->assertEquals($informaciaData['planovany_cas_zverejnenia']->toDateTimeString(), $informacia->planovany_cas_zverejnenia->toDateTimeString());
        $this->assertEquals($informaciaData['odoslat_email_pouzivatelom'], $informacia->odoslat_email_pouzivatelom);
        $this->assertEquals($informaciaData['odoslat_push_notifikacie_pouzivatelom'], $informacia->odoslat_push_notifikacie_pouzivatelom);
        $this->assertEquals($informaciaData['odporucane'], $informacia->odporucane);
        $this->assertIsBool($informacia->je_odoslana);

        if (is_null($informaciaData['odoslane'])) {
            $this->assertNull( $informaciaData['odoslane']);
        } else {
            $this->assertEquals($informaciaData['odoslane']->toDateTimeString(), $informacia->odoslane->toDateTimeString());
        }
    }

    /** @test */
    public function it_belongs_to_a_pouzivatel()
    {
        $pouzivatel = factory(Pouzivatel::class)->create(['pracovisko_id' => 1]);
        $informacia = factory(Informacia::class)->create(['vytvoril_id' => $pouzivatel->getKey()]);

        $this->assertInstanceOf(Pouzivatel::class, $informacia->vytvoril);
        $this->assertEquals($pouzivatel->id, $informacia->vytvoril->id);
    }

    /** @test */
    public function it_stores_zverejnit_pre_pouzivatelov_podla_role_as_json()
    {
        $roles = ['superadmin', 'moderator'];
        $pouzivatel = factory(Pouzivatel::class)->create(['pracovisko_id' => 1]);
        $informacia = factory(Informacia::class)->create(['vytvoril_id' => $pouzivatel->getKey(), 'zverejnit_pre_pouzivatelov_podla_role' => $roles]);

        $this->assertEquals($roles, $informacia->zverejnit_pre_pouzivatelov_podla_role);
        $this->assertDatabaseHas('informacie', [
            'id' => $informacia->id,
            'zverejnit_pre_pouzivatelov_podla_role' => json_encode($roles),
        ]);
    }

    /** @test */
    public function it_can_retrieve_all_attributes()
    {
        $pouzivatel = factory(Pouzivatel::class)->create(['pracovisko_id' => 1]);
        $informaciaData = [
            'vytvoril_id' => $pouzivatel->id,
            'titulok' => 'Ďalší testovací titulok',
            'obsah' => 'Ďalší testovací obsah.',
            'stav' => StavInformacieEnum::ZVEREJNENA(),
            'zverejnit_pre_pouzivatelov_podla_role' => ['guest'],
            'planovany_cas_zverejnenia' => now()->addWeek(),
            'odoslat_email_pouzivatelom' =>boolval(rand(0, 1)),
            'odoslat_push_notifikacie_pouzivatelom' => boolval(rand(0, 1)),
            'odoslane' => rand(0, 1) ? now()->addDays(rand(30, 35)) : null,
            'odporucane' =>boolval(rand(0, 1)),
        ];
        $informacia = factory(Informacia::class)->create($informaciaData);

        $retrievedInformacia = Informacia::query()->find($informacia->id);

        $this->assertEquals($informaciaData['vytvoril_id'], $retrievedInformacia->vytvoril_id);
        $this->assertEquals($informaciaData['titulok'], $retrievedInformacia->titulok);
        $this->assertEquals($informaciaData['obsah'], $retrievedInformacia->obsah);
        $this->assertEquals($informaciaData['stav'], $retrievedInformacia->stav);
        $this->assertEquals($informaciaData['zverejnit_pre_pouzivatelov_podla_role'], $retrievedInformacia->zverejnit_pre_pouzivatelov_podla_role);
        $this->assertEquals($informaciaData['planovany_cas_zverejnenia']->toDateTimeString(), $retrievedInformacia->planovany_cas_zverejnenia->toDateTimeString());
        $this->assertEquals($informaciaData['odoslat_email_pouzivatelom'], $informacia->odoslat_email_pouzivatelom);
        $this->assertEquals($informaciaData['odoslat_push_notifikacie_pouzivatelom'], $informacia->odoslat_push_notifikacie_pouzivatelom);
        $this->assertEquals($informaciaData['odporucane'], $informacia->odporucane);
        $this->assertIsBool($informacia->je_odoslana);

        if (is_null($informaciaData['odoslane'])) {
            $this->assertNull( $informaciaData['odoslane']);
        } else {
            $this->assertEquals($informaciaData['odoslane']->toDateTimeString(), $informacia->odoslane->toDateTimeString());
        }
    }
}
