<?php

namespace App\Console\Commands;

use App\Models\User;
use App\Notifications\EngagementReminderNotification;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;

class SendEngagementReminderNotifications extends Command
{
    protected $signature = 'notifications:send-engagement-reminders
        {--limit= : Maximum number of users to notify}
        {--dry-run : Count eligible users without sending notifications}';

    protected $description = 'Send occasional hard-coded engagement reminders to mobile users.';

    public function handle(): int
    {
        $limit = $this->limitOption();

        if ($limit === false) {
            $this->error('The --limit option must be an integer greater than zero.');

            return self::FAILURE;
        }

        $query = $this->eligibleUsersQuery();

        if ($this->option('dry-run')) {
            $this->info("{$query->count()} eligible user(s) found.");

            return self::SUCCESS;
        }

        $sent = 0;

        foreach ($query->lazyById(100) as $user) {
            if ($limit !== null && $sent >= $limit) {
                break;
            }

            $user->notify(
                new EngagementReminderNotification(EngagementReminderNotification::randomMessageKey()),
            );

            $sent++;
        }

        $this->info("{$sent} engagement reminder notification(s) sent.");

        return self::SUCCESS;
    }

    private function eligibleUsersQuery(): Builder
    {
        return User::query()
            ->select(['id', 'locale', 'suspended_at'])
            ->whereNull('suspended_at')
            ->whereHas('deviceTokens')
            ->whereDoesntHave('mealPosts', fn (Builder $query): Builder => $query
                ->where('created_at', '>=', now()->subDay()));
    }

    private function limitOption(): int|false|null
    {
        $limit = $this->option('limit');

        if ($limit === null || $limit === '') {
            return null;
        }

        return filter_var($limit, FILTER_VALIDATE_INT, [
            'options' => ['min_range' => 1],
        ]);
    }
}
