package db

import (
	model2 "applet/app/db/offical/model"
	"errors"
	"fmt"

	"xorm.io/xorm"

	"applet/app/cfg"
	"applet/app/db/model"
	"applet/app/utils/logx"
)

func MapBaseExists() (bool, error) {
	return Db.IsTableExist("db_mapping")
}

func InitMapDbs(c *cfg.DBCfg, prd bool) {
	var tables *[]model.DbMapping
	exists, err := MapBaseExists()
	if !exists || err != nil {
		logx.Fatalf("db_mapping not exists : %v", err)
	}
	// tables := MapAllDatabases(debug)
	if prd {
		tables = GetAllDatabasePrd() //debug 获取生产
	} else {
		tables = GetAllDatabaseDev() //debug 获取开发
	}

	if tables == nil {
		logx.Fatal("no database tables data")
	}
	var e *xorm.Engine
	DBs = map[string]*xorm.Engine{}
	for _, v := range *tables {
		if v.DbName != "" && v.DeletedAt == 0 && v.DbName != c.Name {
			dbCfg := cfg.DBCfg{
				Name:         v.DbName,
				ShowLog:      c.ShowLog,
				MaxLifetime:  c.MaxLifetime,
				MaxOpenConns: c.MaxOpenConns,
				MaxIdleConns: c.MaxIdleConns,
				Path:         fmt.Sprintf(c.Path, v.DbName),
			}
			if v.DbHost != "" && v.DbUsername != "" && v.DbPassword != "" {
				dbCfg.Host = v.DbHost
				dbCfg.User = v.DbUsername
				dbCfg.Psw = v.DbPassword
			} else {
				dbCfg.Host = c.Host
				dbCfg.User = c.User
				dbCfg.Psw = c.Psw
			}
			e, err = NewDB(&dbCfg)
			if err != nil || e == nil {
				logx.Warnf("db engine can't create, please check config, params[host:%s, user:%s, psw: %s, name: %s], err: %v", dbCfg.Host, dbCfg.User, dbCfg.Psw, dbCfg.Name, err)
			} else {
				DBs[v.DbMasterId] = e
			}
		}
	}
}

func MapAllDatabases(debug bool) *[]model.DbMapping {
	sql := "`db_name` != ?"
	if debug {
		sql = "`db_name` = ?"
	}
	var m []model.DbMapping
	if err := Db.Where(sql, cfg.DB.Name).Find(&m); err != nil || len(m) == 0 {
		logx.Warn(err)
		return nil
	}
	return &m
}

// GetAllDatabasePrd is 获取生成库 所有db 除了 deleted_at = 1 的
func GetAllDatabasePrd() *[]model.DbMapping {
	var m []model.DbMapping
	if err := Db.Where("deleted_at != ? AND is_dev = '0' ", 1).Find(&m); err != nil || len(m) == 0 {
		logx.Warn(err)
		return nil
	}
	return &m
}

// GetAllDatabaseDev is 获取开发库 所有db 除了 deleted_at = 1 的
func GetAllDatabaseDev() *[]model.DbMapping {
	var m []model.DbMapping
	var err error
	if cfg.Local { // 本地调试 加快速度
		//fmt.Println("notice:LOCAL TEST, only masterId:** 123456 ** available!")
		err = Db.Where("deleted_at != ? AND is_dev = '1' AND db_master_id=?", 1, 123456).Find(&m)
		//err = Db.Where(" db_master_id=?", 36274003).Find(&m)
	} else {
		err = Db.Where("deleted_at != ? AND is_dev = '1' ", 1).Find(&m)
	}

	//err := Db.Where("deleted_at != ? AND is_dev = '1' and db_master_id='123456'", 1).Find(&m)
	if err != nil || len(m) == 0 {
		logx.Warn(err)
		return nil
	}
	return &m
}

// GetDatabaseByMasterID is 根据站长id 获取对应的的数据库信息
func GetDatabaseByMasterID(Db *xorm.Engine, id string) (*model.DbMapping, error) {
	var m model.DbMapping
	has, err := Db.Where("db_master_id=?", id).Get(&m)
	if !has {
		return nil, errors.New("Not Found DB data by " + id)
	}
	if err != nil {
		return nil, err
	}
	if m.DbHost == "" {
		m.DbHost = cfg.DB.Host
		m.DbUsername = cfg.DB.User
		m.DbPassword = cfg.DB.Psw
	}
	return &m, nil
}

// SessionGetDatabaseByMasterID is 根据站长id 获取对应的的数据库信息
func SessionGetDatabaseByMasterID(Db *xorm.Session, id string) (*model.DbMapping, error) {
	var m model.DbMapping
	has, err := Db.Where("db_master_id=?", id).Get(&m)
	if !has {
		return nil, errors.New("Not Found DB data by " + id)
	}
	if err != nil {
		return nil, err
	}
	if m.DbHost == "" {
		m.DbHost = cfg.DB.Host
		m.DbName = cfg.DB.Name
		m.DbUsername = cfg.DB.User
		m.DbPassword = cfg.DB.Psw
	}
	return &m, nil
}

// 获取自动任务队列
func MapCrontabCfg(eg *xorm.Engine) *[]model.SysCfg {
	var c []model.SysCfg
	// 数据库查询如果有下划线会认为是一个任意字符
	if err := eg.Where("`key` LIKE 'cron\\_%' AND val != ''").Cols("`key`,`val`").Find(&c); err != nil || len(c) == 0 {
		logx.Warn(err)
		return nil
	}
	return &c
}

// 获取官方域名
func GetOfficialDomainInfoByType(Db *xorm.Engine, masterId, key string) (string, error) {
	type SysCfg struct {
		K    string
		V    string
		Memo string
	}
	var domainBase SysCfg

	has, err := Db.Where("k=?", "domain_wap_base").Get(&domainBase)
	if err != nil {
		return "", err
	}
	if has == false {
		return "", errors.New("can not find key by : domain_base")
	}

	if key == "wap" {
		return masterId + "." + domainBase.V, nil
	}

	if key == "api" {
		var apiDomain SysCfg
		has, err = Db.Where("k=?", "domain_api_base").Get(&apiDomain)
		if err != nil {
			return "", err
		}
		if has == false {
			return "", errors.New("can not find key by : domain_api_base")
		}
		return apiDomain.V, nil
	}

	if key == "admin" {
		return "admin." + masterId + "." + domainBase.V, nil
	}
	// 默认返回H5的
	return masterId + "." + domainBase.V, nil
}
func GetOfficialDomainInfoByTypeToAgent(Db *xorm.Engine, masterId, uuid, key string) (string, error) {
	type SysCfg struct {
		K    string
		V    string
		Memo string
	}
	var domainBase model2.MasterListCfg
	has, err := Db.Where("uid=? and k=?", uuid, "domain_base").Get(&domainBase)
	if err != nil {
		return "", err
	}
	if has == false {
		return "", errors.New("can not find key by : domain_base")
	}

	if key == "wap" {
		return masterId + ".h5." + domainBase.V, nil
	}

	if key == "api" {
		var apiDomain SysCfg
		has, err = Db.Where("k=?", "domain_api_base").Get(&apiDomain)
		if err != nil {
			return "", err
		}
		if has == false {
			return "", errors.New("can not find key by : domain_api_base")
		}
		return apiDomain.V, nil
	}

	if key == "admin" {
		return "admin." + masterId + "." + domainBase.V, nil
	}
	// 默认返回H5的
	return masterId + "." + domainBase.V, nil
}
