package repository

import (
	"backend/pkg/chat/domain/chat"
	"backend/pkg/chat/domain/entity"
	"backend/pkg/chat/domain/repository"
	"backend/pkg/library/cassandra"
	"context"
	"strconv"
	"testing"
	"time"

	"github.com/gocql/gocql"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

var (
	// 全局變量：所有測試共享的資源（與 message_test.go 共享）
	roomTestRepo repository.RoomRepository
)

// ensureRoomRepository 確保 Room Repository 已初始化
func ensureRoomRepository(t *testing.T) {
	if roomTestRepo == nil {
		if testDB == nil {
			t.Fatal("testDB is not initialized. Make sure TestMain in message_test.go runs first.")
		}
		var err error
		roomTestRepo, err = NewRoomRepository(testDB, "test_keyspace")
		if err != nil {
			t.Fatalf("Failed to create room repository: %v", err)
		}
	}
}

// clearRoomData 清空所有 room 相關表的數據
func clearRoomData(t *testing.T) {
	ctx := context.Background()
	tables := []string{"user_room", "room_member", "room"}
	for _, table := range tables {
		truncateStmt := "TRUNCATE test_keyspace." + table
		if err := testDB.GetSession().Query(truncateStmt, nil).WithContext(ctx).Exec(); err != nil {
			t.Fatalf("Failed to truncate %s table: %v", table, err)
		}
	}
	// 等待數據清空
	time.Sleep(50 * time.Millisecond)
}

// ==================== Room Interface 測試 ====================

func TestNewRoomRepository(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	assert.NotNil(t, roomTestRepo)
}

func TestRoomRepository_Create(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	tests := []struct {
		name    string
		room    *entity.Room
		wantErr bool
	}{
		{
			name: "successful create",
			room: &entity.Room{
				Name:   "Test Room",
				Status: "active",
			},
			wantErr: false,
		},
		{
			name: "create with auto timestamp",
			room: &entity.Room{
				Name:   "Auto Timestamp Room",
				Status: "active",
			},
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			err := roomTestRepo.Create(ctx, tt.room)
			if tt.wantErr {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
				// 驗證 RoomID 和時間戳是否被自動設置
				assert.NotZero(t, tt.room.RoomID)
				assert.NotZero(t, tt.room.CreatedAt)
				assert.NotZero(t, tt.room.UpdatedAt)
			}
		})
	}
}

func TestRoomRepository_RoomGet(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	room := &entity.Room{
		Name:   "Get Test Room",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))
	roomIDStr := room.RoomID.String()

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	tests := []struct {
		name    string
		roomID  string
		wantErr bool
	}{
		{
			name:    "get existing room",
			roomID:  roomIDStr,
			wantErr: false,
		},
		{
			name:    "get non-existent room",
			roomID:  gocql.TimeUUID().String(),
			wantErr: true,
		},
		{
			name:    "get with invalid UUID",
			roomID:  "invalid-uuid",
			wantErr: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := roomTestRepo.RoomGet(ctx, tt.roomID)
			if tt.wantErr {
				assert.Error(t, err)
				assert.Nil(t, result)
			} else {
				assert.NoError(t, err)
				assert.NotNil(t, result)
				assert.Equal(t, room.Name, result.Name)
				assert.Equal(t, room.Status, result.Status)
			}
		})
	}
}

func TestRoomRepository_RoomUpdate(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	room := &entity.Room{
		Name:   "Original Name",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))
	originalCreatedAt := room.CreatedAt

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	// 更新房間
	room.Name = "Updated Name"
	room.Status = "archived"
	err := roomTestRepo.RoomUpdate(ctx, room)
	require.NoError(t, err)

	// 驗證更新
	updated, err := roomTestRepo.RoomGet(ctx, room.RoomID.String())
	require.NoError(t, err)
	assert.Equal(t, "Updated Name", updated.Name)
	assert.Equal(t, "archived", updated.Status)
	assert.Equal(t, originalCreatedAt, updated.CreatedAt) // CreatedAt 不應該改變
	assert.Greater(t, updated.UpdatedAt, originalCreatedAt) // UpdatedAt 應該更新
}

func TestRoomRepository_RoomDelete(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	room := &entity.Room{
		Name:   "Delete Test Room",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))
	roomIDStr := room.RoomID.String()

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	// 刪除房間
	err := roomTestRepo.RoomDelete(ctx, roomIDStr)
	require.NoError(t, err)

	// 驗證房間已被刪除
	_, err = roomTestRepo.RoomGet(ctx, roomIDStr)
	assert.Error(t, err)
	assert.True(t, cassandra.IsNotFound(err))
}

func TestRoomRepository_RoomList(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建多個測試房間
	rooms := make([]*entity.Room, 5)
	for i := 0; i < 5; i++ {
		room := &entity.Room{
			Name:   "Room " + strconv.Itoa(i),
			Status: "active",
		}
		require.NoError(t, roomTestRepo.Create(ctx, room))
		rooms[i] = room
		time.Sleep(10 * time.Millisecond) // 確保時間戳不同
	}

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	tests := []struct {
		name    string
		param   repository.ListRoomsReq
		wantLen int
		wantErr bool
	}{
		{
			name: "list all rooms",
			param: repository.ListRoomsReq{
				PageSize: 10,
			},
			wantLen: 5,
			wantErr: false,
		},
		{
			name: "list with status filter",
			param: repository.ListRoomsReq{
				Status:   "active",
				PageSize: 10,
			},
			wantLen: 5,
			wantErr: false,
		},
		{
			name: "list with page size limit",
			param: repository.ListRoomsReq{
				PageSize: 2,
			},
			wantLen: 2,
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := roomTestRepo.RoomList(ctx, tt.param)
			if tt.wantErr {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
				assert.Len(t, result, tt.wantLen)
			}
		})
	}
}

func TestRoomRepository_RoomCount(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	for i := 0; i < 3; i++ {
		room := &entity.Room{
			Name:   "Count Room " + strconv.Itoa(i),
			Status: "active",
		}
		require.NoError(t, roomTestRepo.Create(ctx, room))
	}

	// 創建一個 archived 房間
	archivedRoom := &entity.Room{
		Name:   "Archived Room",
		Status: "archived",
	}
	require.NoError(t, roomTestRepo.Create(ctx, archivedRoom))

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	tests := []struct {
		name    string
		param   repository.CountRoomsReq
		want    int64
		wantErr bool
	}{
		{
			name: "count all rooms",
			param: repository.CountRoomsReq{},
			want:  4,
		},
		{
			name: "count active rooms",
			param: repository.CountRoomsReq{
				Status: "active",
			},
			want: 3,
		},
		{
			name: "count archived rooms",
			param: repository.CountRoomsReq{
				Status: "archived",
			},
			want: 1,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			count, err := roomTestRepo.RoomCount(ctx, tt.param)
			if tt.wantErr {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
				assert.Equal(t, tt.want, count)
			}
		})
	}
}

func TestRoomRepository_RoomExists(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	room := &entity.Room{
		Name:   "Exists Test Room",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))
	roomIDStr := room.RoomID.String()
	nonExistentID := gocql.TimeUUID().String()

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	tests := []struct {
		name    string
		roomID  string
		want    bool
		wantErr bool
	}{
		{
			name:    "existing room",
			roomID:  roomIDStr,
			want:    true,
			wantErr: false,
		},
		{
			name:    "non-existent room",
			roomID:  nonExistentID,
			want:    false,
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			exists, err := roomTestRepo.RoomExists(ctx, tt.roomID)
			if tt.wantErr {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
				assert.Equal(t, tt.want, exists)
			}
		})
	}
}

func TestRoomRepository_RoomGetByID(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建多個測試房間
	rooms := make([]*entity.Room, 3)
	roomIDs := make([]string, 3)
	for i := 0; i < 3; i++ {
		room := &entity.Room{
			Name:   "Room " + strconv.Itoa(i),
			Status: "active",
		}
		require.NoError(t, roomTestRepo.Create(ctx, room))
		rooms[i] = room
		roomIDs[i] = room.RoomID.String()
	}

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	tests := []struct {
		name    string
		roomIDs []string
		wantLen int
		wantErr bool
	}{
		{
			name:    "get multiple rooms",
			roomIDs: roomIDs,
			wantLen: 3,
			wantErr: false,
		},
		{
			name:    "get empty list",
			roomIDs: []string{},
			wantLen: 0,
			wantErr: false,
		},
		{
			name:    "get with non-existent ID",
			roomIDs: []string{roomIDs[0], gocql.TimeUUID().String()},
			wantLen: 1, // 只返回存在的房間
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := roomTestRepo.RoomGetByID(ctx, tt.roomIDs)
			if tt.wantErr {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
				assert.Len(t, result, tt.wantLen)
			}
		})
	}
}

// ==================== Member Interface 測試 ====================

func TestRoomRepository_Insert(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	room := &entity.Room{
		Name:   "Member Test Room",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))

	tests := []struct {
		name    string
		member  *entity.RoomMember
		wantErr bool
	}{
		{
			name: "successful insert",
			member: &entity.RoomMember{
				RoomID: room.RoomID,
				UID:    "user-1",
				Role:   chat.RoomRoleMember.String(),
			},
			wantErr: false,
		},
		{
			name: "insert with auto role",
			member: &entity.RoomMember{
				RoomID: room.RoomID,
				UID:    "user-2",
			},
			wantErr: false,
		},
		{
			name: "insert with admin role",
			member: &entity.RoomMember{
				RoomID: room.RoomID,
				UID:    "user-3",
				Role:   chat.RoomRoleAdmin.String(),
			},
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			err := roomTestRepo.Insert(ctx, tt.member)
			if tt.wantErr {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
				// 驗證 JoinedAt 是否被自動設置
				assert.NotZero(t, tt.member.JoinedAt)
				// 驗證 Role 是否被自動設置（如果為空）
				if tt.member.Role == "" {
					assert.Equal(t, chat.RoomRoleMember.String(), tt.member.Role)
				}

				// 驗證 user_room 表也被更新
				userRooms, err := roomTestRepo.GetUserRooms(ctx, tt.member.UID)
				require.NoError(t, err)
				assert.Greater(t, len(userRooms), 0)
			}
		})
	}
}

func TestRoomRepository_Get(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間和成員
	room := &entity.Room{
		Name:   "Get Member Test Room",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))

	member := &entity.RoomMember{
		RoomID: room.RoomID,
		UID:    "user-1",
		Role:   chat.RoomRoleAdmin.String(),
	}
	require.NoError(t, roomTestRepo.Insert(ctx, member))

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	tests := []struct {
		name    string
		roomID  string
		uid     string
		wantErr bool
	}{
		{
			name:    "get existing member",
			roomID:  room.RoomID.String(),
			uid:     "user-1",
			wantErr: false,
		},
		{
			name:    "get non-existent member",
			roomID:  room.RoomID.String(),
			uid:     "non-existent-user",
			wantErr: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := roomTestRepo.Get(ctx, tt.roomID, tt.uid)
			if tt.wantErr {
				assert.Error(t, err)
				assert.Nil(t, result)
			} else {
				assert.NoError(t, err)
				assert.NotNil(t, result)
				assert.Equal(t, member.UID, result.UID)
				assert.Equal(t, member.Role, result.Role)
			}
		})
	}
}

func TestRoomRepository_AllMembers(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	room := &entity.Room{
		Name:   "All Members Test Room",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))

	// 插入多個成員
	members := []*entity.RoomMember{
		{RoomID: room.RoomID, UID: "user-1", Role: chat.RoomRoleMember.String()},
		{RoomID: room.RoomID, UID: "user-2", Role: chat.RoomRoleAdmin.String()},
		{RoomID: room.RoomID, UID: "user-3", Role: chat.RoomRoleMember.String()},
	}

	for _, member := range members {
		require.NoError(t, roomTestRepo.Insert(ctx, member))
	}

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	// 查詢所有成員
	result, err := roomTestRepo.AllMembers(ctx, room.RoomID.String())
	require.NoError(t, err)
	assert.Len(t, result, 3)
}

func TestRoomRepository_UpdateRole(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間和成員
	room := &entity.Room{
		Name:   "Update Role Test Room",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))

	member := &entity.RoomMember{
		RoomID: room.RoomID,
		UID:    "user-1",
		Role:   chat.RoomRoleMember.String(),
	}
	require.NoError(t, roomTestRepo.Insert(ctx, member))

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	// 更新角色
	member.Role = chat.RoomRoleAdmin.String()
	err := roomTestRepo.UpdateRole(ctx, member)
	require.NoError(t, err)

	// 驗證更新
	updated, err := roomTestRepo.Get(ctx, room.RoomID.String(), "user-1")
	require.NoError(t, err)
	assert.Equal(t, chat.RoomRoleAdmin.String(), updated.Role)
}

func TestRoomRepository_DeleteMember(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間和成員
	room := &entity.Room{
		Name:   "Delete Member Test Room",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))

	member := &entity.RoomMember{
		RoomID: room.RoomID,
		UID:    "user-1",
		Role:   chat.RoomRoleMember.String(),
	}
	require.NoError(t, roomTestRepo.Insert(ctx, member))

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	// 刪除成員
	err := roomTestRepo.DeleteMember(ctx, room.RoomID.String(), "user-1")
	require.NoError(t, err)

	// 驗證成員已被刪除
	_, err = roomTestRepo.Get(ctx, room.RoomID.String(), "user-1")
	assert.Error(t, err)
	assert.True(t, cassandra.IsNotFound(err))

	// 驗證 user_room 表也被刪除
	userRooms, err := roomTestRepo.GetUserRooms(ctx, "user-1")
	require.NoError(t, err)
	assert.Len(t, userRooms, 0)
}

func TestRoomRepository_DeleteRoom(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	room := &entity.Room{
		Name:   "Delete Room Test",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))

	// 插入多個成員
	members := []*entity.RoomMember{
		{RoomID: room.RoomID, UID: "user-1", Role: chat.RoomRoleMember.String()},
		{RoomID: room.RoomID, UID: "user-2", Role: chat.RoomRoleAdmin.String()},
	}

	for _, member := range members {
		require.NoError(t, roomTestRepo.Insert(ctx, member))
	}

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	// 刪除整個房間
	err := roomTestRepo.DeleteRoom(ctx, room.RoomID.String())
	require.NoError(t, err)

	// 驗證所有成員已被刪除
	allMembers, err := roomTestRepo.AllMembers(ctx, room.RoomID.String())
	require.NoError(t, err)
	assert.Len(t, allMembers, 0)

	// 驗證 user_room 表中的關聯也被刪除
	for _, member := range members {
		userRooms, err := roomTestRepo.GetUserRooms(ctx, member.UID)
		require.NoError(t, err)
		// 驗證該用戶的 user_room 記錄中不包含這個房間
		found := false
		for _, ur := range userRooms {
			if ur.RoomID == room.RoomID {
				found = true
				break
			}
		}
		assert.False(t, found, "user_room should not contain deleted room")
	}
}

func TestRoomRepository_Count(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	room := &entity.Room{
		Name:   "Count Members Test Room",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))

	// 插入多個成員
	for i := 0; i < 5; i++ {
		member := &entity.RoomMember{
			RoomID: room.RoomID,
			UID:    "user-" + strconv.Itoa(i),
			Role:   chat.RoomRoleMember.String(),
		}
		require.NoError(t, roomTestRepo.Insert(ctx, member))
	}

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	// 計算成員數
	count, err := roomTestRepo.Count(ctx, room.RoomID.String())
	require.NoError(t, err)
	assert.Equal(t, int64(5), count)
}

// ==================== User Interface 測試 ====================

func TestRoomRepository_GetUserRooms(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建多個測試房間
	rooms := make([]*entity.Room, 3)
	for i := 0; i < 3; i++ {
		room := &entity.Room{
			Name:   "User Room " + strconv.Itoa(i),
			Status: "active",
		}
		require.NoError(t, roomTestRepo.Create(ctx, room))
		rooms[i] = room
	}

	// 將用戶加入多個房間
	uid := "user-1"
	for _, room := range rooms {
		member := &entity.RoomMember{
			RoomID: room.RoomID,
			UID:    uid,
			Role:   chat.RoomRoleMember.String(),
		}
		require.NoError(t, roomTestRepo.Insert(ctx, member))
	}

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	// 查詢用戶所在的所有房間
	userRooms, err := roomTestRepo.GetUserRooms(ctx, uid)
	require.NoError(t, err)
	assert.Len(t, userRooms, 3)
}

func TestRoomRepository_CountUserRooms(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	rooms := make([]*entity.Room, 5)
	for i := 0; i < 5; i++ {
		room := &entity.Room{
			Name:   "Count User Room " + strconv.Itoa(i),
			Status: "active",
		}
		require.NoError(t, roomTestRepo.Create(ctx, room))
		rooms[i] = room
	}

	// 將用戶加入多個房間
	uid := "user-1"
	for _, room := range rooms {
		member := &entity.RoomMember{
			RoomID: room.RoomID,
			UID:    uid,
			Role:   chat.RoomRoleMember.String(),
		}
		require.NoError(t, roomTestRepo.Insert(ctx, member))
	}

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	// 計算用戶所在的房間數
	count, err := roomTestRepo.CountUserRooms(ctx, uid)
	require.NoError(t, err)
	assert.Equal(t, int64(5), count)
}

func TestRoomRepository_IsUserInRoom(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建測試房間
	room := &entity.Room{
		Name:   "Is User In Room Test",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))

	// 插入成員
	member := &entity.RoomMember{
		RoomID: room.RoomID,
		UID:    "user-1",
		Role:   chat.RoomRoleMember.String(),
	}
	require.NoError(t, roomTestRepo.Insert(ctx, member))

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	tests := []struct {
		name    string
		uid     string
		roomID  string
		want    bool
		wantErr bool
	}{
		{
			name:    "user in room",
			uid:     "user-1",
			roomID:  room.RoomID.String(),
			want:    true,
			wantErr: false,
		},
		{
			name:    "user not in room",
			uid:     "user-2",
			roomID:  room.RoomID.String(),
			want:    false,
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := roomTestRepo.IsUserInRoom(ctx, tt.uid, tt.roomID)
			if tt.wantErr {
				assert.Error(t, err)
			} else {
				assert.NoError(t, err)
				assert.Equal(t, tt.want, result)
			}
		})
	}
}

// ==================== 整合測試 ====================

func TestRoomRepository_Integration(t *testing.T) {
	ensureRoomRepository(t)
	clearRoomData(t)
	ctx := context.Background()

	// 創建房間
	room := &entity.Room{
		Name:   "Integration Test Room",
		Status: "active",
	}
	require.NoError(t, roomTestRepo.Create(ctx, room))

	// 添加多個成員
	members := []*entity.RoomMember{
		{RoomID: room.RoomID, UID: "user-1", Role: chat.RoomRoleOwner.String()},
		{RoomID: room.RoomID, UID: "user-2", Role: chat.RoomRoleAdmin.String()},
		{RoomID: room.RoomID, UID: "user-3", Role: chat.RoomRoleMember.String()},
	}

	for _, member := range members {
		require.NoError(t, roomTestRepo.Insert(ctx, member))
	}

	// 等待數據寫入
	time.Sleep(100 * time.Millisecond)

	// 驗證房間存在
	exists, err := roomTestRepo.RoomExists(ctx, room.RoomID.String())
	require.NoError(t, err)
	assert.True(t, exists)

	// 驗證成員數量
	count, err := roomTestRepo.Count(ctx, room.RoomID.String())
	require.NoError(t, err)
	assert.Equal(t, int64(3), count)

	// 驗證所有成員
	allMembers, err := roomTestRepo.AllMembers(ctx, room.RoomID.String())
	require.NoError(t, err)
	assert.Len(t, allMembers, 3)

	// 驗證用戶所在的房間
	for _, member := range members {
		userRooms, err := roomTestRepo.GetUserRooms(ctx, member.UID)
		require.NoError(t, err)
		assert.Greater(t, len(userRooms), 0)

		inRoom, err := roomTestRepo.IsUserInRoom(ctx, member.UID, room.RoomID.String())
		require.NoError(t, err)
		assert.True(t, inRoom)
	}
}

