package usecase

import (
	"context"
	"errors"
	"testing"

	"apps/backend/internal/module/radar/domain"
	"apps/backend/internal/module/radar/repository"
)

func TestSetPrimaryProductRequiresMatchAndReasonForWeak(t *testing.T) {
	ctx := context.Background()
	svc := New(repository.NewMemory())
	op, err := svc.Repo.UpsertByExternalID(ctx, integrationOpportunity(42))
	if err != nil {
		t.Fatal(err)
	}
	weak := &domain.ProductMatch{BrandID: "b", ProductID: "weak", ProductFitScore: 0, ProductFitBand: domain.ProductFitBandWeak, Reasons: []domain.ProductFitReason{{Dimension: domain.ProductFitPain, Reason: "none"}, {Dimension: domain.ProductFitScenario, Reason: "none"}, {Dimension: domain.ProductFitAudience, Reason: "none"}, {Dimension: domain.ProductFitCapability, Reason: "none"}}}
	if _, err := svc.Repo.MergeProductMatch(ctx, 42, op.ID, weak); err != nil {
		t.Fatal(err)
	}
	if _, err := svc.SetPrimaryProduct(ctx, 42, op.ID, "missing", "no"); !errors.Is(err, domain.ErrValidation) {
		t.Fatalf("missing match err=%v", err)
	}
	if _, err := svc.SetPrimaryProduct(ctx, 42, op.ID, "weak", ""); !errors.Is(err, domain.ErrValidation) {
		t.Fatalf("missing reason err=%v", err)
	}
	selected, err := svc.SetPrimaryProduct(ctx, 42, op.ID, "weak", "人工確認特殊情境")
	if err != nil {
		t.Fatal(err)
	}
	if selected.PrimaryProductID != "weak" || !selected.PrimaryProductOverridden || selected.PrimaryProductOverride == nil || selected.PrimaryProductOverride.ActorUID != 42 {
		t.Fatalf("override audit missing: %+v", selected)
	}
}

func TestSetPrimaryProductOverrideSurvivesFutureHigherMerge(t *testing.T) {
	ctx := context.Background()
	svc := New(repository.NewMemory())
	op, err := svc.Repo.UpsertByExternalID(ctx, integrationOpportunity(42))
	if err != nil {
		t.Fatal(err)
	}
	if _, err := svc.Repo.MergeProductMatch(ctx, 42, op.ID, integrationMatch("p1", 60)); err != nil {
		t.Fatal(err)
	}
	if _, err := svc.Repo.MergeProductMatch(ctx, 42, op.ID, integrationMatch("p2", 80)); err != nil {
		t.Fatal(err)
	}
	if _, err := svc.SetPrimaryProduct(ctx, 42, op.ID, "p1", "客戶已指定"); err != nil {
		t.Fatal(err)
	}
	if _, err := svc.Repo.MergeProductMatch(ctx, 42, op.ID, integrationMatch("p3", 100)); err != nil {
		t.Fatal(err)
	}
	got, err := svc.GetOpportunity(ctx, 42, op.ID)
	if err != nil {
		t.Fatal(err)
	}
	if got.PrimaryProductID != "p1" || !got.PrimaryProductOverridden {
		t.Fatalf("future merge replaced override: %+v", got)
	}
}
