<?php

declare(strict_types=1);

namespace App\Module\Commercial\Application\Validator;

use ApiPlatform\Validator\Exception\ValidationException;
use App\Module\Commercial\Domain\Entity\Client;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;

/**
 * Validator metier RG-1.04 (durcie ERP-74) : pour un utilisateur portant le
 * role metier Commerciale, TOUS les champs de l'onglet Information sont
 * obligatoires sur POST comme sur tout PATCH, independamment des champs
 * reellement envoyes.
 *
 * Invoque par le ClientProcessor des que l'utilisateur courant porte le role
 * Commerciale (plus de condition d'intersection avec l'onglet Information).
 * Pour les autres roles, ces champs restent optionnels — le validator n'est
 * pas appele.
 *
 * Leve une ValidationException (HTTP 422) listant chaque champ manquant, par
 * coherence avec les violations Symfony rendues par API Platform.
 */
final class ClientInformationCompletenessValidator
{
    public function validate(Client $client): void
    {
        // Map champ -> valeur courante de l'onglet Information.
        $fields = [
            'description'    => $client->getDescription(),
            'competitors'    => $client->getCompetitors(),
            'foundedAt'      => $client->getFoundedAt(),
            'employeesCount' => $client->getEmployeesCount(),
            'revenueAmount'  => $client->getRevenueAmount(),
            'directorName'   => $client->getDirectorName(),
            'profitAmount'   => $client->getProfitAmount(),
        ];

        $violations = new ConstraintViolationList();

        foreach ($fields as $property => $value) {
            if ($this->isMissing($value)) {
                $violations->add(new ConstraintViolation(
                    sprintf('Ce champ est obligatoire pour le role Commerciale (champ "%s").', $property),
                    null,
                    [],
                    $client,
                    $property,
                    $value,
                ));
            }
        }

        if (count($violations) > 0) {
            throw new ValidationException($violations);
        }
    }

    /**
     * Une valeur est manquante si null ou, pour une chaine, vide apres trim.
     * Les zeros numeriques (employeesCount = 0, profitAmount = "0.00") sont des
     * valeurs valides : on ne les considere pas manquants.
     */
    private function isMissing(mixed $value): bool
    {
        if (null === $value) {
            return true;
        }

        return is_string($value) && '' === trim($value);
    }
}
