<?php declare(strict_types=1);

namespace App\Repositories;

use App\Contracts\Search;
use App\Models\User;
use App\Dto\Builder\User as UserBuilderDto;
use App\Services\User\BuilderCommand;
use App\Services\Search\CreateSearchInstanceCommand;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Builder;

final readonly class UserRepository
{
    public function __construct(
        private CreateSearchInstanceCommand $createSearchInstanceCommand,
        private BuilderCommand $builderCommand
    ) { }

    public function getUserById(int $id): ?User
    {
        return User::query()->where('id', $id)->first();
    }

    public function getUserByEmail(string $email): ?User
    {
        return User::query()->where('email', Str::lower($email))->first();
    }

    public function getUsers(UserBuilderDto $userBuilderDto, array $with = []): Search
    {
        $query = $this->builderCommand->execute(
            query: User::query()->with($with),
            userBuilderDto: $userBuilderDto
        );

        return $this->createSearchInstanceCommand->execute($query);
    }

    public function isExistsEmail(string $email, ?int $exceptId = null): bool
    {
        return User::query()
            ->where('email', Str::lower($email))
            ->when($exceptId, function (Builder $query, int $exceptId) {
                $query->where('id', '!=', $exceptId);
            })
            ->withTrashed()
            ->exists();
    }
}