<?php

declare(strict_types=1);

namespace App\Framework\Notification\Storage;

use App\Framework\Notification\Notification;
use App\Framework\Notification\ValueObjects\NotificationId;
use App\Framework\Notification\ValueObjects\NotificationStatus;

/**
 * Repository interface for notification persistence
 */
interface NotificationRepository
{
    /**
     * Save a notification
     *
     * @param Notification $notification The notification to save
     * @return void
     */
    public function save(Notification $notification): void;

    /**
     * Find notification by ID
     *
     * @param NotificationId $id The notification ID
     * @return Notification|null The notification or null if not found
     */
    public function findById(NotificationId $id): ?Notification;

    /**
     * Find all notifications for a user
     *
     * @param string $userId The user identifier
     * @param int $limit Maximum number of notifications to return
     * @param int $offset Offset for pagination
     * @return array<Notification> Array of notifications
     */
    public function findByUser(string $userId, int $limit = 20, int $offset = 0): array;

    /**
     * Find unread notifications for a user
     *
     * @param string $userId The user identifier
     * @param int $limit Maximum number of notifications to return
     * @return array<Notification> Array of unread notifications
     */
    public function findUnreadByUser(string $userId, int $limit = 20): array;

    /**
     * Count unread notifications for a user
     *
     * @param string $userId The user identifier
     * @return int Number of unread notifications
     */
    public function countUnreadByUser(string $userId): int;

    /**
     * Mark notification as read
     *
     * @param NotificationId $id The notification ID
     * @return bool True if updated successfully
     */
    public function markAsRead(NotificationId $id): bool;

    /**
     * Mark all notifications as read for a user
     *
     * @param string $userId The user identifier
     * @return int Number of notifications marked as read
     */
    public function markAllAsReadForUser(string $userId): int;

    /**
     * Delete notification
     *
     * @param NotificationId $id The notification ID
     * @return bool True if deleted successfully
     */
    public function delete(NotificationId $id): bool;

    /**
     * Delete old notifications by status
     *
     * @param NotificationStatus $status The status to filter by
     * @param int $daysOld Delete notifications older than this many days
     * @return int Number of notifications deleted
     */
    public function deleteOldByStatus(NotificationStatus $status, int $daysOld): int;
}
