package routingcodes

import (
	"strings"
	"testing"
	"time"
)

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

	params, err := NormalizeRequirementParams(RequirementParams{
		Provider:    "Provider-US-ACH",
		Country:     "us",
		Network:     "ACH",
		CodeType:    TypeABARoutingNumber,
		Required:    true,
		Active:      true,
		Description: " US ACH contract rule ",
	})
	if err != nil {
		t.Fatalf("valid requirement rejected: %v", err)
	}

	if params.Provider != "provider-us-ach" {
		t.Fatalf("unexpected provider normalization: %q", params.Provider)
	}
	if params.Country != "US" || params.Network != "ach" || params.Currency != "*" {
		t.Fatalf("unexpected route normalization: %+v", params)
	}
	if params.RuleSource != RuleSourceProviderContract || params.ApprovalStatus != ApprovalStatusDraft {
		t.Fatalf("unexpected defaults: %+v", params)
	}
	if string(params.Metadata) != "{}" {
		t.Fatalf("unexpected default metadata: %s", string(params.Metadata))
	}
}

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

	_, err := NormalizeRequirementParams(RequirementParams{
		Provider:       "provider_us_ach",
		Country:        "US",
		Network:        "ach",
		Currency:       "USD",
		CodeType:       TypeABARoutingNumber,
		RuleSource:     RuleSourceProviderContract,
		ApprovalStatus: ApprovalStatusApproved,
	})
	if err == nil {
		t.Fatal("expected missing contract_reference to fail")
	}
	if !strings.Contains(err.Error(), "contract_reference") {
		t.Fatalf("unexpected error: %v", err)
	}
}

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

	params, err := NormalizeRequirementParams(RequirementParams{
		Provider:          "provider_us_ach",
		Country:           "US",
		Network:           "ach",
		Currency:          "USD",
		CodeType:          TypeABARoutingNumber,
		RuleSource:        RuleSourceProviderContract,
		ContractReference: "signed-ach-contract-2026",
		ApprovalStatus:    ApprovalStatusApproved,
	})
	if err != nil {
		t.Fatalf("approved requirement rejected: %v", err)
	}
	if params.EffectiveFrom == "" {
		t.Fatal("expected effective_from default")
	}
	if _, err := time.Parse(time.DateOnly, params.EffectiveFrom); err != nil {
		t.Fatalf("invalid effective_from default: %v", err)
	}
}

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

	_, err := NormalizeRequirementParams(RequirementParams{
		Provider:      "provider_gb_fps",
		Country:       "GB",
		Network:       "fps",
		Currency:      "GBP",
		CodeType:      TypeSortCode,
		EffectiveFrom: "2026-06-10",
		EffectiveTo:   "2026-06-09",
	})
	if err == nil {
		t.Fatal("expected invalid effective range to fail")
	}
}

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

	_, err := NormalizeRequirementParams(RequirementParams{
		Provider: "provider_gb_fps",
		Country:  "GB",
		Network:  "fps",
		Currency: "GBP",
		CodeType: TypeSortCode,
		Metadata: []byte("{"),
	})
	if err == nil {
		t.Fatal("expected invalid metadata to fail")
	}
}
