<?php

namespace App\Observers;

use App\Jobs\SendWebPushToUser;
use App\Models\Partnership;
use App\Models\User;
use App\Models\WorkspaceMember;
use App\Services\WebPushSender;
use Illuminate\Support\Facades\Auth;

class PartnershipObserver
{
    public function created(Partnership $partnership): void
    {
        if (! app(WebPushSender::class)->isConfigured()) {
            return;
        }

        $actorId = Auth::id();
        foreach ($this->eligibleUserIds($partnership) as $userId) {
            if ($actorId !== null && $userId === $actorId) {
                continue;
            }
            if (User::query()->find($userId)?->pushSubscriptions()->doesntExist()) {
                continue;
            }

            SendWebPushToUser::dispatch(
                $userId,
                (string) config('app.name', 'Collabs'),
                __('New collab: :name', ['name' => $partnership->restaurant_name]),
                '/app',
                'collab-created-'.$partnership->id,
            )->afterCommit();
        }
    }

    public function updated(Partnership $partnership): void
    {
        if (! $partnership->wasChanged('status')) {
            return;
        }

        if (! app(WebPushSender::class)->isConfigured()) {
            return;
        }

        $actorId = Auth::id();
        $statusLabel = $partnership->status instanceof \BackedEnum
            ? $partnership->status->value
            : (string) $partnership->status;

        foreach ($this->eligibleUserIds($partnership) as $userId) {
            if ($actorId !== null && $userId === $actorId) {
                continue;
            }
            if (User::query()->find($userId)?->pushSubscriptions()->doesntExist()) {
                continue;
            }

            SendWebPushToUser::dispatch(
                $userId,
                (string) config('app.name', 'Collabs'),
                __(':name moved to :status', ['name' => $partnership->restaurant_name, 'status' => $statusLabel]),
                '/app',
                'collab-status-'.$partnership->id,
            )->afterCommit();
        }
    }

    public function deleting(Partnership $partnership): void
    {
        if (! app(WebPushSender::class)->isConfigured()) {
            return;
        }

        $actorId = Auth::id();
        $name = $partnership->restaurant_name;

        foreach ($this->eligibleUserIds($partnership) as $userId) {
            if ($actorId !== null && $userId === $actorId) {
                continue;
            }
            if (User::query()->find($userId)?->pushSubscriptions()->doesntExist()) {
                continue;
            }

            SendWebPushToUser::dispatch(
                $userId,
                (string) config('app.name', 'Collabs'),
                __(':name was removed from the board', ['name' => $name]),
                '/app',
                'collab-deleted-'.$partnership->id,
            )->afterCommit();
        }
    }

    /**
     * @return list<int>
     */
    private function eligibleUserIds(Partnership $partnership): array
    {
        $ids = WorkspaceMember::query()
            ->where('workspace_id', $partnership->workspace_id)
            ->pluck('user_id')
            ->unique()
            ->all();

        $out = [];
        foreach ($ids as $userId) {
            $user = User::query()->find($userId);
            if ($user !== null && $partnership->isVisibleTo($user)) {
                $out[] = (int) $userId;
            }
        }

        return $out;
    }
}
