package services

import (
	"errors"
	"log"
	"sync"

	"gorm.io/gorm"

	"fafa-crawler/src/models"
)

// BulkInsertLibraryProducts 使用 CreateInBatches 并发插入 products。
// 参数：
// - db: gorm DB
// - products: 待插入记录切片
// - batchSize: 每个批次的记录数（<=0 则使用 1000）
// - workers: 并发 worker 数（<=0 则使用 4）
func BulkInsertLibraryProducts(db *gorm.DB, products []models.LibraryProduct, batchSize, workers int) error {
	if db == nil {
		return errors.New("db is nil")
	}
	n := len(products)
	if n == 0 {
		return nil
	}
	if batchSize <= 0 {
		batchSize = 1000
	}
	if workers <= 0 {
		workers = 4
	}

	// 切分为多个批次（每个批次不超过 batchSize）
	chunks := make([][]models.LibraryProduct, 0, (n+batchSize-1)/batchSize)
	for i := 0; i < n; i += batchSize {
		end := i + batchSize
		if end > n {
			end = n
		}
		chunks = append(chunks, products[i:end])
	}

	jobs := make(chan []models.LibraryProduct, len(chunks))
	errCh := make(chan error, workers)
	var wg sync.WaitGroup

	worker := func() {
		defer wg.Done()
		for chunk := range jobs {
			tx := db.Begin()
			if tx.Error != nil {
				errCh <- tx.Error
				return
			}

			if err := tx.Session(&gorm.Session{CreateBatchSize: batchSize}).CreateInBatches(chunk, batchSize).Error; err != nil {
				_ = tx.Rollback()
				errCh <- err
				return
			}

			if err := tx.Commit().Error; err != nil {
				errCh <- err
				return
			}
		}
	}

	// 启动 workers
	for i := 0; i < workers; i++ {
		wg.Add(1)
		go worker()
	}

	// 发送任务
	for _, c := range chunks {
		jobs <- c
	}
	close(jobs)

	wg.Wait()
	close(errCh)

	// 如果有错误，返回第一个错误
	for e := range errCh {
		if e != nil {
			log.Printf("Bulk insert error: %v", e)
			return e
		}
	}
	return nil
}

// GenerateDummyProducts 用于测试/演示，生产 count 个简单的 LibraryProduct
func GenerateDummyProducts(count int) []models.LibraryProduct {
	out := make([]models.LibraryProduct, 0, count)
	for i := 0; i < count; i++ {
		p := models.LibraryProduct{
			Name:     "demo_product",
			Sname:    "demo",
			Keywords: "demo",
			Price:    0.0,
			Status:   1,
		}
		out = append(out, p)
	}
	return out
}
