package usecase

import (
	"errors"

	"golang.org/x/crypto/bcrypt"
)

// ErrInvalidPassword is returned when password validation fails
var ErrInvalidPassword = errors.New("invalid password")

// HashPassword generates a bcrypt hash from the given password with the specified cost.
// The cost parameter should be between 4 and 31, with higher values being more secure but slower.
func HashPassword(password string, cost int) (string, error) {
	if password == "" {
		return "", ErrInvalidPassword
	}

	if cost < bcrypt.MinCost || cost > bcrypt.MaxCost {
		cost = bcrypt.DefaultCost
	}

	bytes, err := bcrypt.GenerateFromPassword([]byte(password), cost)
	return string(bytes), err
}

// CheckPasswordHash compares a password with its bcrypt hash.
// Returns true if the password matches the hash, false otherwise.
func CheckPasswordHash(password, hash string) bool {
	if password == "" || hash == "" {
		return false
	}

	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
	return err == nil
}

// GetHashingCost extracts the cost parameter from a bcrypt hash.
// Returns the cost used to generate the hash, or 0 if the hash is invalid.
func GetHashingCost(hashedPassword []byte) int {
	if len(hashedPassword) == 0 {
		return 0
	}

	cost, err := bcrypt.Cost(hashedPassword)
	if err != nil {
		return 0
	}

	return cost
}
