package dev.lions.user.manager.service.impl;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import java.util.regex.Pattern;

/**
 * Classe utilitaire pour la validation des données CSV lors de l'import d'utilisateurs
 *
 * @author Lions Development Team
 * @version 1.0.0
 * @since 2026-01-02
 */
@Slf4j
@UtilityClass
public class CsvValidationHelper {

    /**
     * Pattern pour valider le format d'email selon RFC 5322 (simplifié)
     */
    private static final Pattern EMAIL_PATTERN = Pattern.compile(
        "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$"
    );

    /**
     * Pattern pour valider le username (alphanumérique, tirets, underscores, points)
     */
    private static final Pattern USERNAME_PATTERN = Pattern.compile(
        "^[a-zA-Z0-9._-]{2,255}$"
    );

    /**
     * Longueur minimale pour un username
     */
    private static final int USERNAME_MIN_LENGTH = 2;

    /**
     * Longueur maximale pour un username
     */
    private static final int USERNAME_MAX_LENGTH = 255;

    /**
     * Longueur maximale pour un nom ou prénom
     */
    private static final int NAME_MAX_LENGTH = 255;

    /**
     * Valide le format d'un email
     *
     * @param email Email à valider
     * @return true si l'email est valide, false sinon
     */
    public static boolean isValidEmail(String email) {
        if (email == null || email.isBlank()) {
            return false;
        }
        return EMAIL_PATTERN.matcher(email.trim()).matches();
    }

    /**
     * Valide un username
     *
     * @param username Username à valider
     * @return Message d'erreur si invalide, null si valide
     */
    public static String validateUsername(String username) {
        if (username == null || username.isBlank()) {
            return "Username obligatoire";
        }

        String trimmed = username.trim();

        if (trimmed.length() < USERNAME_MIN_LENGTH) {
            return String.format("Username trop court (minimum %d caractères)", USERNAME_MIN_LENGTH);
        }

        if (trimmed.length() > USERNAME_MAX_LENGTH) {
            return String.format("Username trop long (maximum %d caractères)", USERNAME_MAX_LENGTH);
        }

        if (!USERNAME_PATTERN.matcher(trimmed).matches()) {
            return "Username invalide (autorisé: lettres, chiffres, .-_)";
        }

        return null; // Valide
    }

    /**
     * Valide un email (peut être vide)
     *
     * @param email Email à valider
     * @return Message d'erreur si invalide, null si valide ou vide
     */
    public static String validateEmail(String email) {
        if (email == null || email.isBlank()) {
            return null; // Email optionnel
        }

        if (!isValidEmail(email)) {
            return "Format d'email invalide";
        }

        return null; // Valide
    }

    /**
     * Valide un nom ou prénom
     *
     * @param name Nom à valider
     * @param fieldName Nom du champ pour les messages d'erreur
     * @return Message d'erreur si invalide, null si valide
     */
    public static String validateName(String name, String fieldName) {
        if (name == null || name.isBlank()) {
            return null; // Nom optionnel
        }

        String trimmed = name.trim();

        if (trimmed.length() > NAME_MAX_LENGTH) {
            return String.format("%s trop long (maximum %d caractères)", fieldName, NAME_MAX_LENGTH);
        }

        return null; // Valide
    }

    /**
     * Valide une valeur boolean
     *
     * @param value Valeur à valider
     * @return Message d'erreur si invalide, null si valide
     */
    public static String validateBoolean(String value) {
        if (value == null || value.isBlank()) {
            return null; // Optionnel, défaut à false
        }

        String trimmed = value.trim().toLowerCase();
        if (!trimmed.equals("true") && !trimmed.equals("false") &&
            !trimmed.equals("1") && !trimmed.equals("0") &&
            !trimmed.equals("yes") && !trimmed.equals("no")) {
            return "Valeur boolean invalide (attendu: true/false, 1/0, yes/no)";
        }

        return null; // Valide
    }

    /**
     * Convertit une chaîne en boolean
     *
     * @param value Valeur à convertir
     * @return boolean correspondant
     */
    public static boolean parseBoolean(String value) {
        if (value == null || value.isBlank()) {
            return false;
        }

        String trimmed = value.trim().toLowerCase();
        return trimmed.equals("true") || trimmed.equals("1") || trimmed.equals("yes");
    }

    /**
     * Nettoie une chaîne (trim et null si vide)
     *
     * @param value Valeur à nettoyer
     * @return Valeur nettoyée ou null
     */
    public static String clean(String value) {
        if (value == null || value.isBlank()) {
            return null;
        }
        return value.trim();
    }
}
