<?php

namespace NoahVet\Reef\Business\Enumerator;

use NoahVet\Reef\Jane\Client;
use NoahVet\Reef\Jane\Exception\GetAllManufacturerUserBadRequestException;
use NoahVet\Reef\Jane\Model\ManufacturerResponseItem;
use NoahVet\Reef\Jane\Model\ManufacturerUserResponseItem;

class ManufacturerTeamMembersEnumerator implements ManufacturerTeamMembersEnumeratorInterface
{
    public function __construct(
        protected readonly Client $internalServiceClient,
    ) {
    }

    /**
     * @param ?string[] $manufacturerIdFilter
     *
     * @return \Generator<ManufacturerUserResponseItem>
     */
    #[\Override]
    public function enumerateAll(?array $manufacturerIdFilter = null, int $querySize = 50): \Generator
    {
        for ($page = 0; true; ++$page) {
            try {
                $params = ['page' => $page, 'limit' => $querySize];
                if (null !== $manufacturerIdFilter && !empty($manufacturerIdFilter)) {
                    $params['manufacturerId'] = $manufacturerIdFilter;
                }
                $teamMembers = $this->internalServiceClient->getAllManufacturerUser($params);

                \assert(\is_array($teamMembers));

                foreach ($teamMembers as $teamMember) {
                    yield $teamMember;
                }

                if (\count($teamMembers) < $querySize) {
                    break;
                }
            } catch (GetAllManufacturerUserBadRequestException) {
                // End of enumeration
                break;
            }
        }
    }

    /**
     * @param ManufacturerResponseItem[] $manufacturers
     *
     * @return array<string, array<ManufacturerUserResponseItem>>
     */
    #[\Override]
    public function getTeamMembers(array $manufacturers, int $querySize = 50): array
    {
        $idFilter = \array_map(static fn ($m): string => $m->getId(), $manufacturers);

        return \array_reduce(
            \iterator_to_array($this->enumerateAll($idFilter, $querySize)),
            static function (array $carry, ManufacturerUserResponseItem $item): array {
                $manufacturerId = $item->getManufacturer()?->getId();

                if (null !== $manufacturerId) {
                    $carry[$manufacturerId][] = $item;
                }

                return $carry;
            },
            [],
        );
    }
}
