<?php

declare(strict_types=1);

namespace App\Module\Transport\Application\Service;

/**
 * Normalisation serveur des champs texte d'un Carrier / CarrierContact, appliquee
 * par le CarrierProcessor (et les futurs processors de sous-ressources, WT6/7/8)
 * AVANT persistance. Cf. spec-back M4 § 2.10 + RG-4.13. Jumeau de
 * SupplierFieldNormalizer (M2), enrichi du cas LIOT (immatriculations).
 *
 * - name : UPPERCASE integral (RG-4.13)
 * - firstName / lastName (personnes, sur CarrierContact) : Title Case (RG-4.13)
 * - phone* : chiffres uniquement, ex "06.12.34.56.78" -> "0612345678" (RG-4.13).
 *   Le formatage d'affichage "XX XX XX XX XX" est de la responsabilite du front.
 * - email : lowercase integral (RG-4.13)
 * - liotPlates : liste « ; » -> split, trim, UPPER, rejoin "; " (cas LIOT RG-4.01).
 *
 * Toutes les methodes sont null-safe et trim-ent l'entree ; une chaine vide apres
 * trim devient null (evite de persister "" dans des colonnes nullable).
 */
final class CarrierFieldNormalizer
{
    /**
     * Raison sociale en majuscules (RG-4.13). Conserve null tel quel ; une chaine
     * non vide est trim + upper. Une chaine vide reste "" (champ obligatoire :
     * c'est l'Assert\NotBlank qui rejette, pas le normalizer).
     */
    public function normalizeName(?string $value): ?string
    {
        if (null === $value) {
            return null;
        }

        return mb_strtoupper(trim($value), 'UTF-8');
    }

    /**
     * Nom/prenom de personne en Title Case (RG-4.13) : "JEAN dupont" ->
     * "Jean Dupont". Une chaine vide apres trim devient null.
     */
    public function normalizePersonName(?string $value): ?string
    {
        if (null === $value) {
            return null;
        }

        $value = trim($value);

        return '' === $value ? null : mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
    }

    /**
     * Email en minuscules (RG-4.13). Une chaine vide apres trim devient null.
     */
    public function normalizeEmail(?string $value): ?string
    {
        if (null === $value) {
            return null;
        }

        $value = trim($value);

        return '' === $value ? null : mb_strtolower($value, 'UTF-8');
    }

    /**
     * Telephone reduit aux chiffres (RG-4.13) : "06.12.34.56.78" -> "0612345678".
     * Une valeur sans aucun chiffre devient null.
     */
    public function normalizePhone(?string $value): ?string
    {
        if (null === $value) {
            return null;
        }

        $digits = preg_replace('/\D+/', '', $value) ?? '';

        return '' === $digits ? null : $digits;
    }

    /**
     * Immatriculations LIOT (RG-4.01 / RG-4.13) : la saisie « ; »-separee est
     * decoupee, chaque plaque trim + UPPER, les segments vides ecartes, puis
     * recomposee avec le separateur canonique "; ". Une saisie sans aucune plaque
     * exploitable devient null.
     */
    public function normalizeLiotPlates(?string $value): ?string
    {
        if (null === $value) {
            return null;
        }

        $plates = [];
        foreach (explode(';', $value) as $plate) {
            $plate = trim($plate);
            if ('' !== $plate) {
                $plates[] = mb_strtoupper($plate, 'UTF-8');
            }
        }

        return [] === $plates ? null : implode('; ', $plates);
    }
}
