<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Validation\Validator;

use Chill\MainBundle\Entity\UserGroup;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Exception\UnexpectedValueException;

final class UserGroupDoNotExclude extends ConstraintValidator
{
    public function __construct(private readonly TranslatableStringHelperInterface $translatableStringHelper) {}

    public function validate($value, Constraint $constraint)
    {
        if (!$constraint instanceof \Chill\MainBundle\Validation\Constraint\UserGroupDoNotExclude) {
            throw new UnexpectedTypeException($constraint, UserGroupDoNotExclude::class);
        }

        if (null === $value) {
            return;
        }

        if (!is_iterable($value)) {
            throw new UnexpectedValueException($value, 'iterable');
        }

        $groups = [];

        foreach ($value as $gr) {
            if ($gr instanceof UserGroup) {
                $groups[$gr->getExcludeKey()][] = $gr;
            }
        }

        foreach ($groups as $excludeKey => $groupByKey) {
            if ('' === $excludeKey) {
                continue;
            }

            if (1 < count($groupByKey)) {
                $excludedGroups = implode(
                    ', ',
                    array_map(
                        fn (UserGroup $group) => $this->translatableStringHelper->localize($group->getLabel()),
                        $groupByKey
                    )
                );

                $this->context
                    ->buildViolation($constraint->message)
                    ->setCode($constraint->code)
                    ->setParameters(['excluded_groups' => $excludedGroups])
                    ->addViolation();
            }
        }
    }
}
