package usecase

import (
	"context"
	"errors"
	"testing"

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

type demandMapProducts struct{ product *ProductCatalogProduct }

func (s demandMapProducts) GetBrand(context.Context, int64, string) (*ProductBrand, error) {
	return nil, domain.ErrNotFound
}
func (s demandMapProducts) GetProduct(_ context.Context, ownerUID int64, id string) (*ProductCatalogProduct, error) {
	if s.product == nil || s.product.OwnerUID != ownerUID || s.product.ID != id {
		return nil, domain.ErrNotFound
	}
	return s.product, nil
}

func TestDemandMapBaselineAndOptimisticVersion(t *testing.T) {
	const owner = int64(42)
	repo := repository.NewMemory()
	svc := New(repo)
	svc.ProductSource = demandMapProducts{product: &ProductCatalogProduct{
		ID: "p1", OwnerUID: owner, Label: "舒緩精華", ProductContext: "換季日常修護",
		PainPoints: []string{"泛紅不適"}, MatchTags: []string{"舒緩保濕"},
		ProviderCapabilityTerms: []string{"修護"}, UpdatedAt: 7,
	}}
	first, err := svc.GetDemandMap(context.Background(), owner, "p1")
	if err != nil {
		t.Fatal(err)
	}
	if first.State != "ready" || first.MapVersion != 1 || len(first.DemandInputVersion) != len("demand-")+16 {
		t.Fatalf("unexpected baseline: %+v", first)
	}
	for _, p := range append(append([]domain.DemandMapPhrase{}, first.PainPhrases...), append(first.ScenarioPhrases, first.SolutionSignals...)...) {
		if !domain.IsThreadsSearchable(p.Text) {
			t.Fatalf("baseline phrase %q is not searchable", p.Text)
		}
	}
	first.PainPhrases[0].Text = "新的痛點"
	updated, err := svc.UpdateDemandMap(context.Background(), owner, first, 1)
	if err != nil {
		t.Fatal(err)
	}
	if updated.MapVersion != 2 || updated.PainPhrases[0].Text != "新的痛點" {
		t.Fatalf("unexpected update: %+v", updated)
	}
	if _, err := svc.UpdateDemandMap(context.Background(), owner, first, 1); !errors.Is(err, domain.ErrConflict) {
		t.Fatalf("stale update must conflict, got %v", err)
	}
}

func TestDemandMapBaselineIncomplete(t *testing.T) {
	repo := repository.NewMemory()
	svc := New(repo)
	svc.ProductSource = demandMapProducts{product: &ProductCatalogProduct{ID: "p2", OwnerUID: 42, Label: "服務", PainPoints: []string{"等待太久"}, UpdatedAt: 1}}
	m, err := svc.GetDemandMap(context.Background(), 42, "p2")
	if err != nil {
		t.Fatal(err)
	}
	if m.State != "incomplete" {
		t.Fatalf("expected incomplete baseline, got %q", m.State)
	}
}
