package repository

import (
	"context"
	"fmt"
	"sync/atomic"
	"testing"
	"time"

	gormsqlite "gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	_ "modernc.org/sqlite"

	"github.com/user-management-system/internal/domain"
	"github.com/user-management-system/internal/pagination"
)

var operationLogTestCounter int64

func openOperationLogTestDB(t *testing.T) *gorm.DB {
	t.Helper()

	id := atomic.AddInt64(&operationLogTestCounter, 1)
	dsn := fmt.Sprintf("file:operationlogtestdb%d?mode=memory&cache=private", id)

	db, err := gorm.Open(gormsqlite.New(gormsqlite.Config{
		DriverName: "sqlite",
		DSN:        dsn,
	}), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Silent),
	})
	if err != nil {
		t.Fatalf("打开测试数据库失败: %v", err)
	}

	if err := db.AutoMigrate(&domain.OperationLog{}); err != nil {
		t.Fatalf("数据库迁移失败: %v", err)
	}
	return db
}

func setupOperationLogTestDB(t *testing.T) *gorm.DB {
	return openOperationLogTestDB(t)
}

func TestOperationLogRepository_ListCursor(t *testing.T) {
	db := setupOperationLogTestDB(t)
	repo := NewOperationLogRepository(db)
	ctx := context.Background()

	now := time.Now()
	for i := 0; i < 5; i++ {
		repo.Create(ctx, &domain.OperationLog{
			UserID:         nil,
			OperationType:  "test",
			OperationName:  "测试操作" + string(rune('0'+i)),
			RequestMethod:  "GET",
			RequestPath:    "/api/test",
			ResponseStatus: 200,
			IP:             "192.168.1." + string(rune('0'+i)),
			CreatedAt:      now.Add(-time.Duration(i) * time.Minute),
		})
	}

	// 第一次查询，获取前3个
	logs, hasMore, err := repo.ListCursor(ctx, 3, nil)
	if err != nil {
		t.Fatalf("ListCursor() error = %v", err)
	}
	if len(logs) != 3 {
		t.Errorf("len(logs) = %d, want 3", len(logs))
	}
	if !hasMore {
		t.Error("hasMore should be true when more logs exist")
	}

	// 使用游标继续查询
	lastLog := logs[len(logs)-1]
	cursor := &pagination.Cursor{
		LastID:    lastLog.ID,
		LastValue: lastLog.CreatedAt,
	}
	logs2, hasMore2, err := repo.ListCursor(ctx, 3, cursor)
	if err != nil {
		t.Fatalf("ListCursor() error = %v", err)
	}
	if len(logs2) != 2 {
		t.Errorf("len(logs2) = %d, want 2", len(logs2))
	}
	if hasMore2 {
		t.Error("hasMore2 should be false")
	}
}
