<?php

declare(strict_types=1);

namespace Seka\Vzdelavanie\Services\Pouzivatel\Testovanie;

use Exception;
use Illuminate\Support\Facades\Auth;
use Seka\Vzdelavanie\Models\Pouzivatel\Testovanie\Test;
use Seka\Vzdelavanie\Models\Pouzivatel\Testovanie\Otazka;
use Seka\Vzdelavanie\Models\Pouzivatel\Testovanie\Odpoved;
use Seka\Vzdelavanie\Services\Pouzivatel\Testovanie\Exceptions\TestUzBolVyhodnotenyException;

/**
 * Class UlozenieOdpovediPouzivatela
 *
 * @package Seka\Vzdelavanie\Services\Pouzivatel\Testovanie
 */
final class UlozenieOdpovediPouzivatela
{
    /**
     * @param \Seka\Vzdelavanie\Models\Pouzivatel\Testovanie\Test $test
     * @param array                                               $data
     *
     * @throws \Seka\Vzdelavanie\Services\Pouzivatel\Testovanie\Exceptions\TestUzBolVyhodnotenyException
     * @throws \Throwable
     */
    public static function ulozit(Test $test, array $data)
    {
        if ($test->jeVyhodnoteny()) {
            throw new TestUzBolVyhodnotenyException();
        }

        if ($test->getAttribute('id') !== $data['id']) {
            // nie je totozny test
            // throw new
        }

        $otazky = collect($data['otazky']);

        $otazky->each(function (array $otazka) use ($test) {
            /** @var Otazka $_otazka */
            $_otazka = Otazka::query()
                ->with('test')
                ->findOrFail($otazka['id']);

            // ak otazka nepatri do ukladaneho testu pouzivatela
            if ($_otazka->test->pouzivatel_id !== Auth::id()) {
                throw new Exception('Otazka nepatri do testu pouzivatela...');
            }

            // ak otazka nepatri pod ukladany test pouzivatela
            if ($_otazka->test->id !== $test->id) {
                throw new Exception('Otazka nepatri pod ukladany test pouzivatela...');
            }

            $odpovede = collect($otazka['odpovede']);

            $odpovede->each(function (array $odpoved) use ($test, $_otazka) {
                $_odpoved = Odpoved::query()
                    ->with('otazka.test')
                    ->findOrFail($odpoved['id']);

                if ($_odpoved->otazka->id !== $odpoved['otazka_id']) {
                    throw new Exception('Odpoved nepatri pod pozadovanu otazku...');
                }

                if ($_odpoved->otazka->test->id !== $test->id) {
                    throw new Exception('Odpoved nepatri pod test...');
                }

                $_odpoved->setAttribute('zvolena', (bool) $odpoved['zvolena']);
                $_odpoved->saveOrFail();

                return $_odpoved->fresh();
            });
        });
    }
}
