package data_manage

import (
	"eta_gn/eta_api/global"
	"eta_gn/eta_api/utils"
	"time"
)

type PredictEdbConf struct {
	ConfigId         int       `orm:"column(config_id);pk" gorm:"primaryKey"  description:"规则id"`
	PredictEdbInfoId int       `orm:"column(predict_edb_info_id)" description:"预测指标id"`
	SourceEdbInfoId  int       `description:"来源指标id"`
	RuleType         int       `description:"预测规则,1:最新,2:固定值,3:同比,4:同差,5:环比,6:环差,7:N期移动均值,8:N期段线性外推值,9:动态环差"`
	FixedValue       float64   `description:"固定值"`
	Value            string    `description:"配置的值"`
	EmptyType        int       `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"`
	MaxEmptyType     int       `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"`
	EndDate          time.Time `description:"截止日期"`
	ModifyTime       time.Time `description:"修改时间"`
	CreateTime       time.Time `description:"添加时间"`
}

// PredictEdbConfDetail 预测规则 和 规则相关联的指标
type PredictEdbConfDetail struct {
	ConfigId         int                                     `orm:"column(config_id);pk" gorm:"primaryKey"  description:"规则id"`
	PredictEdbInfoId int                                     `orm:"column(predict_edb_info_id)" description:"预测指标id"`
	SourceEdbInfoId  int                                     `description:"来源指标id"`
	RuleType         int                                     `description:"预测规则,1:最新,2:固定值,3:同比,4:同差,5:环比,6:环差,7:N期移动均值,8:N期段线性外推值,9:动态环差"`
	FixedValue       float64                                 `description:"固定值"`
	Value            string                                  `description:"配置的值"`
	EmptyType        int                                     `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"`
	MaxEmptyType     int                                     `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"`
	EndDate          string                                  `description:"截止日期"`
	ModifyTime       string                                  `description:"修改时间"`
	CreateTime       string                                  `description:"添加时间"`
	CalculateList    []*PredictEdbConfCalculateMappingDetail `description:"配置与指标的关联信息"`
}

// PredictEdbConfAndData 预测规则和其对应的动态数据
type PredictEdbConfAndData struct {
	ConfigId         int            `orm:"column(config_id);pk" gorm:"primaryKey"  description:"规则id"`
	PredictEdbInfoId int            `orm:"column(predict_edb_info_id)" description:"预测指标id"`
	SourceEdbInfoId  int            `description:"来源指标id"`
	RuleType         int            `description:"预测规则,1:最新,2:固定值,3:同比,4:同差,5:环比,6:环差,7:N期移动均值,8:N期段线性外推值,9:动态环差"`
	FixedValue       float64        `description:"固定值"`
	Value            string         `description:"配置的值"`
	EndDate          time.Time      `description:"截止日期"`
	ModifyTime       time.Time      `description:"修改时间"`
	CreateTime       time.Time      `description:"添加时间"`
	DataList         []*EdbDataList `description:"动态数据"`
}

// GetPredictEdbConfCount 根据来源指标id获取被引用的次数
func GetPredictEdbConfCount(sourceEdbInfoId int) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM predict_edb_conf WHERE source_edb_info_id=? `
	err = global.DmSQL["data"].Raw(sql, sourceEdbInfoId).Scan(&count).Error
	return
}

// AddPredictEdb 添加预测指标
func AddPredictEdb(item *EdbInfo, calculateMappingItem *EdbInfoCalculateMapping, predictEdbConfList []*PredictEdbConf) (err error) {
	to := global.DmSQL["data"].Begin()

	defer func() {
		if err != nil {
			_ = to.Rollback()
		} else {
			_ = to.Commit()
		}
	}()

	// 新增预测指标
	err = to.Create(item).Error
	if err != nil {
		return
	}
	// 新增预测指标
	calculateMappingItem.EdbInfoId = item.EdbInfoId

	err = to.Create(calculateMappingItem).Error
	if err != nil {
		return
	}

	// 新增预测指标配置
	lenPredictEdbConf := len(predictEdbConfList)
	if lenPredictEdbConf > 0 {
		for _, v := range predictEdbConfList {
			v.PredictEdbInfoId = item.EdbInfoId
		}
		err = to.CreateInBatches(predictEdbConfList, utils.MultiAddNum).Error
		if err != nil {
			return
		}
	}
	return
}

// EditPredictEdb 修改预测指标
func EditPredictEdb(edbInfo *EdbInfo, predictEdbConfList []*PredictEdbConf, updateEdbInfoCol []string) (err error) {
	to := global.DmSQL["data"].Begin()

	defer func() {
		if err != nil {
			_ = to.Rollback()
		} else {
			_ = to.Commit()
		}
	}()

	// 修改预测指标
	err = to.Select(updateEdbInfoCol).Updates(edbInfo).Error
	if err != nil {
		return
	}

	// 先删除原有的配置
	sql := ` DELETE FROM predict_edb_conf WHERE predict_edb_info_id = ?`
	err = to.Exec(sql, edbInfo.EdbInfoId).Error
	if err != nil {
		return
	}
	// 新增新有的预测指标配置
	lenPredictEdbConf := len(predictEdbConfList)
	if lenPredictEdbConf > 0 {
		err = to.CreateInBatches(predictEdbConfList, utils.MultiAddNum).Error
		if err != nil {
			return
		}
	}
	return
}

// GetPredictEdbInfoAllCalculate 根据基础预测指标id集合 获取 所有的普通指标列表数据
func GetPredictEdbInfoAllCalculate(edbInfoIdList []int) (list []*EdbInfo, err error) {
	num := len(edbInfoIdList)
	if num <= 0 {
		return
	}
	sql := ` SELECT DISTINCT b.* FROM predict_edb_conf AS a
			 INNER JOIN edb_info AS b ON a.source_edb_info_id=b.edb_info_id
	        WHERE a.predict_edb_info_id in (` + utils.GetOrmInReplace(num) + `)
			 ORDER BY b.edb_info_id ASC `
	err = global.DmSQL["data"].Raw(sql, edbInfoIdList).Find(&list).Error
	return
}

// GetPredictEdbConfListById 根据预测指标id获取预测指标配置信息列表
func GetPredictEdbConfListById(edbInfoId int) (items []*PredictEdbConf, err error) {
	sql := ` SELECT * FROM predict_edb_conf WHERE predict_edb_info_id=? ORDER BY config_id ASC`
	err = global.DmSQL["data"].Raw(sql, edbInfoId).Find(&items).Error
	return
}

// GetGroupPredictEdbBySourceEdbInfoId 根据来源指标id获取配置
func GetGroupPredictEdbBySourceEdbInfoId(sourceEdbInfoId int) (items []*EdbInfo, err error) {
	sql := ` SELECT a.* FROM edb_info AS a 
	JOIN predict_edb_conf AS b  on a.edb_info_id = b.predict_edb_info_id
	     WHERE b.source_edb_info_id=? group by a.edb_info_id`
	err = global.DmSQL["data"].Raw(sql, sourceEdbInfoId).Find(&items).Error
	return
}

// GetGroupPredictEdbInfoIdListBySourceEdbInfoId 根据来源指标id获取配置
func GetGroupPredictEdbInfoIdListBySourceEdbInfoId(sourceEdbInfoId int) (items []int, err error) {
	sql := ` SELECT a.edb_info_id FROM edb_info AS a 
	JOIN predict_edb_conf AS b  on a.edb_info_id = b.predict_edb_info_id
	     WHERE b.source_edb_info_id=? group by a.edb_info_id`
	err = global.DmSQL["data"].Raw(sql, sourceEdbInfoId).Scan(&items).Error
	return
}