package routingcodes

import (
	"testing"

	"github.com/niels/banking-app/backend/internal/domain"
)

func TestNormalizeAndValidateRoutingCodes(t *testing.T) {
	t.Parallel()

	codes, err := NormalizeAndValidate([]domain.RoutingCode{
		{CodeType: "aba_routing_number", Country: "us", Network: "ach", Code: "011000015"},
		{CodeType: "sort_code", Country: "gb", Network: "fps", Code: "123456"},
		{CodeType: "bank_code", Country: "nl", Network: "sepa", Code: "swfn"},
	})
	if err != nil {
		t.Fatalf("valid routing codes rejected: %v", err)
	}
	if codes[0].Country != "US" || codes[0].Code != "011000015" {
		t.Fatalf("unexpected ABA normalization: %+v", codes[0])
	}
	if codes[1].Code != "12-34-56" {
		t.Fatalf("unexpected sort code normalization: %+v", codes[1])
	}
	if codes[2].Code != "SWFN" {
		t.Fatalf("unexpected bank code normalization: %+v", codes[2])
	}
}

func TestNormalizeAndValidateRejectsInvalidABAChecksum(t *testing.T) {
	t.Parallel()

	_, err := NormalizeAndValidate([]domain.RoutingCode{
		{CodeType: "aba_routing_number", Country: "US", Network: "ach", Code: "011000016"},
	})
	if err == nil {
		t.Fatal("expected invalid ABA checksum to fail")
	}
}

func TestNormalizeAndValidateRejectsDuplicates(t *testing.T) {
	t.Parallel()

	_, err := NormalizeAndValidate([]domain.RoutingCode{
		{CodeType: "bank_code", Country: "NL", Network: "sepa", Code: "SWFN"},
		{CodeType: "bank_code", Country: "nl", Network: "sepa", Code: "swfn"},
	})
	if err == nil {
		t.Fatal("expected duplicate routing code to fail")
	}
}

func TestInferFromIBANAddsDutchSEPABankCode(t *testing.T) {
	t.Parallel()

	codes := InferFromIBAN("NL88 SWFN 1234 5678 90")
	if len(codes) != 1 {
		t.Fatalf("expected one inferred code, got %d", len(codes))
	}
	if code := codes[0]; code.CodeType != TypeBankCode || code.Country != "NL" || code.Network != "sepa" || code.Code != "SWFN" {
		t.Fatalf("unexpected inferred code: %+v", code)
	}
}

func TestMergeInferredDoesNotDuplicateExistingRouteType(t *testing.T) {
	t.Parallel()

	merged := MergeInferred(
		[]domain.RoutingCode{{CodeType: "bank_code", Country: "nl", Network: "sepa", Code: "ABCD"}},
		[]domain.RoutingCode{{CodeType: TypeBankCode, Country: "NL", Network: "sepa", Code: "SWFN"}},
	)
	if len(merged) != 1 {
		t.Fatalf("expected explicit code to win, got %+v", merged)
	}
	if merged[0].Code != "ABCD" {
		t.Fatalf("unexpected merged code: %+v", merged[0])
	}
}
