package typeManage

import (
	"errors"
	"fmt"
	"gorm.io/gorm"
	"log-server/global"
	"log-server/model/common/request"
	"log-server/model/typeManage"
)

type AccountTypeService struct {

}

//添加账号类型
func (a *AccountTypeService) CreateAccountType(accountType typeManage.AccountType) (err error) {
	//首先检查数据库中是否有同名账号类型
	err = global.GVA_DB.Table("account_type").Where("type_name = ?", accountType.TypeName).First(&typeManage.AccountType{}).Error
	if !errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("已存在相同账号类型，请勿重复添加")
	}
	return global.GVA_DB.Table("account_type").Omit("create_time", "update_time").Create(&accountType).Error
}
//单个删除账号类型
func (a *AccountTypeService) DeleteAccountType(accountType typeManage.AccountType) (err error) {
	//首先检查数据库中是否有这条记录
	//为了后端数据的安全，声明一个实体用来存储扫描到的记录
	//删除实体
	var entity typeManage.AccountType
	err = global.GVA_DB.Table("account_type").Where("id = ?", accountType.Id).First(&entity).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return err
	}
	return global.GVA_DB.Table("account_type").Delete(&entity).Error
}
//批量删除账号类型
func (a *AccountTypeService) DeleteAccountTypesByIds(ids request.IdsReq) (err error) {
	err = global.GVA_DB.Table("account_type").Delete(&[]typeManage.AccountType{}, "id in ?", ids.Ids).Error
	return err
}
//更改账号类型
func (a *AccountTypeService) UpdateAccountType(accountType typeManage.AccountType) (err error) {
	//做业务逻辑判断
	//比如不能更改至同名账号类型，如果存在同名账号类型就直接返回错误
	//排错之后再更新
	err = global.GVA_DB.Table("account_type").Where("id != ? and type_name = ?", accountType.Id, accountType.TypeName).First(&typeManage.AccountType{}).Error
	if !errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("已存在同名账号类型，无法更新")
	}
	return global.GVA_DB.Table("account_type").Updates(&accountType).Error
}


//通过id获取单条数据
func (a *AccountTypeService) GetAccountTypeById(id int) (accountType typeManage.AccountType, err error){
	err = global.GVA_DB.Table("account_type").Where("id = ?", id).First(&accountType).Error
	return
}
//获取所有账号类型列表
func (a *AccountTypeService) AccountTypeList(accountType typeManage.AccountType, info request.PageInfo, order string, desc bool) (list interface{}, total int64, err error){
	//accountType是传输过来的查询条件
	//info是传输过来的分页信息
	//order是传输过来的排序字段
	//desc是传输过来的升降序信息

	//获取limit和offset
	limit := info.PageSize
	offset := (info.Page - 1) * info.PageSize


	db := global.GVA_DB.Table("account_type").Model(&typeManage.AccountType{})
	var accountTypeList []typeManage.AccountType

	//先条件过滤
	if accountType.TypeName != "" {
		//条件过滤记录数
		db = db.Where("type_name like ?", "%" + accountType.TypeName + "%")
	}
	//查找数量并且校验是否出错，注意，即使count=0，Count也不会出错，出错的地方可能在于我条件筛选没有，然后我再count，然后出错？
	//非也非也，我即使条件查询没有，从逻辑上来说不该报错，而且实际业务表现上也没有报错，所以可能是为了防止其他错误出现稳一手

	//只要进行了条件筛选，就可以直接去查询count了，后续任何操作比如分页排序都无法也不能改变count，所以在条件查询之后、在分页和排序之前去操作count

	err = db.Count(&total).Error
	if err != nil{
		//如果出错直接返回
		return accountTypeList, total, err
	} else {
		//先分页再排序
		db = db.Limit(limit).Offset(offset)
		if order != ""{
			//传入排序字段，进行排序
			//定义orderStr存储完整的排序字段
			var  orderStr string
			//为了避免sql注入，自己创建数组匹配
			orderMap := make(map[string]bool, 3)
			orderMap["type_name"] = true
			orderMap["create_time"] = true
			orderMap["update_time"] = true
			if orderMap[order] {
				//是好人，可以排序
				if desc {
					//传入desc,是降序
					orderStr = order + " desc"
				} else {
					//没有传入desc，是默认升序
					orderStr = order
				}
			} else {
				//传入非法字段，不能排序
				err = fmt.Errorf("传入非法字段 %v", order)
				return accountTypeList, total, err
			}
			//排序
			err = db.Order(orderStr).Find(&accountTypeList).Error
		} else {
			//没有传入排序字段，默认按照类型名称降序排序
			err = db.Order("type_name desc").Find(&accountTypeList).Error
		}
	}
	//是因为只有切片能排序，model没办法排序;还是说为了将数组返回至前端才find扫描至切片呢？
	return accountTypeList, total, err
}