package validators

import (
	"regexp"
)

var (
	hasUpper   = regexp.MustCompile(`[A-Z]`)
	hasLower   = regexp.MustCompile(`[a-z]`)
	hasNumber  = regexp.MustCompile(`[0-9]`)
	hasSpecial = regexp.MustCompile(`[!@#$%^&*(),.?":{}|<>]`)
)

// PasswordValidator valide la force d'un mot de passe
type PasswordValidator struct {
	MinLength int
}

// NewPasswordValidator crée une nouvelle instance de PasswordValidator
func NewPasswordValidator() *PasswordValidator {
	return &PasswordValidator{MinLength: 12}
}

// PasswordStrength représente le résultat de la validation d'un mot de passe
type PasswordStrength struct {
	Valid   bool
	Score   int
	Details []string
}

// Validate valide la force d'un mot de passe selon les règles définies
func (v *PasswordValidator) Validate(password string) (PasswordStrength, error) {
	strength := PasswordStrength{
		Valid:   true,
		Details: []string{},
	}

	// Length check
	if len(password) < v.MinLength {
		strength.Valid = false
		strength.Details = append(strength.Details,
			"Password must be at least 12 characters long")
		return strength, nil
	}

	// Upper case check
	if !hasUpper.MatchString(password) {
		strength.Valid = false
		strength.Details = append(strength.Details, "Must contain uppercase letter")
	} else {
		strength.Score++
	}

	// Lower case check
	if !hasLower.MatchString(password) {
		strength.Valid = false
		strength.Details = append(strength.Details, "Must contain lowercase letter")
	} else {
		strength.Score++
	}

	// Number check
	if !hasNumber.MatchString(password) {
		strength.Valid = false
		strength.Details = append(strength.Details, "Must contain number")
	} else {
		strength.Score++
	}

	// Special character check
	if !hasSpecial.MatchString(password) {
		strength.Valid = false
		strength.Details = append(strength.Details, "Must contain special character")
	} else {
		strength.Score++
	}

	return strength, nil
}
