<?php

namespace App\Filter;

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\QueryBuilder;
use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use Symfony\Component\PropertyInfo\Type;

class NotEqualIdFilter extends AbstractFilter
{
    protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void
    {
        if ($property !== 'id') {
            return;
        }

        if (is_array($value) && isset($value['neq'])) {
            $value = $value['neq'];
        }

        if (is_string($value)) {
            $value = array_map('intval', explode(',', $value));
        }

        if (!is_array($value) || empty($value)) {
            return;
        }

        $alias = $queryBuilder->getRootAliases()[0];
        $paramName = $queryNameGenerator->generateParameterName('id');

        $queryBuilder
            ->andWhere(sprintf('%s.%s NOT IN (:%s)', $alias, $property, $paramName))
            ->setParameter($paramName, $value);
    }

    public function getDescription(string $resourceClass): array
    {
        return [
            'id[neq]' => [
                'property' => 'id',
                'type' => Type::BUILTIN_TYPE_INT,
                'required' => false,
                'description' => 'Exclude records where id is in the given list.',
            ],
        ];
    }
}
