package chat

import (
	"testing"
	"time"

	"hfb_sys/backend/internal/model"

	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

func setupConversationTestDB(t *testing.T) *gorm.DB {
	t.Helper()
	db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Silent),
	})
	if err != nil {
		t.Fatalf("无法创建测试数据库: %v", err)
	}
	if err := db.AutoMigrate(
		&model.User{},
		&model.RentalOrder{},
		&model.ChatConversation{},
		&model.ChatParticipant{},
		&model.ChatMessage{},
	); err != nil {
		t.Fatalf("数据库迁移失败: %v", err)
	}
	return db
}

func TestFindOrderConversationPrefersListingGroup(t *testing.T) {
	db := setupConversationTestDB(t)
	repo := NewRepository(db, nil, nil)
	now := time.Date(2026, 6, 18, 12, 0, 0, 0, time.UTC)

	owner := model.User{Phone: "13800001001", Nickname: "号主"}
	renter := model.User{Phone: "13800001002", Nickname: "租客"}
	if err := db.Create(&owner).Error; err != nil {
		t.Fatalf("创建号主失败: %v", err)
	}
	if err := db.Create(&renter).Error; err != nil {
		t.Fatalf("创建租客失败: %v", err)
	}

	order := model.RentalOrder{
		OrderNo:   "ORDER-LISTING-GROUP",
		ListingID: 101,
		AccountID: 201,
		OwnerID:   owner.ID,
		RenterID:  renter.ID,
		Status:    "renting",
	}
	if err := db.Create(&order).Error; err != nil {
		t.Fatalf("创建订单失败: %v", err)
	}
	orderConv := model.ChatConversation{
		OrderID: &order.ID,
		Type:    ConversationTypeOrderGroup,
		Title:   "旧订单群",
		Status:  "active",
	}
	listingConv := model.ChatConversation{
		ListingID: &order.ListingID,
		Type:      ConversationTypeListingGroup,
		Title:     "发布群",
		Status:    "active",
	}
	if err := db.Create(&orderConv).Error; err != nil {
		t.Fatalf("创建订单群失败: %v", err)
	}
	if err := db.Create(&listingConv).Error; err != nil {
		t.Fatalf("创建发布群失败: %v", err)
	}
	participants := []model.ChatParticipant{
		{ConversationID: orderConv.ID, ParticipantType: "user", ParticipantID: order.RenterID, Role: "renter", JoinedAt: now},
		{ConversationID: listingConv.ID, ParticipantType: "user", ParticipantID: order.RenterID, Role: "renter", JoinedAt: now},
	}
	if err := db.Create(&participants).Error; err != nil {
		t.Fatalf("创建成员失败: %v", err)
	}

	dto, err := repo.FindOrderConversation(t.Context(), order.RenterID, order.ID)
	if err != nil {
		t.Fatalf("查询订单会话失败: %v", err)
	}
	if dto.ID != listingConv.ID {
		t.Fatalf("会话 ID = %d, want 发布群 %d", dto.ID, listingConv.ID)
	}
	if dto.Type != ConversationTypeListingGroup {
		t.Fatalf("会话类型 = %q, want %q", dto.Type, ConversationTypeListingGroup)
	}
}

func TestFindOrderConversationFallsBackToOrderGroup(t *testing.T) {
	db := setupConversationTestDB(t)
	repo := NewRepository(db, nil, nil)
	now := time.Date(2026, 6, 18, 12, 0, 0, 0, time.UTC)

	owner := model.User{Phone: "13800001003", Nickname: "号主"}
	renter := model.User{Phone: "13800001004", Nickname: "租客"}
	if err := db.Create(&owner).Error; err != nil {
		t.Fatalf("创建号主失败: %v", err)
	}
	if err := db.Create(&renter).Error; err != nil {
		t.Fatalf("创建租客失败: %v", err)
	}

	order := model.RentalOrder{
		OrderNo:   "ORDER-LEGACY-GROUP",
		ListingID: 102,
		AccountID: 202,
		OwnerID:   owner.ID,
		RenterID:  renter.ID,
		Status:    "renting",
	}
	if err := db.Create(&order).Error; err != nil {
		t.Fatalf("创建订单失败: %v", err)
	}
	orderConv := model.ChatConversation{
		OrderID: &order.ID,
		Type:    ConversationTypeOrderGroup,
		Title:   "旧订单群",
		Status:  "active",
	}
	if err := db.Create(&orderConv).Error; err != nil {
		t.Fatalf("创建订单群失败: %v", err)
	}
	participant := model.ChatParticipant{
		ConversationID:  orderConv.ID,
		ParticipantType: "user",
		ParticipantID:   order.RenterID,
		Role:            "renter",
		JoinedAt:        now,
	}
	if err := db.Create(&participant).Error; err != nil {
		t.Fatalf("创建成员失败: %v", err)
	}

	dto, err := repo.FindOrderConversation(t.Context(), order.RenterID, order.ID)
	if err != nil {
		t.Fatalf("查询订单会话失败: %v", err)
	}
	if dto.ID != orderConv.ID {
		t.Fatalf("会话 ID = %d, want 订单群 %d", dto.ID, orderConv.ID)
	}
	if dto.Type != ConversationTypeOrderGroup {
		t.Fatalf("会话类型 = %q, want %q", dto.Type, ConversationTypeOrderGroup)
	}
}
