<?php

declare(strict_types=1);

namespace App\Tests\Unit\SuperAdmin\Infrastructure\Console;

use App\Administration\Application\Port\PasswordHasher;
use App\Shared\Domain\Clock;
use App\SuperAdmin\Infrastructure\Console\CreateTestSuperAdminCommand;
use App\SuperAdmin\Infrastructure\Persistence\InMemory\InMemorySuperAdminRepository;
use DateTimeImmutable;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Tester\CommandTester;

final class CreateTestSuperAdminCommandTest extends TestCase
{
    private InMemorySuperAdminRepository $repository;
    private CommandTester $commandTester;

    protected function setUp(): void
    {
        $this->repository = new InMemorySuperAdminRepository();

        $clock = new class implements Clock {
            public function now(): DateTimeImmutable
            {
                return new DateTimeImmutable('2026-02-17 10:00:00');
            }
        };

        $passwordHasher = new class implements PasswordHasher {
            public function hash(string $plainPassword): string
            {
                return 'hashed_' . $plainPassword;
            }

            public function verify(string $hashedPassword, string $plainPassword): bool
            {
                return $hashedPassword === 'hashed_' . $plainPassword;
            }
        };

        $command = new CreateTestSuperAdminCommand(
            $this->repository,
            $passwordHasher,
            $clock,
        );

        $this->commandTester = new CommandTester($command);
    }

    #[Test]
    public function createsNewSuperAdmin(): void
    {
        $exitCode = $this->commandTester->execute([
            '--email' => 'sadmin@test.com',
            '--password' => 'SuperAdmin123',
            '--first-name' => 'Super',
            '--last-name' => 'Admin',
        ]);

        self::assertSame(Command::SUCCESS, $exitCode);
        self::assertStringContainsString('Test super admin created successfully', $this->commandTester->getDisplay());

        $superAdmin = $this->repository->findByEmail('sadmin@test.com');
        self::assertNotNull($superAdmin);
        self::assertSame('sadmin@test.com', $superAdmin->email);
        self::assertSame('Super', $superAdmin->firstName);
        self::assertSame('Admin', $superAdmin->lastName);
        self::assertSame('hashed_SuperAdmin123', $superAdmin->hashedPassword);
    }

    #[Test]
    public function returnsSuccessForExistingEmail(): void
    {
        // Create first
        $this->commandTester->execute([
            '--email' => 'sadmin@test.com',
            '--password' => 'SuperAdmin123',
        ]);

        // Create again with same email
        $exitCode = $this->commandTester->execute([
            '--email' => 'sadmin@test.com',
            '--password' => 'SuperAdmin123',
        ]);

        self::assertSame(Command::SUCCESS, $exitCode);
        self::assertStringContainsString('already exists', $this->commandTester->getDisplay());
    }

    #[Test]
    public function usesDefaultValues(): void
    {
        $exitCode = $this->commandTester->execute([]);

        self::assertSame(Command::SUCCESS, $exitCode);

        $superAdmin = $this->repository->findByEmail('sadmin@test.com');
        self::assertNotNull($superAdmin);
        self::assertSame('Super', $superAdmin->firstName);
        self::assertSame('Admin', $superAdmin->lastName);
    }
}
