//go:build mysql

package mysql

import (
	"errors"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"gorm.io/gorm"

	"nex/backend/internal/config"
)

func TestConstraint_ForeignKeyEnforced(t *testing.T) {
	db := SetupMySQLTestDB(t)

	model := config.Model{
		ID:         "test-model-id",
		ProviderID: "non-existent-provider",
		ModelName:  "gpt-4",
		Enabled:    true,
	}

	err := db.Create(&model).Error
	assert.Error(t, err, "创建 model 时 provider_id 不存在应失败")
	assert.Contains(t, err.Error(), "foreign key constraint", "错误应为外键约束错误")
}

func TestConstraint_CascadeDelete(t *testing.T) {
	db := SetupMySQLTestDB(t)

	provider := config.Provider{
		ID:      "test-provider-cascade",
		Name:    "Test Provider",
		APIKey:  "test-key",
		BaseURL: "https://test.com",
		Enabled: true,
	}
	err := db.Create(&provider).Error
	require.NoError(t, err, "创建 provider 应成功")

	model := config.Model{
		ID:         "test-model-cascade",
		ProviderID: provider.ID,
		ModelName:  "gpt-4",
		Enabled:    true,
	}
	err = db.Create(&model).Error
	require.NoError(t, err, "创建 model 应成功")

	err = db.Delete(&provider).Error
	require.NoError(t, err, "删除 provider 应成功")

	var count int64
	err = db.Model(&config.Model{}).Where("provider_id = ?", provider.ID).Count(&count).Error
	require.NoError(t, err)
	assert.Equal(t, int64(0), count, "删除 provider 后其 models 应被级联删除")
}

func TestConstraint_UniqueProviderModel(t *testing.T) {
	db := SetupMySQLTestDB(t)

	provider := config.Provider{
		ID:      "test-provider-unique",
		Name:    "Test Provider",
		APIKey:  "test-key",
		BaseURL: "https://test.com",
		Enabled: true,
	}
	err := db.Create(&provider).Error
	require.NoError(t, err, "创建 provider 应成功")

	model1 := config.Model{
		ID:         "test-model-unique-1",
		ProviderID: provider.ID,
		ModelName:  "gpt-4",
		Enabled:    true,
	}
	err = db.Create(&model1).Error
	require.NoError(t, err, "创建第一个 model 应成功")

	model2 := config.Model{
		ID:         "test-model-unique-2",
		ProviderID: provider.ID,
		ModelName:  "gpt-4",
		Enabled:    true,
	}
	err = db.Create(&model2).Error
	assert.Error(t, err, "创建相同 (provider_id, model_name) 的 model 应失败")
	assert.True(t, errors.Is(err, gorm.ErrDuplicatedKey) ||
		(err != nil && (err.Error() == "Error 1062" || containsDuplicateError(err.Error()))),
		"错误应为唯一约束错误")
}

func TestConstraint_UniqueUsageStats(t *testing.T) {
	db := SetupMySQLTestDB(t)

	today := time.Now().Format("2006-01-02")
	todayTime, _ := time.Parse("2006-01-02", today)

	providerID := "test-provider-unique-stats"

	stats1 := config.UsageStats{
		ProviderID:   providerID,
		ModelName:    "gpt-4",
		RequestCount: 10,
		Date:         todayTime,
	}
	err := db.Create(&stats1).Error
	require.NoError(t, err, "创建第一个 usage_stats 应成功")

	stats2 := config.UsageStats{
		ProviderID:   providerID,
		ModelName:    "gpt-4",
		RequestCount: 20,
		Date:         todayTime,
	}
	err = db.Create(&stats2).Error
	assert.Error(t, err, "创建相同 (provider_id, model_name, date) 的 usage_stats 应失败")
	assert.True(t, errors.Is(err, gorm.ErrDuplicatedKey) ||
		(err != nil && (err.Error() == "Error 1062" || containsDuplicateError(err.Error()))),
		"错误应为唯一约束错误")
}

func containsDuplicateError(errStr string) bool {
	return len(errStr) > 0 && (errStr[0:8] == "Error 10" || errStr[0:5] == "Dupli")
}
