<?php

declare(strict_types=1);

namespace HyperfTest\Cases\Unit\Command;

use App\Command\UserListCommand;
use Hyperf\Context\ApplicationContext;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Tester\CommandTester;

/**
 * UserListCommand 单元测试
 *
 * @internal
 * @coversNothing
 */
class UserListCommandTest extends TestCase
{
    private function runInCoroutine(callable $callback): void
    {
        if (\Swoole\Coroutine::getCid() > 0) {
            $callback();
            return;
        }

        $exception = null;
        \Swoole\Coroutine\run(static function () use ($callback, &$exception): void {
            try {
                $callback();
            } catch (\Throwable $e) {
                $exception = $e;
            }
        });
        if ($exception !== null) {
            throw $exception;
        }
    }

    public function test_list_all_users_displays_table(): void
    {
        $this->runInCoroutine(function (): void {
            $container = ApplicationContext::getContainer();
            $command = new UserListCommand($container);
            $tester = new CommandTester($command);
            $tester->execute([]);

            $output = $tester->getDisplay();
            $this->assertStringContainsString('ID', $output);
            $this->assertStringContainsString('Username', $output);
            $this->assertStringContainsString('Email', $output);
            $this->assertStringContainsString('Role', $output);
            $this->assertStringContainsString('Status', $output);
            $this->assertStringContainsString('Total:', $output);
        });
    }

    public function test_list_users_filtered_by_role(): void
    {
        $this->runInCoroutine(function (): void {
            $container = ApplicationContext::getContainer();
            $command = new UserListCommand($container);
            $tester = new CommandTester($command);
            $tester->execute(['--role' => 'administrator']);

            $output = $tester->getDisplay();
            $this->assertTrue(
                str_contains($output, 'administrator') || str_contains($output, 'No users found'),
                'Should display administrator users or empty message'
            );
        });
    }

    public function test_list_users_with_nonexistent_role_shows_empty(): void
    {
        $this->runInCoroutine(function (): void {
            $container = ApplicationContext::getContainer();
            $command = new UserListCommand($container);
            $tester = new CommandTester($command);
            $tester->execute(['--role' => 'nonexistent_role_xyz_123']);

            $output = $tester->getDisplay();
            $this->assertStringContainsString('No users found', $output);
        });
    }
}
