<?php

namespace Tests\Unit\App\Models\Informacia;

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

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

    /** @test */
    public function it_can_create_an_informacia()
    {
        /** @var Pracovisko $pek */
        $pek = factory(Pracovisko::class)->create();
        /** @var Pouzivatel $pouzivatel */
        $pouzivatel = factory(Pouzivatel::class)->make();
        $pouzivatel->pracovisko()->associate($pek)->save();
        $pouzivatel = $pouzivatel->refresh();

        $informaciaData = [
            'vytvoril_id' => $pouzivatel->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()
    {
        /** @var Pracovisko $pek */
        $pek = factory(Pracovisko::class)->create();
        /** @var Pouzivatel $user */
        $pouzivatel = factory(Pouzivatel::class)->create();
        $pouzivatel->pracovisko()->associate($pek)->make();
        $informacia = factory(Informacia::class)->create(['vytvoril_id' => $pouzivatel->getKey()]);
        $pouzivatel = $pouzivatel->refresh();

        $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'];
        /** @var Pracovisko $pek */
        $pek = factory(Pracovisko::class)->create();
        /** @var Pouzivatel $user */
        $pouzivatel = factory(Pouzivatel::class)->make();
        $pouzivatel->pracovisko()->associate($pek)->save();
        $pouzivatel = $pouzivatel->refresh();
        $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()
    {
        /** @var Pracovisko $pek */
        $pek = factory(Pracovisko::class)->create();
        /** @var Pouzivatel $user */
        $pouzivatel = factory(Pouzivatel::class)->make();
        $pouzivatel->pracovisko()->associate($pek)->save();
        $pouzivatel = $pouzivatel->refresh();
        $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(),
            );
        }
    }
}
