package models

import (
	"fmt"
	"log"
	"strings"

	"bsm/full/module/base/mgt/internal/config"

	"git.apinb.com/bsm-sdk/core/database/sql"
	"git.apinb.com/bsm-sdk/core/types"
	"git.apinb.com/bsm-sdk/core/vars"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var (
	DBService     *gorm.DB
	migrateTables = []any{
		&MgtUser{},
		&MgtDepartment{},
		&MgtRole{},
		&MgtPermission{},
		&MgtApplication{},
		&MgtLinkUserDpt{},
		&MgtLinkUserRole{},
		&MgtLinkUserPmn{},
		&MgtLinkUserApp{},
		&MgtLinkRolePmn{},
		&MgtLinkRoleApp{},
		&MgtLinkDptRole{},
		&MgtLinkDptPmn{},
	}
)

func New(driver string, dsn []string, options *types.SqlOptions) (err error) {
	driver = strings.ToLower(driver)

	switch driver {
	case "mysql":
		DBService, err = NewMysql(dsn, options)
	case "postgres":
		DBService, err = NewPostgres(dsn, options)
	default:
		log.Fatalln("Unsupported database driver:", driver)
		return
	}

	if err != nil {
		log.Fatalln(err)
		return err
	}
	log.Println("数据库连接成功")

	// 注册自定义连接表
	setupRegister()

	log.Println("自定义连接表注册成功")
	// 自动迁移表
	err = DBService.AutoMigrate(migrateTables...)
	if err != nil {
		log.Fatalln(err)
		return err
	}
	log.Println("数据表迁移成功")

	// 初始化管理员数据（幂等操作，如果已存在则跳过）
	if config.InitRootUserEnabled() {
		InitRootUserData()
		log.Println("管理员数据初始化完成（如已存在则跳过）")
	} else {
		log.Println("已跳过管理员数据初始化（InitRootUser=false）")
	}

	return
}

func NewMysql(dsn []string, options *types.SqlOptions) (gormDb *gorm.DB, err error) {
	//set connection default val.
	if options == nil {
		maxIdleConns := vars.SqlOptionMaxIdleConns
		// MaxOpenConns 应该大于 MaxIdleConns，通常设置为 MaxIdleConns * 2 或更大
		maxOpenConns := maxIdleConns * 2
		if maxOpenConns < 10 {
			maxOpenConns = 10 // 确保最小值
		}
		options = &types.SqlOptions{
			MaxIdleConns:    maxIdleConns,
			MaxOpenConns:    maxOpenConns,
			ConnMaxLifetime: vars.SqlOptionConnMaxLifetime,
			LogStdout:       false,
			Debug:           true,
		}
	} else {
		// 如果传入了options但MaxOpenConns未设置或小于MaxIdleConns，则自动调整
		if options.MaxOpenConns <= 0 || options.MaxOpenConns < options.MaxIdleConns {
			maxOpenConns := options.MaxIdleConns * 2
			if maxOpenConns < 10 {
				maxOpenConns = 10
			}
			options.MaxOpenConns = maxOpenConns
		}
	}

	gormDb, err = gorm.Open(mysql.Open(dsn[0]), &gorm.Config{
		SkipDefaultTransaction: true,
	})
	if err != nil {
		return nil, err
	}

	if options.Debug {
		gormDb = gormDb.Debug()
	}

	// 获取通用数据库对象 sql.DB ，然后使用其提供的功能
	sqlDB, _ := gormDb.DB()
	// SetMaxIdleConns 用于设置连接池中空闲连接的最大数量。
	sqlDB.SetMaxIdleConns(options.MaxIdleConns)
	// SetMaxOpenConns 设置打开数据库连接的最大数量。
	sqlDB.SetMaxOpenConns(options.MaxOpenConns)
	// SetConnMaxLifetime 设置了连接可复用的最大时间。
	sqlDB.SetConnMaxLifetime(options.ConnMaxLifetime)

	return gormDb, nil
}

func NewPostgres(dsn []string, options *types.SqlOptions) (gormDb *gorm.DB, err error) {
	fmt.Println(dsn[0])

	//set connection default val.
	if options == nil {
		maxIdleConns := vars.SqlOptionMaxIdleConns
		// MaxOpenConns 应该大于 MaxIdleConns，通常设置为 MaxIdleConns * 2 或更大
		maxOpenConns := maxIdleConns * 2
		if maxOpenConns < 10 {
			maxOpenConns = 10 // 确保最小值
		}
		options = &types.SqlOptions{
			MaxIdleConns:    maxIdleConns,
			MaxOpenConns:    maxOpenConns,
			ConnMaxLifetime: vars.SqlOptionConnMaxLifetime,
			LogStdout:       false,
			Debug:           true,
		}
	} else {
		// 如果传入了options但MaxOpenConns未设置或小于MaxIdleConns，则自动调整
		if options.MaxOpenConns <= 0 || options.MaxOpenConns < options.MaxIdleConns {
			maxOpenConns := options.MaxIdleConns * 2
			if maxOpenConns < 10 {
				maxOpenConns = 10
			}
			options.MaxOpenConns = maxOpenConns
		}
	}

	db, err := sql.NewPostgreSql(dsn[0], options)
	if err != nil {
		return nil, err
	}

	return db, nil
}
