package middleware

import (
	"fmt"
	"regexp"

	"github.com/go-playground/validator/v10"
)

// PasswordValidator validates password complexity requirements
type PasswordValidator struct{}

// Validate checks if a password meets complexity requirements:
// - Minimum 8 characters
// - At least one uppercase letter
// - At least one lowercase letter
// - At least one number
// - At least one special character
func (v *PasswordValidator) Validate(fl validator.FieldLevel) bool {
	password := fl.Field().String()

	// Check minimum length
	if len(password) < 8 {
		return false
	}

	// Check for uppercase
	hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(password)
	if !hasUpper {
		return false
	}

	// Check for lowercase
	hasLower := regexp.MustCompile(`[a-z]`).MatchString(password)
	if !hasLower {
		return false
	}

	// Check for number
	hasNumber := regexp.MustCompile(`[0-9]`).MatchString(password)
	if !hasNumber {
		return false
	}

	// Check for special character
	hasSpecial := regexp.MustCompile(`[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]`).MatchString(password)
	if !hasSpecial {
		return false
	}

	return true
}

// GetPasswordRequirements returns a human-readable list of password requirements
func GetPasswordRequirements() []string {
	return []string{
		"At least 8 characters long",
		"At least one uppercase letter (A-Z)",
		"At least one lowercase letter (a-z)",
		"At least one number (0-9)",
		"At least one special character (!@#$%^&*()_+-=[]{}|;':\",./<>?)",
	}
}

// ValidatePassword checks a password and returns an error if it doesn't meet requirements
func ValidatePassword(password string) error {
	if len(password) < 8 {
		return fmt.Errorf("password must be at least 8 characters long")
	}

	if !regexp.MustCompile(`[A-Z]`).MatchString(password) {
		return fmt.Errorf("password must contain at least one uppercase letter")
	}

	if !regexp.MustCompile(`[a-z]`).MatchString(password) {
		return fmt.Errorf("password must contain at least one lowercase letter")
	}

	if !regexp.MustCompile(`[0-9]`).MatchString(password) {
		return fmt.Errorf("password must contain at least one number")
	}

	if !regexp.MustCompile(`[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]`).MatchString(password) {
		return fmt.Errorf("password must contain at least one special character")
	}

	return nil
}

// RegisterPasswordValidation registers the password validator with the validator instance
func RegisterPasswordValidation(v *validator.Validate) error {
	return v.RegisterValidation("passwordcomplex", func(fl validator.FieldLevel) bool {
		pv := &PasswordValidator{}
		return pv.Validate(fl)
	})
}
