<?php

namespace Seka\Vzdelavanie\Http\Controllers\Backend\Kniznica;

use Exception;
use Illuminate\Support\Facades\Log;
use Seka\Vzdelavanie\Dtos\Kniznica\UcebnicaDTO;
use Seka\Vzdelavanie\Http\Controllers\Controller;
use Seka\Vzdelavanie\Services\SekciaServiceInterface;
use Seka\Vzdelavanie\Services\UcebnicaServiceInterface;
use Seka\Vzdelavanie\Services\KategoriaServiceInterface;
use Seka\Vzdelavanie\Http\Requests\UcebnicaStoreRequest;
use Seka\Vzdelavanie\Http\Requests\UcebnicaUpdateRequest;
use Seka\Vzdelavanie\Events\Kniznica\Backend\UcebnyMaterialCreated;
use Seka\Vzdelavanie\Events\Kniznica\Backend\UcebnyMaterialUpdated;
use Seka\Vzdelavanie\Events\Kniznica\Backend\UcebnyMaterialDeleted;
use Seka\Vzdelavanie\Repositories\Exceptions\ModelNotFoundException;

/**
 * Class UcebnicaController
 * @package Seka\Vzdelavanie\Http\Controllers\Backend\Kniznica
 */
final class UcebnicaController extends Controller
{
    /**
     * @var \Seka\Vzdelavanie\Services\SekciaServiceInterface
     */
    protected $sekciaService;

    /**
     * @var \Seka\Vzdelavanie\Services\UcebnicaServiceInterface
     */
    protected $ucebnicaService;

    /**
     * @var \Seka\Vzdelavanie\Services\KategoriaServiceInterface
     */
    protected $kategoriaService;

    /**
     * pocet zaznamov v zozname ucebnych materialov zvolenej kategorie
     */
    private const POCET_ZAZNAMOV_NA_STRANU = 15;

    /**
     * UcebnicaController constructor.
     * @param \Seka\Vzdelavanie\Services\SekciaServiceInterface    $sekciaService
     * @param \Seka\Vzdelavanie\Services\UcebnicaServiceInterface  $ucebnicaService
     * @param \Seka\Vzdelavanie\Services\KategoriaServiceInterface $kategoriaService
     */
    public function __construct(
        SekciaServiceInterface $sekciaService,
        UcebnicaServiceInterface $ucebnicaService,
        KategoriaServiceInterface $kategoriaService
    )
    {
        $this->sekciaService = $sekciaService;
        $this->ucebnicaService = $ucebnicaService;
        $this->kategoriaService = $kategoriaService;
    }

    /**
     * @param int $vzdKnzncKategoriaId
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function index(int $vzdKnzncKategoriaId)
    {
        $kategoria = null;
        $kategorie = null;
        $ucebneMaterialy = null;

        try {
            $kategoria = $this->kategoriaService->vratKategoriuSUcebnymiMaterialmi($vzdKnzncKategoriaId);
            $ucebneMaterialy = $this->ucebnicaService->strankovanieUcebnychMaterialovKategorie(
                $vzdKnzncKategoriaId,
                request('page', 1),
                self::POCET_ZAZNAMOV_NA_STRANU
            );
            $kategorie = $this->kategoriaService->vratVsetky();
        } catch (ModelNotFoundException $e) {
            flash()->error('Kategória učebného materiálu neexistuje.')->important();
        } catch (Exception $e) {
            Log::error($e->getMessage(), $e->getTrace());

            flash()->error($e->getMessage())->important();
        } finally {
            return view('Vzdelavanie::partials.kniznica.kategorie.zoznam_ucebnych_materialov')
                ->withKategoria($kategoria)
                ->withKategorie($kategorie)
                ->withUcebneMaterialy($ucebneMaterialy);
        }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @param int $vzdKnzncKategoriaId
     *
     * @return \Illuminate\Http\Response
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function create(int $vzdKnzncKategoriaId)
    {
        $kategorie = null;

        try {
            $kategorie = $this->kategoriaService->vratVsetky();
            $kategoria = $this->kategoriaService->vratKategoriuSUcebnymiMaterialmi($vzdKnzncKategoriaId);
            $actionRoute = route('vzdelavanie.sprava.kniznica.kategoria.ucebnice.store', $kategoria);
        } catch (Exception $e) {
            Log::error($e->getMessage(), $e->getTrace());

            flash()->error($e->getMessage())->important();
        } finally {
            return view('Vzdelavanie::pages.sprava.kniznica.ucebne_materialy.novy')
                ->withActionRoute($actionRoute)
                ->withKategoria($kategoria)
                ->withKategorie($kategorie);
        }
    }

    /**
     * @param \Seka\Vzdelavanie\Http\Requests\UcebnicaStoreRequest $request
     * @param int                                                  $vzdKnzncKategoriaId
     *
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function store(UcebnicaStoreRequest $request, int $vzdKnzncKategoriaId)
    {
        try {
            $kategoria = $this->kategoriaService->vratKategoriuSUcebnymiMaterialmi($vzdKnzncKategoriaId);
            $ucebnyMaterial = $this->ucebnicaService->vytvorit(
                $request->all(['nazov', 'kategoria', 'autor', 'popis', 'stav', 'obrazok'])
            );

            flash()->success('Učebný materiál bol vytvorený.')->important();

            event(new UcebnyMaterialCreated(UcebnicaDTO::fromModel($ucebnyMaterial)));
        } catch (Exception $e) {
            Log::error($e->getMessage(), $e->getTrace());

            flash()->error($e->getMessage())->important();

            return back()->withInput($request->all());
        }

        return redirect(route('vzdelavanie.sprava.kniznica.kategoria.ucebnice.edit', [$kategoria, $ucebnyMaterial]));
    }

    /**
     * @param int $vzdKnzncKategoriaId
     * @param int $vzdKnzncUcbnMtrlId
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function edit(int $vzdKnzncKategoriaId, int $vzdKnzncUcbnMtrlId)
    {
        $kategorie = null;
        $ucebnica = null;
        $sekcie = null;

        try {
            $kategoria = $this->kategoriaService->vratKategoriuSUcebnymiMaterialmi($vzdKnzncKategoriaId);
            $kategorie = $this->kategoriaService->vratVsetky();
            $ucebnica = $this->ucebnicaService->vratUcebnyText($vzdKnzncUcbnMtrlId);
            $sekcie = $this->sekciaService->vratZoznamSekciiUcebnehoTextu($vzdKnzncUcbnMtrlId, false);
            $actionRoute = route('vzdelavanie.sprava.kniznica.kategoria.ucebnice.update', [$kategoria, $ucebnica]);
        } catch (Exception $e) {
            Log::error($e->getMessage(), $e->getTrace());

            flash()->error($e->getMessage())->important();
        } finally {
            return view('Vzdelavanie::pages.sprava.kniznica.ucebne_materialy.upravit')
                ->withActionRoute($actionRoute)
                ->withKategoria($kategoria)
                ->withKategorie($kategorie)
                ->withUcebnica($ucebnica)
                ->withSekcie($sekcie);
        }
    }

    /**
     * Update the specified resource in storage.
     *
     * @param \Seka\Vzdelavanie\Http\Requests\UcebnicaUpdateRequest $request
     * @param int                                                   $vzdKnzncKategoriaId
     * @param int                                                   $vzdKnzncUcbnMtrlId
     *
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Routing\Redirector
     */
    public function update(UcebnicaUpdateRequest $request, int $vzdKnzncKategoriaId, int $vzdKnzncUcbnMtrlId)
    {
        try {
            $this->ucebnicaService->upravit(
                $vzdKnzncUcbnMtrlId,
                $request->all(['nazov', 'kategoria', 'autor', 'popis', 'stav', 'obrazok'])
            );

            $ucebnyMaterial = $this->ucebnicaService->vratUcebnyText($vzdKnzncUcbnMtrlId);
            $kategoria = $this->kategoriaService->vratKategoriuSUcebnymiMaterialmi($vzdKnzncKategoriaId);

            flash()->success('Učebný materiál bol upravený.')->important();

            event(new UcebnyMaterialUpdated(UcebnicaDTO::fromModel($ucebnyMaterial)));
        } catch (Exception $e) {
            Log::error($e->getMessage(), $e->getTrace());

            flash()->error($e->getMessage())->important();

            return back()->withInput($request->all());
        }

        return redirect(route('vzdelavanie.sprava.kniznica.kategoria.ucebnice.edit', [$kategoria, $ucebnyMaterial]));
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param int $vzdKnzncKategoriaId
     * @param int $vzdKnzncUcbnMtrlId
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy(int $vzdKnzncKategoriaId, int $vzdKnzncUcbnMtrlId)
    {
        try {
            /** @var \Seka\Vzdelavanie\Models\Kniznica\Ucebnica $ucebnyMaterial */
            $ucebnyMaterial = $this->ucebnicaService->vratUcebnyText($vzdKnzncUcbnMtrlId);
            $kategoria = $this->kategoriaService->vratKategoriuSUcebnymiMaterialmi($vzdKnzncKategoriaId);
            $this->ucebnicaService->odstranit($vzdKnzncUcbnMtrlId);

            flash()->success('Učebný materiál bol odstránený.')->important();

            // event je async, pri jeho spracovani uz nebude v DB existovat vymazany zaznam, preto DTO
            event(new UcebnyMaterialDeleted(UcebnicaDTO::fromModel($ucebnyMaterial)));
        } catch (Exception $e) {
            Log::error($e->getMessage(), $e->getTrace());

            flash()->error($e->getMessage())->important();

            return back();
        }

        return redirect()->route('vzdelavanie.sprava.kniznica.kategoria.ucebnice.index', $kategoria);
    }
}
