package db

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

	"gorm.io/gorm"

	"be.ems/src/framework/config"
)

// ImportSQL 导入SQL
func ImportSQL() {
	sqlPath := config.Get("sqlPath").(string)
	if sqlPath == "" {
		return
	}
	sqlSource := config.Get("sqlSource").(string)
	if sqlSource == "" {
		sqlSource = config.Get("database.defaultDataSourceName").(string)
	}

	// 数据源
	db := DB(sqlSource)
	if db == nil {
		log.Fatalln("not database source")
		return
	}

	// 获取路径信息
	fileInfo, err := os.Stat(sqlPath)
	if err != nil {
		log.Fatalln(err.Error())
		return
	}

	// 处理目录或文件
	if fileInfo.IsDir() {
		// 处理目录
		files, err := os.ReadDir(sqlPath)
		if err != nil {
			log.Fatalln(err.Error())
			return
		}

		for _, file := range files {
			if file.IsDir() {
				continue
			}
			if !strings.HasSuffix(file.Name(), ".sql") {
				continue
			}
			processSQLFile(db, filepath.Join(sqlPath, file.Name()))
		}
	} else {
		// 处理单个文件
		processSQLFile(db, sqlPath)
	}

	// log.Println("process success")
	os.Exit(0)
}

// 处理单个SQL文件的通用函数
func processSQLFile(db *gorm.DB, filePath string) {
	file, err := os.Open(filePath)
	if err != nil {
		log.Fatalln(err.Error())
		return
	}
	defer file.Close()

	// 逐行读取 SQL 文件
	scanner := bufio.NewScanner(file)
	var sqlBuilder strings.Builder
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		// 跳过注释和空行
		if strings.HasPrefix(line, "--") || strings.TrimSpace(line) == "" {
			continue
		}
		// 跳过配置语句
		if strings.HasPrefix(line, "/*!") {
			continue
		}

		sqlBuilder.WriteString(line + "\n")

		// 当遇到分号时，执行 SQL 语句
		if strings.HasSuffix(line, ";") {
			// 执行 SQL 语句
			if err := db.Exec(sqlBuilder.String()).Error; err != nil {
				errorStr := strings.ToLower(err.Error())
				// log.Printf("Exec SQL: %s\n", line)
				// log.Println(err.Error())
				if strings.Contains(errorStr, "duplicate column") {
					// 忽略重复字段错误
					// Error 1060 (42S21): Duplicate column name 'field_name'
					// SQL logic error: duplicate column name: title (1)
				} else if strings.Contains(errorStr, "duplicate key") {
					// 忽略重复索引错误
					// Error 1061 (42000): Duplicate key name 'key_name'
				} else if strings.Contains(errorStr, "duplicate entry") {
					// 忽略重复记录错误
					// Error 1062 (23000): Duplicate entry 'value' for key 'key_name'
					log.Println(err.Error())
				} else if strings.Contains(errorStr, "unknown column") || strings.Contains(errorStr, "no such column") {
					// 忽略未知字段错误
					// Error 1054 (42S22): Unknown column 'field_name' in 'table'
					// sql logic error: no such column: "field_name" (1)
				} else if strings.Contains(errorStr, "can't drop") {
					// 忽略删除字段或索引错误
					// Error 1091 (42000): Can't DROP COLUMN `field_name`; check that it exists
					// Error 1091 (42000): Can't DROP 'idx_ne_type_id'; check that column/key exists
				} else if strings.Contains(errorStr, "doesn't match") {
					// 忽略列数不匹配错误
					// Error 1136 (21S01): Column count doesn't match value count at row 1
					log.Println(err.Error())
				} else {
					// 其他错误终止程序
					log.Fatalln(errorStr)
					return
				}
			}

			sqlBuilder.Reset()
			continue
		}
	}
}
