package account

import (
	"errors"
	"regexp"
	"testing"
)

func TestNormalizeEmail(t *testing.T) {
	tests := []struct {
		name    string
		in      string
		want    string
		wantErr bool
	}{
		{"lowercases", "User@Example.COM", "user@example.com", false},
		{"trims", "  a@b.io  ", "a@b.io", false},
		{"strips display name", "Jane Doe <jane@x.org>", "jane@x.org", false},
		{"empty", "", "", true},
		{"no at sign", "notanemail", "", true},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			got, err := normalizeEmail(tc.in)
			if tc.wantErr {
				if !errors.Is(err, ErrInvalidEmail) {
					t.Fatalf("err = %v, want ErrInvalidEmail", err)
				}
				return
			}
			if err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
			if got != tc.want {
				t.Errorf("got %q, want %q", got, tc.want)
			}
		})
	}
}

func TestGenerateCodeFormat(t *testing.T) {
	sixDigits := regexp.MustCompile(`^\d{6}$`)
	for range 50 {
		code, hash, err := generateCode()
		if err != nil {
			t.Fatalf("generate: %v", err)
		}
		if !sixDigits.MatchString(code) {
			t.Fatalf("code %q is not exactly six digits", code)
		}
		if hash != hashCode(code) {
			t.Errorf("returned hash does not match hashCode(%q)", code)
		}
	}
}

func TestHashCodeStable(t *testing.T) {
	if hashCode("123456") != hashCode("123456") {
		t.Fatal("hashCode is not deterministic")
	}
	if hashCode("123456") == hashCode("654321") {
		t.Fatal("distinct codes must not share a hash")
	}
	if got := len(hashCode("000000")); got != 64 {
		t.Errorf("hex SHA-256 length = %d, want 64", got)
	}
}
