<?php

namespace Tests\Fakes;

use App\Shared\ValueObject\EmailAddress;
use App\User\CreateUserDto;
use App\User\User;
use App\User\UserRepository;

class FakeUserRepository implements UserRepository
{
    private array $usersById = [];
    private array $usersByEmail = [];

    public function create(CreateUserDto $dto): User
    {
        $id = count($this->usersById) + 1;
        $user = new User($id, $dto->email, $dto->passwordHash);
        $this->usersById[$id] = $user;
        $this->usersByEmail[$dto->email->value()] = $user;

        return $user;
    }

    public function findByEmail(EmailAddress $email): ?User
    {
        if (! isset($this->usersByEmail[$email->value()])) {
            return null;
        }

        $stored = $this->usersByEmail[$email->value()];

        return new User(
            $stored->getId(),
            $stored->getEmail(),
            $stored->getPasswordHash()
        );
    }

    public function findByEmailDomain(string $domain): array
    {
        $result = [];
        foreach ($this->usersByEmail as $email => $stored) {
            if (str_ends_with($email, '@' . $domain)) {
                $result[] = new User(
                    $stored->getId(),
                    $stored->getEmail(),
                    $stored->getPasswordHash()
                );
            }
        }

        return $result;
    }

    public function find(int $id): ?User
    {
        if (! isset($this->usersById[$id])) {
            return null;
        }

        $stored = $this->usersById[$id];

        return new User(
            $stored->getId(),
            $stored->getEmail(),
            $stored->getPasswordHash()
        );
    }
}
