package initialize

import (
	"kra/internal/conf"

	"gorm.io/gorm"
)

const SystemDB = "system"

// DBList 数据库列表管理器
type DBList struct {
	dbs map[string]*gorm.DB
}

// NewDBList 创建数据库列表
func NewDBList() *DBList {
	return &DBList{
		dbs: make(map[string]*gorm.DB),
	}
}

// InitDBList 初始化多数据库连接
func InitDBList(dbList []*conf.SpecializedDB) (*DBList, error) {
	list := NewDBList()

	for _, info := range dbList {
		if info.Disable {
			continue
		}

		var db *gorm.DB
		var err error

		switch info.Type {
		case "mysql":
			db, err = GormMysqlByConfig(specializedDBToMysql(info))
		case "pgsql":
			db, err = GormPgsqlByConfig(specializedDBToPgsql(info))
		case "sqlite":
			db, err = GormSqliteByConfig(specializedDBToSqlite(info))
		case "mssql":
			db, err = GormMssqlByConfig(specializedDBToMssql(info))
		case "oracle":
			db, err = GormOracleByConfig(specializedDBToOracle(info))
		default:
			continue
		}

		if err != nil {
			return nil, err
		}

		if db != nil {
			list.dbs[info.AliasName] = db
		}
	}

	return list, nil
}

// Get 获取指定名称的数据库连接
func (l *DBList) Get(name string) *gorm.DB {
	if l.dbs == nil {
		return nil
	}
	return l.dbs[name]
}

// GetSystem 获取系统数据库连接
func (l *DBList) GetSystem() *gorm.DB {
	return l.Get(SystemDB)
}

// Set 设置数据库连接
func (l *DBList) Set(name string, db *gorm.DB) {
	if l.dbs == nil {
		l.dbs = make(map[string]*gorm.DB)
	}
	l.dbs[name] = db
}

// All 获取所有数据库连接
func (l *DBList) All() map[string]*gorm.DB {
	return l.dbs
}

// Close 关闭所有数据库连接
func (l *DBList) Close() error {
	for _, db := range l.dbs {
		sqlDB, err := db.DB()
		if err != nil {
			continue
		}
		sqlDB.Close()
	}
	return nil
}

// specializedDBToMysql 转换为MySQL配置
func specializedDBToMysql(s *conf.SpecializedDB) *conf.Mysql {
	return &conf.Mysql{
		Prefix:       s.Prefix,
		Path:         s.Path,
		Port:         s.Port,
		Config:       s.Config,
		DbName:       s.DbName,
		Username:     s.Username,
		Password:     s.Password,
		Engine:       s.Engine,
		MaxIdleConns: s.MaxIdleConns,
		MaxOpenConns: s.MaxOpenConns,
		LogMode:      s.LogMode,
		LogZap:       s.LogZap,
		Singular:     s.Singular,
	}
}

// specializedDBToPgsql 转换为PostgreSQL配置
func specializedDBToPgsql(s *conf.SpecializedDB) *conf.Pgsql {
	return &conf.Pgsql{
		Prefix:       s.Prefix,
		Path:         s.Path,
		Port:         s.Port,
		Config:       s.Config,
		DbName:       s.DbName,
		Username:     s.Username,
		Password:     s.Password,
		Engine:       s.Engine,
		MaxIdleConns: s.MaxIdleConns,
		MaxOpenConns: s.MaxOpenConns,
		LogMode:      s.LogMode,
		LogZap:       s.LogZap,
		Singular:     s.Singular,
	}
}

// specializedDBToSqlite 转换为SQLite配置
func specializedDBToSqlite(s *conf.SpecializedDB) *conf.Sqlite {
	return &conf.Sqlite{
		Prefix:       s.Prefix,
		Path:         s.Path,
		DbName:       s.DbName,
		Engine:       s.Engine,
		MaxIdleConns: s.MaxIdleConns,
		MaxOpenConns: s.MaxOpenConns,
		LogMode:      s.LogMode,
		LogZap:       s.LogZap,
		Singular:     s.Singular,
	}
}

// specializedDBToMssql 转换为MSSQL配置
func specializedDBToMssql(s *conf.SpecializedDB) *conf.Mssql {
	return &conf.Mssql{
		Prefix:       s.Prefix,
		Path:         s.Path,
		Port:         s.Port,
		Config:       s.Config,
		DbName:       s.DbName,
		Username:     s.Username,
		Password:     s.Password,
		Engine:       s.Engine,
		MaxIdleConns: s.MaxIdleConns,
		MaxOpenConns: s.MaxOpenConns,
		LogMode:      s.LogMode,
		LogZap:       s.LogZap,
		Singular:     s.Singular,
	}
}

// specializedDBToOracle 转换为Oracle配置
func specializedDBToOracle(s *conf.SpecializedDB) *conf.Oracle {
	return &conf.Oracle{
		Prefix:       s.Prefix,
		Path:         s.Path,
		Port:         s.Port,
		Config:       s.Config,
		DbName:       s.DbName,
		Username:     s.Username,
		Password:     s.Password,
		Engine:       s.Engine,
		MaxIdleConns: s.MaxIdleConns,
		MaxOpenConns: s.MaxOpenConns,
		LogMode:      s.LogMode,
		LogZap:       s.LogZap,
		Singular:     s.Singular,
	}
}
