<?php

declare(strict_types=1);

namespace Seka\Portal\Modul\Terminy\Actions;

use App\Models\Pouzivatel\Pouzivatel;
use App\Models\Pracovisko\Pracovisko;
use Seka\Portal\Modul\Terminy\Entities\Udalost\Udalost;
use Seka\Portal\Modul\Terminy\Exceptions\UdalostSaUzKonala;
use Seka\Portal\Modul\Terminy\Exceptions\UdalostUzPrebieha;
use Seka\Portal\Modul\Terminy\Entities\Registracia\Registracia;
use Seka\Portal\Modul\Terminy\Exceptions\UdalostNemaVolnuKapacitu;
use Seka\Portal\Modul\Terminy\Exceptions\NaUdalostNieJePovolenaRegistracia;
use Seka\Portal\Modul\Terminy\Exceptions\ExistujeRegistraciaPouzivatelaNaUdalost;

/**
 * Class CreateRegistration
 *
 * @package Seka\Portal\Modul\Terminy\Actions
 */
final class CreateRegistration
{
    /**
     * @param \Seka\Portal\Modul\Terminy\Entities\Udalost\Udalost         $udalost
     * @param \App\Models\Pouzivatel\Pouzivatel            $registroval
     * @param \App\Models\Pracovisko\Pracovisko            $pracovisko
     * @param \Seka\Portal\Modul\Terminy\Entities\Registracia\Registracia $registracia
     *
     * @throws \Seka\Portal\Modul\Terminy\Exceptions\ExistujeRegistraciaPouzivatelaNaUdalost
     * @throws \Seka\Portal\Modul\Terminy\Exceptions\NaUdalostNieJePovolenaRegistracia
     * @throws \Seka\Portal\Modul\Terminy\Exceptions\UdalostNemaVolnuKapacitu
     * @throws \Seka\Portal\Modul\Terminy\Exceptions\UdalostSaUzKonala
     * @throws \Seka\Portal\Modul\Terminy\Exceptions\UdalostUzPrebieha
     * @throws \Throwable
     */
    public static function execute(Udalost $udalost, Pouzivatel $registroval, Pracovisko $pracovisko, Registracia $registracia): void
    {
        if (false === $udalost->jePovolenaRegistracia()) {
            throw new NaUdalostNieJePovolenaRegistracia();
        }

        if ($udalost->skoncila) {
            throw new UdalostSaUzKonala();
        }

        if (true === $udalost->prebieha) {
            throw new UdalostUzPrebieha();
        }

        if (false === $udalost->ma_volnu_kapacitu) {
            throw new UdalostNemaVolnuKapacitu();
        }

        // ak nebol zvoleny existujuci pouzivatel a registracie na udalost maju zvoleneho existujuceho pouzivatela
        if (!is_null($registracia->pouzivatel_id) && $udalost->registracie()->has('pouzivatel')) {
            if (false === is_null($udalost->registracie()->wherePouzivatelId($registracia->pouzivatel_id)->first())) {
                throw new ExistujeRegistraciaPouzivatelaNaUdalost();
            }
        }

        $registracia->udalost()->associate($udalost);
        $registracia->vytvoril()->associate($registroval);
        $registracia->pracovisko()->associate($pracovisko);

        $registracia->saveOrFail();
    }
}
