mustSuggestArgumentValuesFor('identifier')) { $clients = $this->clientRepository->findAll(Pagination::ofOffsetAndLimit(0, 100)); /** @var list $items */ $items = array_map( static fn (Client $client): Suggestion => new Suggestion( value: $client->identifier->value, description: sprintf('%s (%s)', $client->name->value, $client->isActive ? 'Active' : 'Inactive'), ), $clients->getItems(), ); $suggestions->suggestValues($items); } if ($input->mustSuggestArgumentValuesFor('status')) { $suggestions->suggestValues([ new Suggestion('activate', 'Activate the client'), new Suggestion('deactivate', 'Deactivate the client'), ]); } } public function handle( SetClientStatus $usecase, UsecaseExecutor $executor, ): int { $identifierString = $this->resolveIdentifier(); if ($identifierString === null) { return self::FAILURE; } try { $clientIdentifier = $this->parseClientIdentifier($identifierString); $desiredStatus = $this->resolveDesiredStatus($clientIdentifier); $input = new Input($clientIdentifier, $desiredStatus); $view = UsecaseBuilder::using($executor) ->do($usecase) ->from($input) ->with(new SetClientStatusPresenter()) ->run(); $this->info($view->message); return self::SUCCESS; } catch (ClientNotFoundException | \InvalidArgumentException $e) { $this->error($e->getMessage()); return self::FAILURE; } } private function resolveIdentifier(): ?string { $raw = $this->argument('identifier'); if ($raw !== null) { return (string) $raw; } $clients = $this->clientRepository->findAll(Pagination::ofOffsetAndLimit(0, 50)); $items = $clients->getItems(); if ($items === []) { $this->error('No clients found in the database.'); return null; } $choices = []; foreach ($items as $client) { $choices[$client->identifier->value] = sprintf( '%s (%s) - %s', $client->name->value, $client->isActive ? 'Active' : 'Inactive', $client->identifier->value, ); } $selectedDisplay = $this->choice('Which client would you like to update?', array_values($choices)); return (string) array_search($selectedDisplay, $choices, true); } /** * @throws \InvalidArgumentException */ private function parseClientIdentifier(string $value): ClientIdentifier { try { return new ClientIdentifier($value); } catch (\InvalidArgumentException) { throw new \InvalidArgumentException("Invalid client identifier '{$value}'. Expected a valid client identifier."); } } private function resolveDesiredStatus(ClientIdentifier $clientIdentifier): bool { $status = $this->argument('status') !== null ? (string) $this->argument('status') : null; return match ($status) { 'activate' => true, 'deactivate' => false, null => $this->resolveToggledStatus($clientIdentifier), default => throw new \InvalidArgumentException("Invalid status '{$status}'. Expected 'activate' or 'deactivate'."), }; } private function resolveToggledStatus(ClientIdentifier $clientIdentifier): bool { $client = $this->clientRepository->findByIdentifier($clientIdentifier) ?? throw ClientNotFoundException::forClient($clientIdentifier->value); return ! $client->isActive; } }