<?php

declare(strict_types=1);

namespace Seka\Portal\Modul\Terminy\Http\Controllers\Backend\MoznostiUdalosti\Livewire\Components;

use Exception;
use Illuminate\Contracts\View\View;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Livewire\Component;
use Seka\Portal\Modul\Terminy\Entities\MoznostiUdalosti\MoznostUdalosti;
use Seka\Portal\Modul\Terminy\Entities\MoznostiUdalosti\StavMoznostiUdalostiEnum;

/**
 * Class Form
 *
 * @package Seka\Portal\Modul\Terminy\Http\Controllers\Backend\MoznostiUdalosti\Livewire\Components
 */
final class Form extends Component
{
    use AuthorizesRequests;

    /**
     * @var \Seka\Portal\Modul\Terminy\Entities\MoznostiUdalosti\MoznostUdalosti
     */
    public MoznostUdalosti $moznostUdalosti;

    /**
     * @param \Seka\Portal\Modul\Terminy\Entities\MiestoKonania\MiestoKonania $miesto
     */
    public function mount(MoznostUdalosti $moznostUdalosti): void
    {
        $this->moznostUdalosti = $moznostUdalosti;
    }

    /**
     * @return \Illuminate\Contracts\View\View
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function render(): View
    {
        return view('Terminy::pages.moznostiUdalosti.backend.livewire.components.form');
    }

    /**
     * @throws \Illuminate\Validation\ValidationException
     * @throws \Throwable
     */
    public function save()
    {
        $this->validate();

        try {
            $this->authorize('terminy');

            $existBeforeSave = $this->moznostUdalosti->exists ?? false;

            DB::beginTransaction();

            $this->moznostUdalosti->vytvoril()->associate(auth()->user());
            $this->moznostUdalosti->save();
            $this->moznostUdalosti->refresh();

            DB::commit();

            if (false == $existBeforeSave) {
                $message = 'Nová možnosť udalosti bola vytvorená';
            } else {
                $message = 'Možnosť udalosti bola aktualizovaná';
            }

            flash()->overlay($message, 'Hlásenie')->success();

            return redirect()->route('modul.terminy.backend.moznostiUdalosti.index');
        } catch (Exception $e) {
            DB::rollBack();

            Log::error($e->getMessage(), $e->getTrace());

            flash()->overlay('Možnosť udalosti nebola úspešne uložená.')->error();
        }
    }

    /**
     * Obnovit zneplatnenú možnosť udalosti
     *
     * @return void
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function restore(): void
    {
        try {
            $this->authorize('terminy');

            if (!$this->moznostUdalosti->trashed()) {
                return;
            }

            DB::beginTransaction();

            $this->moznostUdalosti->restore();

            DB::commit();

            $this->moznostUdalosti->refresh();

            flash()->overlay('Možnosť udalosti bola úspešne obnovená')->success();
        } catch (Exception $e) {
            DB::rollBack();

            Log::error($e->getMessage(), $e->getTrace());

            flash()->overlay('Možnosť udalosti sa nepodarilo obnoviť.')->error();
        }
    }

    /**
     * Zneplatnit možnosť udalosti
     *
     * @return \Illuminate\Http\RedirectResponse
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function trash()
    {
        try {
            $this->authorize('terminy');

            DB::beginTransaction();

            // soft delete
            $this->moznostUdalosti->delete();

            DB::commit();

            flash()->overlay('Možnosť udalosti bola úspešne zneplatnená')->success();

            return redirect()->route('modul.terminy.backend.moznostiUdalosti.index');
        } catch (Exception $e) {
            DB::rollBack();

            Log::error($e->getMessage(), $e->getTrace());

            flash()->overlay('Možnosť udalosti nebola zneplatnená.')->error();
        }
    }

    /**
     * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function cancel()
    {
        return redirect()->route('modul.terminy.backend.moznostiUdalosti.index');
    }

    /**
     * Ak je moznost udalosti zneplatnena, tak formular je v rezime zneplatnenia
     *
     * @return bool
     */
    public function trashMode(): bool
    {
        return $this->moznostUdalosti->trashed();
    }

    /**
     * Ak moznost udalosti existuje, tak formular je v rezime uprava
     *
     * @return bool
     */
    public function editMode(): bool
    {
        return $this->moznostUdalosti->exists;
    }

    /**
     * @return string[]
     */
    public function rules(): array
    {
        return [
            'moznostUdalosti.nazov' => 'required',
            'moznostUdalosti.stav' => [
                'required',
                Rule::in(
                    collect(StavMoznostiUdalostiEnum::cases())->map(
                        fn(StavMoznostiUdalostiEnum $case) => $case->name,
                    )->toArray(),
                ),
            ],
        ];
    }

    /**
     * @return string[]
     */
    public function messages(): array
    {
        return [
            'moznostUdalosti.nazov.required' => 'Názov možnosti udalosti je vyžadovaný',
            'moznostUdalosti.stav.required' => 'Stav možnosti udalosti je vyžadovaný',
            'moznostUdalosti.stav.in' => 'Neznámi stav možnosti udalosti',
        ];
    }
}
