<?php

namespace NoahVet\Reef\Business\Enumerator;

use NoahVet\Reef\Business\Model\EstablishmentWithLegalStructure;
use NoahVet\Reef\Business\Model\Factory\TeamMemberFactory;
use NoahVet\Reef\Jane\Model\VeterinaryEstablishmentResponse;
use NoahVet\Reef\Jane\Model\VeterinaryEstablishmentUserResponse;

/**
 * @psalm-import-type VeterinaryEstablishmentFilter from VeterinaryEstablishmentEnumerator
 */
class EstablishmentWithLegalStructureEnumerator
{
    public function __construct(
        protected VeterinaryEstablishmentEnumerator $establishmentEnumerator,
        protected VeterinaryEstablishmentTeamMembersEnumerator $teamMembersEnumerator,
        protected TeamMemberFactory $teamMemberFactory,
    ) {
    }

    /**
     * @param VeterinaryEstablishmentFilter $establishmentFilters
     *
     * @return \Generator<EstablishmentWithLegalStructure>
     */
    public function enumerateAll(
        int $establishmentBatchSize = 50,
        array $establishmentFilters = [],
    ): \Generator {
        $batch = [];

        foreach ($this->establishmentEnumerator->enumerateAll($establishmentFilters, $establishmentBatchSize) as $establishment) {
            $batch[] = $establishment;

            if (\count($batch) === $establishmentBatchSize) {
                yield from $this->buildBatch($batch);
                $batch = [];
            }
        }

        if (!empty($batch)) {
            yield from $this->buildBatch($batch);
        }
    }

    /**
     * @param VeterinaryEstablishmentResponse[] $batch
     *
     * @return EstablishmentWithLegalStructure[]
     */
    private function buildBatch(array $batch): array
    {
        $teamMembers = $this->teamMembersEnumerator->getTeamMembers($batch);

        return \array_map(
            fn (VeterinaryEstablishmentResponse $est): EstablishmentWithLegalStructure => new EstablishmentWithLegalStructure(
                $est->getId(),
                $est->getPrivilegedCode(),
                \array_map(
                    fn (VeterinaryEstablishmentUserResponse $member) => $this->teamMemberFactory->create($member),
                    $teamMembers[$est->getId()] ?? [],
                ),
                $est->getLegalStructure()->getId(),
            ),
            $batch,
        );
    }
}
