<?php

namespace App\Modules\Dashboard\Repositories;

use App\Models\User;
use App\Support\NotificationCategory;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Notifications\DatabaseNotification;
use Illuminate\Support\Collection;

class NotificationCenterRepository
{
    public function unreadCount(User $user): int
    {
        return $user->unreadNotifications()->count();
    }

    /**
     * @return LengthAwarePaginator<int, DatabaseNotification>
     */
    public function paginateForUser(User $user, ?string $category, int $perPage = 20): LengthAwarePaginator
    {
        $q = $user->notifications()->orderByDesc('created_at');
        if ($category !== null && $category !== 'all') {
            if ($category === NotificationCategory::APPROVALS) {
                $q->where(function ($w): void {
                    $w->where('data->category', NotificationCategory::APPROVALS)
                        ->orWhere(function ($legacy): void {
                            $legacy->where('type', 'like', '%LeaveRequest%')
                                ->where(function ($p): void {
                                    $p->whereNull('data->category')
                                        ->orWhere('data->category', '');
                                });
                        });
                });
            } else {
                $q->where('data->category', $category);
            }
        }

        return $q->paginate($perPage)->withQueryString();
    }

    public function findOwned(User $user, string $id): ?DatabaseNotification
    {
        return $user->notifications()->whereKey($id)->first();
    }

    public function markAsRead(User $user, string $id): bool
    {
        $n = $this->findOwned($user, $id);
        if ($n === null) {
            return false;
        }
        if ($n->read_at === null) {
            $n->markAsRead();
        }

        return true;
    }

    public function markAllRead(User $user): void
    {
        $user->unreadNotifications()->update(['read_at' => now()]);
    }

    /**
     * @return Collection<int, DatabaseNotification>
     */
    public function latestUnread(User $user, int $limit = 6)
    {
        return $user->unreadNotifications()->latest()->limit($limit)->get();
    }
}
