<?php

namespace BookStack\Activity\Notifications\Handlers;

use BookStack\Activity\Models\Loggable;
use BookStack\Activity\Notifications\Messages\BaseActivityNotification;
use BookStack\Entities\Models\Entity;
use BookStack\Permissions\Permission;
use BookStack\Permissions\PermissionApplicator;
use BookStack\Users\Models\User;
use Illuminate\Support\Facades\Log;

abstract class BaseNotificationHandler implements NotificationHandler
{
    /**
     * @param class-string<BaseActivityNotification> $notification
     * @param int[] $userIds
     */
    protected function sendNotificationToUserIds(string $notification, array $userIds, User $initiator, string|Loggable $detail, Entity $relatedModel): void
    {
        $users = User::query()->whereIn('id', array_unique($userIds))->get();

        /** @var User $user */
        foreach ($users as $user) {
            // Prevent sending to the user that initiated the activity
            if ($user->id === $initiator->id) {
                continue;
            }

            // Prevent sending of the user does not have notification permissions
            if (!$user->can(Permission::ReceiveNotifications)) {
                continue;
            }

            // Prevent sending if the user does not have access to the related content
            $permissions = new PermissionApplicator($user);
            if (!$permissions->checkOwnableUserAccess($relatedModel, 'view')) {
                continue;
            }

            // Send the notification
            try {
                $user->notify(new $notification($detail, $initiator));
            } catch (\Exception $exception) {
                Log::error("Failed to send email notification to user [id:{$user->id}] with error: {$exception->getMessage()}");
            }
        }
    }
}
