package utils

import (
	"errors"
	"regexp"
)

var (
	ErrInvalidISBN = errors.New("ISBN must be 10 or 13 digits")
)

// NormalizeISBN removes hyphens and spaces from ISBN to standardize format
// Handles ISBN-10 and ISBN-13 formats
// Returns error if ISBN is not 10 or 13 digits after normalization
// Converts ISBN-10 to ISBN-13 by prefixing with "978" and recalculating checksum
func NormalizeISBN(isbn string) (string, error) {
	if isbn == "" {
		return "", nil
	}

	// Remove hyphens and spaces, return only digits and X (for ISBN-10)
	normalized := regexp.MustCompile(`[-\s]`).ReplaceAllString(isbn, "")

	// Check length: must be 10 or 13 digits
	length := len(normalized)
	if length == 10 {
		// Convert ISBN-10 to ISBN-13
		return convertISBN10To13(normalized)
	}
	if length == 13 {
		return normalized, nil
	}

	return "", ErrInvalidISBN
}

// NormalizeISBNSafe removes hyphens and spaces from ISBN without validation
// Used by scanners where metadata may be incomplete or malformed
func NormalizeISBNSafe(isbn string) string {
	if isbn == "" {
		return ""
	}

	// Remove hyphens and spaces, return only digits and X (for ISBN-10)
	return regexp.MustCompile(`[-\s]`).ReplaceAllString(isbn, "")
}

// convertISBN10To13 converts ISBN-10 to ISBN-13 by prefixing "978" and recalculating checksum
func convertISBN10To13(isbn10 string) (string, error) {
	// ISBN-10 to ISBN-13: prefix "978" and recalculate checksum
	// Replace last digit (X becomes 0 for calculation purposes)
	isbn12 := "978" + isbn10[:9]

	// Calculate ISBN-13 checksum
	sum := 0
	for i := 0; i < 12; i++ {
		digit := int(isbn12[i] - '0')
		if i%2 == 0 {
			sum += digit * 1
		} else {
			sum += digit * 3
		}
	}
	checksum := (10 - (sum % 10)) % 10

	return isbn12 + string(rune('0'+checksum)), nil
}
