package database

import (
    "log"
    "os"
    "path/filepath"
    "strings"

	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/models"
	"gorm.io/gorm"
)

// AutoMigrate 自动迁移数据库表结构
func AutoMigrate(db *gorm.DB) error {
	log.Println("开始数据库迁移...")
	
	// 用户相关表
	err := db.AutoMigrate(
		&models.User{},
		&models.UserSocialLink{},
		&models.UserPreference{},
	)
	if err != nil {
		return err
	}
	
    // 词汇相关表迁移由 SQL 脚本维护，避免与既有外键/类型冲突
    // （跳过 Vocabulary* / UserVocabularyProgress / VocabularyTest 的 AutoMigrate）
	
	// 词汇书相关表（新增）
	err = db.AutoMigrate(
		&models.VocabularyBook{},
		&models.VocabularyBookWord{},
	)
	if err != nil {
		return err
	}
	
	// 学习相关表
	err = db.AutoMigrate(
		&models.Notification{},
		&models.StudyPlan{},
		&models.StudyPlanRecord{},
		&models.ListeningMaterial{},
		&models.ListeningRecord{},
		&models.ReadingMaterial{},
		&models.ReadingRecord{},
		&models.WritingPrompt{},
		&models.WritingSubmission{},
		&models.SpeakingScenario{},
		&models.SpeakingRecord{},
	)
	if err != nil {
		return err
	}
	
	log.Println("数据库迁移完成")
	return nil
}

// CreateIndexes 创建额外的索引
func CreateIndexes(db *gorm.DB) error {
	log.Println("开始创建索引...")
	
	// 创建索引的辅助函数
	createIndexIfNotExists := func(indexName, tableName, columns string) {
		// 检查索引是否存在
		var count int64
		db.Raw("SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?", tableName, indexName).Scan(&count)
		if count == 0 {
			// 索引不存在，创建索引
			sql := "CREATE INDEX " + indexName + " ON " + tableName + "(" + columns + ")"
			result := db.Exec(sql)
			if result.Error != nil {
				log.Printf("创建索引 %s 失败: %v", indexName, result.Error)
			}
		}
	}
	
	// 用户表索引
    createIndexIfNotExists("idx_users_email_verified", "ai_users", "email_verified")
    createIndexIfNotExists("idx_users_status", "ai_users", "status")
    createIndexIfNotExists("idx_users_created_at", "ai_users", "created_at")
	
	// 词汇表索引
    createIndexIfNotExists("idx_vocabulary_level", "ai_vocabulary", "level")
    createIndexIfNotExists("idx_vocabulary_frequency", "ai_vocabulary", "frequency")
    createIndexIfNotExists("idx_vocabulary_is_active", "ai_vocabulary", "is_active")
	
	// 用户词汇进度索引
    createIndexIfNotExists("idx_user_vocabulary_progress_user_vocab", "ai_user_vocabulary_progress", "user_id, vocabulary_id")
    createIndexIfNotExists("idx_user_vocabulary_progress_mastery", "ai_user_vocabulary_progress", "mastery_level")
    createIndexIfNotExists("idx_user_vocabulary_progress_next_review", "ai_user_vocabulary_progress", "next_review_at")
	
	// 学习记录索引
    createIndexIfNotExists("idx_listening_records_user_material", "ai_listening_records", "user_id, material_id")
    createIndexIfNotExists("idx_reading_records_user_material", "ai_reading_records", "user_id, material_id")
    createIndexIfNotExists("idx_writing_submissions_user_prompt", "ai_writing_submissions", "user_id, prompt_id")
    createIndexIfNotExists("idx_speaking_records_user_scenario", "ai_speaking_records", "user_id, scenario_id")
	
	// 材料表索引
    createIndexIfNotExists("idx_listening_materials_level", "ai_listening_materials", "level")
    createIndexIfNotExists("idx_reading_materials_level", "ai_reading_materials", "level")
    createIndexIfNotExists("idx_writing_prompts_level", "ai_writing_prompts", "level")
    createIndexIfNotExists("idx_speaking_scenarios_level", "ai_speaking_scenarios", "level")
	
	log.Println("索引创建完成")
	return nil
}

// ApplyMergedSchemaIfNeeded 读取并执行合并后的SQL脚本，用于创建视图、触发器及扩展表
func ApplyMergedSchemaIfNeeded(db *gorm.DB) error {
    // 检查一个扩展表是否存在，作为是否需要执行脚本的依据
    var count int64
    db.Raw("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'ai_vocabulary_books'").Scan(&count)
    if count > 0 {
        // 已存在扩展结构，跳过
        return nil
    }

    // 读取脚本文件（从 serve 目录运行，脚本位于 ../docs/）
    candidates := []string{
        "../docs/database_schema_merged.sql",
        "../docs/database_schema.sql",
    }
    var content []byte
    var readErr error
    for _, p := range candidates {
        abs, _ := filepath.Abs(p)
        content, readErr = os.ReadFile(abs)
        if readErr == nil {
            break
        }
    }
    if readErr != nil {
        log.Printf("读取数据库脚本失败: %v", readErr)
        return nil
    }

    sql := string(content)
    // 移除 DELIMITER 指令并将触发器结束符 // 转为 ;
    lines := strings.Split(sql, "\n")
    var cleaned []string
    for _, line := range lines {
        trimmed := strings.TrimSpace(line)
        if strings.HasPrefix(trimmed, "DELIMITER") {
            continue
        }
        // 将以 // 结尾的行替换为 ;
        if strings.HasSuffix(trimmed, "//") {
            cleaned = append(cleaned, strings.TrimSuffix(line, "//")+";")
            continue
        }
        cleaned = append(cleaned, line)
    }
    cleanedSQL := strings.Join(cleaned, "\n")

    // 关闭外键检查以避免初始化时的顺序问题
    if err := db.Exec("SET FOREIGN_KEY_CHECKS=0;").Error; err != nil {
        log.Printf("关闭外键检查失败: %v", err)
    }
    // 执行脚本（依赖 multiStatements=true）
    if err := db.Exec(cleanedSQL).Error; err != nil {
        log.Printf("执行合并SQL失败: %v", err)
    }
    // 恢复外键检查
    if err := db.Exec("SET FOREIGN_KEY_CHECKS=1;").Error; err != nil {
        log.Printf("开启外键检查失败: %v", err)
    }

    return nil
}