<?php

declare(strict_types=1);

namespace Seka\Portal\Modul\Terminy\Entities\Udalost;

use Seka\Portal\Modul\Terminy\Events\Udalost\NezverejnenaUdalostBolaAktualizovana;
use Seka\Portal\Modul\Terminy\Events\Udalost\NezverejnenaUdalostBolaZverejnena;
use Seka\Portal\Modul\Terminy\Events\Udalost\NovaNezverejnenaUdalost;
use Seka\Portal\Modul\Terminy\Events\Udalost\NovaZverejnenaUdalost;
use Seka\Portal\Modul\Terminy\Events\Udalost\ZverejnenaUdalostBolaAktualizovana;
use Seka\Portal\Modul\Terminy\Events\Udalost\ZverejnenaUdalostBolaNezverejnena;
use Seka\Portal\Modul\Terminy\Events\Udalost\ZverejnenaUdalostBolaObnovena;
use Seka\Portal\Modul\Terminy\Events\Udalost\ZverejnenaUdalostBolaZrusena;

/**
 * Class UdalostObserver
 *
 * @package Seka\Portal\Modul\Terminy\Entities\Udalost
 */
class UdalostObserver
{
    /**
     * Handle "saved" event.
     *
     * @param \Seka\Portal\Modul\Terminy\Entities\Udalost\Udalost $udalost
     *
     * @return void
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function saved(Udalost $udalost): void
    {
        // entita udalosti este neexistuje, jedna sa o akciu vytvorenia novej entity udalosti
        // vyvola sa aplikacna udalost
        if ($udalost->wasRecentlyCreated) {
            if ($udalost->jeZverejnena()) {
                event(new NovaZverejnenaUdalost($udalost));
            } else {
                event(new NovaNezverejnenaUdalost($udalost));
            }
            return;
        }

        // entita udalosti uz existuje, jedna sa o jej upravu
        $udalostPovodna = (clone $udalost)->fill($udalost->getOriginal());

        // ak povodna entita udalosti nebola a ani upravena entita udalosti nie je zverejnena,
        // vyvola sa aplikacna udalost
        if ($udalostPovodna->nieJeZverejnena() && $udalost->nieJeZverejnena()) {
            event(new NezverejnenaUdalostBolaAktualizovana($udalostPovodna, $udalost));
            return;
        }

        // zmena stavu entity udalosti z nezverejnenej na zverejnenu
        // vyvola sa aplikacna udalost
        if ($udalostPovodna->nieJeZverejnena() && $udalost->jeZverejnena()) {
            event(new NezverejnenaUdalostBolaZverejnena($udalostPovodna, $udalost));
            return;
        }

        // zmena stavu entity udalosti zo zverejnenej na nezverejnenu
        // vyvola sa aplikacna udalost
        if ($udalostPovodna->jeZverejnena() && $udalost->nieJeZverejnena()) {
            event(new ZverejnenaUdalostBolaNezverejnena($udalostPovodna, $udalost));
            return;
        }

        // ak nedoslo k zmene stavu zverejnenia entity udalosti a entita udalosti je zverejnena
        // tak na zaklade splnenia podmienok vyvola aplikacnu udalost
        if ($udalostPovodna->jeZverejnena() && $udalost->jeZverejnena()) {
            if (
                (mb_strtoupper($udalostPovodna->nazov) != mb_strtoupper($udalost->nazov))
                || $udalostPovodna->datum_od->notEqualTo($udalost->datum_od)
                || $udalostPovodna->datum_do->notEqualTo($udalost->datum_do)
                || !$udalostPovodna->druh->equals($udalost->druh)
                || ($udalostPovodna->jePovolenaRegistracia() != $udalost->jePovolenaRegistracia())
                || ($udalostPovodna->kapacita != $udalost->kapacita)
                || ($udalostPovodna->miestoKonania->getKey() != $udalost->miestoKonania->getKey())
            ) {
                event(new ZverejnenaUdalostBolaAktualizovana($udalostPovodna, $udalost));
            }
        }
    }

    /**
     * Handle "forceDeleted" event.
     *
     * @param \Seka\Portal\Modul\Terminy\Entities\Udalost\Udalost $udalost
     *
     * @return void
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function forceDeleted(Udalost $udalost): void
    {
        $this->deleted($udalost);
    }

    /**
     * Handle "deleted" event.
     *
     * @param \Seka\Portal\Modul\Terminy\Entities\Udalost\Udalost $udalost
     *
     * @return void
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function deleted(Udalost $udalost): void
    {
        if ($udalost->jeZverejnena()) {
            event(new ZverejnenaUdalostBolaZrusena($udalost));
        }
    }

    /**
     * @param \Seka\Portal\Modul\Terminy\Entities\Udalost\Udalost $udalost
     *
     * @return void
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function restored(Udalost $udalost): void
    {
        if ($udalost->jeZverejnena()) {
            event(new ZverejnenaUdalostBolaObnovena($udalost));
        }
    }
}
