package validation

import (
	"fmt"
	"strings"

	"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
	"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)

const (
	minimumPasswordLength = 8
)

func validateSelfregistrationPassword(user *viewmodel.User, result *[]errors.ValidationError) {
	if len(user.Pass) < minimumPasswordLength {
		*result = append(*result, errors.ValidationError{Field: "password", Message: fmt.Sprint("Password must be at least ", minimumPasswordLength, " characters.")})
	}

	if strings.Contains(user.Pass, user.First) {
		*result = append(*result, errors.ValidationError{Field: "password", Message: "Password cannot include your First Name."})
	}

	if strings.Contains(user.Pass, user.Last) {
		*result = append(*result, errors.ValidationError{Field: "password", Message: "Password cannot include your Last Name."})
	}

	containsUpperCaseLetter := false
	containsLowerCaseLetter := false
	containsNumber := false

	for _, character := range user.Pass {
		containsUpperCaseLetter = containsUpperCaseLetter || characterIsUpperCase(character)
		containsLowerCaseLetter = containsLowerCaseLetter || characterIsLowerCase(character)
		containsNumber = containsNumber || characterIsNumber(character)
	}

	if !containsUpperCaseLetter || !containsLowerCaseLetter || !containsNumber {
		*result = append(*result, errors.ValidationError{Field: "password", Message: "Password must contain one of EACH :"})
		*result = append(*result, errors.ValidationError{Field: "password-tab", Message: "an uppercase letter"})
		*result = append(*result, errors.ValidationError{Field: "password-tab", Message: "a lowercase letter"})
		*result = append(*result, errors.ValidationError{Field: "password-tab", Message: "a number"})
	}
}

func ValidateSelfregistration(user *viewmodel.User) []errors.ValidationError {
	var result []errors.ValidationError

	//Provider Organization Name validation
	if len(user.Provider.OrganizatioName) < 1 {
		result = append(result, errors.ValidationError{Field: "provider.org_name", Message: "Provider Organization Name is required"})
	}

	//Provider NPI validation
	if len(user.Provider.InternalID) != 10 || !isNumeric(user.Provider.InternalID) {
		result = append(result, errors.ValidationError{Field: "provider.internal_id", Message: "Provider NPI must be a 10 digit number"})
	}

	//First name validation
	if len(user.First) < 1 {
		result = append(result, errors.ValidationError{Field: "first", Message: "First Name is required"})
	}

	if !isAlphabetic(user.First) {
		result = append(result, errors.ValidationError{Field: "first", Message: "First Name contains non-alphabetic characters"})
	}

	if len(user.First) > firstNameMaxLength {
		result = append(result, errors.ValidationError{Field: "first", Message: "First Name is too long"})
	}

	//Last name validation
	if len(user.Last) < 1 {
		result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is required"})
	}

	if !isAlphabetic(user.Last) {
		result = append(result, errors.ValidationError{Field: "last", Message: "Last Name contains non-alphabetic characters"})
	}

	if len(user.Last) > lastNameMaxLength {
		result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is too long"})
	}

	//Email validation
	if user.Email != nil {
		if len(*user.Email) < 1 {
			result = append(result, errors.ValidationError{Field: "email", Message: "Email is required"})
		}

		if !isEmailValid(*user.Email) {
			result = append(result, errors.ValidationError{Field: "email", Message: "Email is invalid"})
		}

		if len(*user.Email) > emailMaxLength {
			result = append(result, errors.ValidationError{Field: "email", Message: "Email is too long"})
		}
	} else {
		result = append(result, errors.ValidationError{Field: "email", Message: "Email is required"})
	}

	//Mobile validation
	if (user.PhoneNumber == nil) || len(*user.PhoneNumber) < 1 {
		result = append(result, errors.ValidationError{Field: "phonenumber", Message: "Phone number is required"})
	}

	//Password validation
	validateSelfregistrationPassword(user, &result)

	return result
}
