package initdb

import (
	"fmt"
	"testing"

	"github.com/glebarez/sqlite"
	"github.com/stretchr/testify/require"
	"gorm.io/gorm"
	"senlinai-agent/backend/internal/models"
)

func TestNewInitializesUserAndExpertCatalog(t *testing.T) {
	database := newExpertTestDatabase(t)

	require.NoError(t, New(database))
	requireExpertCatalogCounts(t, database)

	var user models.SaUser
	require.NoError(t, database.Where("email = ?", rootUsername).First(&user).Error)
	require.Equal(t, rootRole, user.Role)
	var expert models.SaAIExpertItem
	require.NoError(t, database.Preload("ExpertCategory").Where("slug = ?", "academic-geographer").First(&expert).Error)
	require.Equal(t, "academic", expert.ExpertCategory.Slug)
	require.Equal(t, "学术研究", expert.ExpertCategory.Name)
	require.Equal(t, "https://ao.aiolaola.com/experts", expert.Reference)
}

func TestInitExpertOnlyInsertsMissingRecords(t *testing.T) {
	database := newExpertTestDatabase(t)
	require.NoError(t, InitExpert(database))

	var preserved models.SaAIExpertItem
	require.NoError(t, database.Where("slug = ?", "academic-geographer").First(&preserved).Error)
	require.NoError(t, database.Model(&preserved).Updates(map[string]any{
		"name":              "保留名称",
		"category_id":       0,
		"category_identity": "",
		"reference":         "",
	}).Error)
	require.NoError(t, database.Where("slug = ?", "academic-historian").Delete(&models.SaAIExpertItem{}).Error)

	require.NoError(t, InitExpert(database))
	requireExpertCatalogCounts(t, database)

	require.NoError(t, database.Where("slug = ?", "academic-geographer").First(&preserved).Error)
	require.Equal(t, "保留名称", preserved.Name)
	require.NotZero(t, preserved.CategoryID)
	require.NotEmpty(t, preserved.CategoryIdentity)
	require.Equal(t, "https://ao.aiolaola.com/experts", preserved.Reference)
	var restored models.SaAIExpertItem
	require.NoError(t, database.Where("slug = ?", "academic-historian").First(&restored).Error)
}

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

	database, err := gorm.Open(sqlite.Open(fmt.Sprintf("file:%s?mode=memory&cache=shared", t.Name())), &gorm.Config{})
	require.NoError(t, err)
	require.NoError(t, database.AutoMigrate(
		&models.SaUser{},
		&models.SaDatasetSource{},
		&models.SaDatasetItem{},
		&models.SaAIExpertCategory{},
		&models.SaAIExpertItem{},
	))
	return database
}

func requireExpertCatalogCounts(t *testing.T, database *gorm.DB) {
	t.Helper()

	var categoryCount int64
	require.NoError(t, database.Model(&models.SaAIExpertCategory{}).Count(&categoryCount).Error)
	require.Equal(t, int64(19), categoryCount)
	var expertCount int64
	require.NoError(t, database.Model(&models.SaAIExpertItem{}).Count(&expertCount).Error)
	require.Equal(t, int64(267), expertCount)
}
