<?php

declare(strict_types=1);

namespace NoahVet\Reef\Mapper\Common\Many;

use Doctrine\Common\Collections\ArrayCollection;
use NoahVet\Reef\Mapper\AbstractMapper;
use Symfony\Component\Serializer\Exception\ExceptionInterface;

/**
 * @template EntityType of object
 * @template ResponseDtoType of object
 *
 * @implements AbstractGetAllMapperInterface<EntityType, ResponseDtoType>
 */
abstract class AbstractGetAllMapper extends AbstractMapper implements AbstractGetAllMapperInterface
{
    /**
     * @param array<int, EntityType>        $data
     * @param class-string<ResponseDtoType> $responseDtoFqcn
     *
     * @return list<ResponseDtoType>
     *
     * @throws ExceptionInterface
     *
     * @psalm-suppress InvalidReturnStatement
     */
    public function mapDataToResponseDto(
        array $data,
        string $responseDtoFqcn,
    ): mixed {
        $data = $this->normalizeEntities(
            new ArrayCollection($data),
        );

        foreach ($data as &$datum) {
            $this->postNormalizeEntity($datum);
        }

        return $this->serializer->denormalize(
            $data,
            $responseDtoFqcn.'[]',
        );
    }

    /**
     * @param list<ResponseDtoType> $dtoAsArray
     *
     * @return list<mixed>
     *
     * @psalm-suppress LessSpecificReturnStatement,MoreSpecificReturnType
     */
    public function normalizeResponseDto(
        array $dtoAsArray,
    ): array {
        return (array) $this->serializer->normalize($dtoAsArray);
    }

    /**
     * @param array<string, mixed> $data
     */
    protected function postNormalizeEntity(array &$data): void
    {
    }
}
