<?php

namespace App\Http\Livewire\Frontend\Pouzivatel\Notifications;

use Livewire\Component;
use Livewire\WithPagination;
use App\Enums\UpozornenieStavEnum;
use App\Models\Pouzivatel\Pouzivatel;

/**
 * Class Zoznam
 *
 * @package App\Http\Livewire\Frontend\Pouzivatel\Notifications
 */
final class Zoznam extends Component
{
    use WithPagination;

    /**
     *
     */
    private const PER_PAGE = 15;

    /**
     * @var string
     */
    protected string $paginationTheme = 'bootstrap';

    /**
     * @var int
     */
    public int $sort = 0;

    /**
     * @var string
     */
    public string $status;

    /**
     * @var bool
     */
    public bool $unreaded = false;

    /**
     * @var int
     */
    protected int $countAll = 0;

    /**
     * @var int
     */
    protected int $countRead = 0;

    /**
     * @var int
     */
    protected int $countNotRead = 0;

    /**
     * @var string[]
     */
    protected $listeners = [
        'filterByReadState',
    ];

    /**
     *
     */
    public function mount()
    {
        $this->pouzivatel = auth()->user();
        $this->status = UpozornenieStavEnum::NOTREAD();
    }

    /**
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View|mixed
     */
    public function render()
    {
        /** @var Pouzivatel $pouzivatel */
        $pouzivatel = auth()->user();
        $query = $pouzivatel->notifications();

        $this->countAll = $pouzivatel->notifications()->count();
        $this->countRead = $pouzivatel->readNotifications()->count();
        $this->countNotRead = $pouzivatel->unreadNotifications()->count();

        $this->unreaded = (bool) $this->countNotRead;

        if (UpozornenieStavEnum::make($this->status)->equals(UpozornenieStavEnum::NOTREAD())) {
            $query = $query->whereNull('read_at');
        }

        if (UpozornenieStavEnum::make($this->status)->equals(UpozornenieStavEnum::READ())) {
            $query = $query->whereNotNull('read_at');
        }

        $upozornenia = $query->orderBy('created_at', $this->sort ? 'asc' : 'desc')
            ->paginate(self::PER_PAGE);

        return view('livewire.frontend.pouzivatel.notifications.zoznam')
            ->withUpozornenia($upozornenia);
    }

    /**
     * Oznacit vsetky neprecitane upozornenia ako precitane
     *
     * @return void
     */
    public function notificationsReaded(): void
    {
        /** @var Pouzivatel $pouzivatel */
        $pouzivatel = auth()->user();
        $pouzivatel->unreadNotifications->markAsRead();

        // udalost pre posluchacov inych aktivnych komponentov na aktualizaciu ich stavu
        $this->emit('userNotificationsReadChanged');
    }

    /**
     * Filtrovanie upozorneni podla stavu precitania upozornenia
     *
     * @param string $state
     * @return void
     */
    public function filterByReading(string $state): void
    {
        $this->status = $state;
    }

    /**
     * @param string $uuid
     * @param string $url
     *
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function markAsRead(string $uuid, string $url)
    {
        /** @var Pouzivatel $pouzivatel */
        $pouzivatel = auth()->user();
        /** @var \Illuminate\Notifications\DatabaseNotification $upozornenie */
        $upozornenie = $pouzivatel->notifications()->findOrFail($uuid);

        // oznacit upozornenie ako precitane ak este nie je precitane
        if (false === $upozornenie->read()) {
            $upozornenie->markAsRead();
        }

        // presmerovanie na zdroj upozornenia
        return redirect($url);
    }

    /**
     * @param string $type
     *
     * @return int
     */
    public function getCountByType(string $type): int
    {
        $stav = UpozornenieStavEnum::make($type);

        switch ($stav) {
            case UpozornenieStavEnum::ALL():
                return $this->countAll;
            case UpozornenieStavEnum::READ():
                return $this->countRead;
            case UpozornenieStavEnum::NOTREAD():
                return $this->countNotRead;
            default:
                return 0;
        }
    }
}
