package database

import (
	_ "embed"
	"fmt"

	"juhe-factory/api/internal/model"

	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

//go:embed schema.sql
var baselineSchema string

func bootstrapEmptyDatabase(db *gorm.DB) error {
	var businessTableCount int64
	if err := db.Raw(`SELECT count(*) FROM pg_tables
		WHERE schemaname = 'public' AND tablename NOT IN ('jcf_schema_migrations', 'schema_migrations')`).
		Scan(&businessTableCount).Error; err != nil {
		return fmt.Errorf("inspect database schema: %w", err)
	}
	if businessTableCount == 0 {
		baselineDB := db.Session(&gorm.Session{Logger: logger.Default.LogMode(logger.Silent)})
		if err := baselineDB.Transaction(func(tx *gorm.DB) error {
			return tx.Exec(baselineSchema).Error
		}); err != nil {
			return fmt.Errorf("initialize database baseline: %w", err)
		}
		if err := db.Exec(`SET search_path TO public`).Error; err != nil {
			return fmt.Errorf("restore database search path: %w", err)
		}
	}

	if err := autoMigrateMissingTables(db, autoMigrateModels()...); err != nil {
		return fmt.Errorf("auto migrate database models: %w", err)
	}
	return nil
}

func autoMigrateMissingTables(db *gorm.DB, tableModels ...any) error {
	for _, tableModel := range tableModels {
		if db.Migrator().HasTable(tableModel) {
			continue
		}
		if err := db.AutoMigrate(tableModel); err != nil {
			return err
		}
	}
	return nil
}

func autoMigrateModels() []any {
	return []any{
		&model.AdminUser{},
		&model.AdminRefreshToken{},
		&model.AdminAuditLog{},
		&model.WebUser{},
		&model.WebRefreshToken{},
		&model.MediaAsset{},
		&model.CreativeProject{},
		&model.ProjectModelConfig{},
		&model.UserModelConfig{},
		&model.ScriptAnalysis{},
		&model.ScriptAnalysisCharacter{},
		&model.ProjectEpisode{},
		&model.ProjectAsset{},
		&model.EpisodeStoryboard{},
		&model.EpisodeSource{},
		&model.DramaImportSession{},
		&model.DramaParseBatch{},
		&model.DramaParseTask{},
		&model.GenerationTask{},
		&model.GenerationOutput{},
	}
}
