<?php

namespace Tests\Feature;

use Tests\Fixtures\PingJob;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Queue\Worker as QueueWorker;
use Illuminate\Queue\WorkerOptions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Tests\TestCase;

class WorkermanQueueTest extends TestCase
{
    use RefreshDatabase;

    /**
     * Workerman 消费者复用 Laravel Queue Worker：验证能真实消费 database 队列任务。
     */
    public function test_worker_consumes_database_job(): void
    {
        config(['queue.default' => 'database']);

        Log::spy();

        dispatch(new PingJob);

        $this->assertSame(1, DB::table('jobs')->count());

        $this->runWorkerOnce('database', 'default');

        $this->assertSame(0, DB::table('jobs')->count());
        Log::shouldHaveReceived('info')->withArgs(fn ($message) => str_contains($message, 'WM_PING_CONSUMED'));
    }

    /**
     * 多队列（default,ai）支持：ai 队列任务也能被消费。
     */
    public function test_worker_consumes_multiple_queues(): void
    {
        config(['queue.default' => 'database']);

        Log::spy();

        dispatch((new PingJob)->onQueue('ai'));

        $this->runWorkerOnce('database', 'default,ai');

        $this->assertSame(0, DB::table('jobs')->count());
        Log::shouldHaveReceived('info')->withArgs(fn ($message) => str_contains($message, 'WM_PING_CONSUMED'));
    }

    private function runWorkerOnce(string $connection, string $queues): void
    {
        $worker = new QueueWorker(
            app('queue'),
            app('events'),
            app(ExceptionHandler::class),
            fn () => app()->isDownForMaintenance(),
        );

        $options = new WorkerOptions(
            name: 'laralog-test',
            backoff: 0,
            memory: 128,
            timeout: 30,
            sleep: 0,
            maxTries: 2,
        );

        $worker->runNextJob($connection, $queues, $options);
    }
}
