package usecase

import (
	"context"
	"testing"

	"haixun-backend/internal/model/brand/domain/entity"
	domusecase "haixun-backend/internal/model/brand/domain/usecase"
)

type memoryBrandRepo struct {
	brand *entity.Brand
}

func (m *memoryBrandRepo) Create(ctx context.Context, brand *entity.Brand) (*entity.Brand, error) {
	m.brand = brand
	return brand, nil
}

func (m *memoryBrandRepo) FindByID(ctx context.Context, tenantID, ownerUID, brandID string) (*entity.Brand, error) {
	return m.brand, nil
}

func (m *memoryBrandRepo) ListByOwner(ctx context.Context, tenantID, ownerUID string) ([]*entity.Brand, error) {
	return nil, nil
}

func (m *memoryBrandRepo) Update(ctx context.Context, tenantID, ownerUID, brandID string, patch map[string]interface{}) (*entity.Brand, error) {
	return m.brand, nil
}

func (m *memoryBrandRepo) SoftDelete(ctx context.Context, tenantID, ownerUID, brandID string) error {
	return nil
}

func (m *memoryBrandRepo) PushProduct(ctx context.Context, tenantID, ownerUID, brandID string, product entity.Product) (*entity.Product, error) {
	m.brand.Products = append(m.brand.Products, product)
	return &product, nil
}

func (m *memoryBrandRepo) UpdateProduct(ctx context.Context, tenantID, ownerUID, brandID, productID string, patch map[string]interface{}) (*entity.Product, error) {
	for i := range m.brand.Products {
		if m.brand.Products[i].ID != productID {
			continue
		}
		if v, ok := patch["products.$.label"].(string); ok {
			m.brand.Products[i].Label = v
		}
		if v, ok := patch["products.$.product_context"].(string); ok {
			m.brand.Products[i].ProductContext = v
		}
		if v, ok := patch["products.$.placement_url"].(string); ok {
			m.brand.Products[i].PlacementURL = v
		}
		item := m.brand.Products[i]
		return &item, nil
	}
	return nil, nil
}

func (m *memoryBrandRepo) PullProduct(ctx context.Context, tenantID, ownerUID, brandID, productID string) error {
	return nil
}

func (m *memoryBrandRepo) EnsureIndexes(ctx context.Context) error {
	return nil
}

func TestCreateAndUpdateProductPlacementURL(t *testing.T) {
	repo := &memoryBrandRepo{
		brand: &entity.Brand{
			ID:       "brand-1",
			TenantID: "tenant-1",
			OwnerUID: "user-1",
			Status:   entity.StatusOpen,
		},
	}
	uc := NewUseCase(repo)
	ctx := context.Background()

	created, err := uc.CreateProduct(ctx, domusecase.CreateProductRequest{
		TenantID:       "tenant-1",
		OwnerUID:       "user-1",
		BrandID:        "brand-1",
		Label:          "主力商品",
		ProductContext: "賣點描述",
		PlacementURL:   "https://example.com/product",
	})
	if err != nil {
		t.Fatal(err)
	}
	if created.PlacementURL != "https://example.com/product" {
		t.Fatalf("create placement_url = %q", created.PlacementURL)
	}

	label := "主力商品"
	contextRaw := "賣點描述"
	placementURL := "https://example.com/updated"
	updated, err := uc.UpdateProduct(ctx, domusecase.UpdateProductRequest{
		TenantID:        "tenant-1",
		OwnerUID:        "user-1",
		BrandID:         "brand-1",
		ProductID:       created.ID,
		Label:           &label,
		ProductContext:  &contextRaw,
		PlacementURL:    &placementURL,
		PlacementURLSet: true,
	})
	if err != nil {
		t.Fatal(err)
	}
	if updated.PlacementURL != placementURL {
		t.Fatalf("update placement_url = %q, want %q", updated.PlacementURL, placementURL)
	}
}
