<?php

namespace App\Http\Livewire\Components\Informacia\Components;

use App\Models\Hodnotenie\HodnotenieEnum;
use App\Models\Hodnotenie\HodnotenieModel;
use Exception;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\View\View;
use Livewire\Component;

/**
 * Class HodnotiaceTlacidla
 *
 * @package App\Http\Livewire\Components\Informacia\Components
 */
final class HodnotiaceTlacidla extends Component
{
    use AuthorizesRequests;

    /**
     * @var bool
     */
    public bool $povolitZaporneHodnotenie;
    /**
     * @var Model
     */
    public $hodnotenyZaznam;
    /**
     * @var int
     */
    public int $pocetKladnychHodnoteni = 0;
    /**
     * @var int
     */
    public int $pocetZapornychHodnoteni = 0;
    /**
     * @var bool
     */
    public bool $hodnoteniePouzivatelaKladne = false;
    /**
     * @var bool
     */
    public bool $hodnoteniePouzivatelaZaporne = false;

    /**
     * @var string[]
     */
    protected $listeners = [
        'hodnotenieBoloZmenene' => 'nacitajAktualneHodnotenia',
    ];

    /**
     * @param bool|null $povolitZaporneHodnotenie
     * @param Model $hodnotenyZaznam
     * @return void
     */
    public function mount(
        ?bool $povolitZaporneHodnotenie,
        Model $hodnotenyZaznam
    ): void {
        $this->povolitZaporneHodnotenie = $povolitZaporneHodnotenie ?? false;
        $this->hodnotenyZaznam = $hodnotenyZaznam;

        $this->nacitajAktualneHodnotenia();
    }

    /**
     * @return void
     */
    public function nacitajAktualneHodnotenia(): void
    {
        $this->pocetKladnychHodnoteni = $this->hodnotenyZaznam->pocetHodnoteniPodlaDruhu(HodnotenieEnum::kladne());
        $this->pocetZapornychHodnoteni = $this->hodnotenyZaznam->pocetHodnoteniPodlaDruhu(HodnotenieEnum::zaporne());
        $hodnoteniePouzivatela = $this->hodnotenyZaznam->hodnoteniePouzivatela(auth()->user()) ?? null;
        $this->hodnoteniePouzivatelaKladne = $hodnoteniePouzivatela && HodnotenieEnum::kladne()->equals(
                $hodnoteniePouzivatela,
            );
        $this->hodnoteniePouzivatelaZaporne = $hodnoteniePouzivatela && HodnotenieEnum::zaporne()->equals(
                $hodnoteniePouzivatela,
            );

        $this->emit('aktualizovanyPocetHodnoteni', $this->hodnotenyZaznam->pocetHodnoteni());
    }

    /**
     * @return Application|Factory|View
     */
    public function render()
    {
        return view('livewire.components.hodnotenie.hodnotiace-tlacidla');
    }

    /**
     * @param string $hodnotenieValue
     * @return void
     * @throws Exception
     */
    public function zmenitHodnotenie(string $hodnotenieValue): void
    {
        $hodnotenie = new HodnotenieModel();
        $hodnotenie->hodnotil()->associate(auth()->user());
        $hodnotenie->hodnotitelne()->associate($this->hodnotenyZaznam);

        try {
            $hodnotenie = HodnotenieModel::whereHasMorph(
                'hodnotitelne',
                get_class($this->hodnotenyZaznam),
                function ($query) {
                    $query
                        ->whereHodnotilId(auth()->user()->id)
                        ->whereHodnotitelneId($this->hodnotenyZaznam->id);
                },
            )->firstOrFail();
        } finally {
            if ($hodnotenie->exists && $hodnotenie->hodnotenie->equals(HodnotenieEnum::from($hodnotenieValue))) {
                $hodnotenie->delete();
            } else {
                $hodnotenie->hodnotenie = HodnotenieEnum::from($hodnotenieValue);
                $hodnotenie->save();
            }

            $this->emitSelf('hodnotenieBoloZmenene');

            return;
        }
    }
}
