package data_manage

import (
	"eta/eta_mobile/services/alarm_msg"
	"eta/eta_mobile/utils"
	"github.com/beego/beego/v2/client/orm"
	"time"
)

type PredictEdbConf struct {
	ConfigId         int       `orm:"column(config_id);pk" 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" 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:"添加时间"`
	CalculateList    []*PredictEdbConfCalculateMappingDetail `description:"配置与指标的关联信息"`
}

// PredictEdbConfAndData 预测规则和其对应的动态数据
type PredictEdbConfAndData struct {
	ConfigId         int            `orm:"column(config_id);pk" 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:"动态数据"`
}

// GetPredictEdbConfById 根据预测指标id获取预测指标配置信息
func GetPredictEdbConfById(edbInfoId int) (item *PredictEdbConf, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` SELECT * FROM predict_edb_conf WHERE predict_edb_info_id=? `
	err = o.Raw(sql, edbInfoId).QueryRow(&item)
	return
}

// GetPredictEdbConfBySourceEdbInfoId 根据来源指标id获取配置
func GetPredictEdbConfBySourceEdbInfoId(sourceEdbInfoId int) (item *PredictEdbConf, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` SELECT * FROM predict_edb_conf WHERE source_edb_info_id=? `
	err = o.Raw(sql, sourceEdbInfoId).QueryRow(&item)
	return
}

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

// AddPredictEdbConf 添加预测指标规则
func AddPredictEdbConf(item *PredictEdbConf) (lastId int64, err error) {
	o := orm.NewOrmUsingDB("data")
	lastId, err = o.Insert(item)
	return
}

// AddPredictEdb 添加预测指标
func AddPredictEdb(item *EdbInfo, calculateMappingItem *EdbInfoCalculateMapping, predictEdbConfList []*PredictEdbConf) (err error) {
	o := orm.NewOrmUsingDB("data")
	tx, err := o.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			tmpErr := tx.Rollback()
			if tmpErr != nil {
				go alarm_msg.SendAlarmMsg("AddPredictEdb 事务回滚失败,Err:"+tmpErr.Error(), 3)
			}
		} else {
			err = tx.Commit()
		}
	}()
	// 新增预测指标
	edbInfoId, err := o.Insert(item)
	if err != nil {
		return
	}
	item.EdbInfoId = int(edbInfoId)

	// 新增预测指标
	calculateMappingItem.EdbInfoId = item.EdbInfoId
	_, err = o.Insert(calculateMappingItem)
	if err != nil {
		return
	}

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

// EditPredictEdb 修改预测指标
func EditPredictEdb(edbInfo *EdbInfo, predictEdbConfList []*PredictEdbConf, updateEdbInfoCol []string) (err error) {
	o := orm.NewOrmUsingDB("data")
	tx, err := o.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			tmpErr := tx.Rollback()
			if tmpErr != nil {
				go alarm_msg.SendAlarmMsg("AddPredictEdb 事务回滚失败,Err:"+tmpErr.Error(), 3)
			}
		} else {
			err = tx.Commit()
		}
	}()
	// 修改预测指标
	_, err = o.Update(edbInfo, updateEdbInfoCol...)
	if err != nil {
		return
	}

	// 先删除原有的配置
	sql := ` DELETE FROM predict_edb_conf WHERE predict_edb_info_id = ?`
	_, err = o.Raw(sql, edbInfo.EdbInfoId).Exec()
	if err != nil {
		return
	}

	// 新增新有的预测指标配置
	lenPredictEdbConf := len(predictEdbConfList)
	if lenPredictEdbConf > 0 {
		_, err = o.InsertMulti(lenPredictEdbConf, predictEdbConfList)
		if err != nil {
			return
		}
	}
	return
}

// GetPredictEdbInfoAllCalculate 根据基础预测指标id集合 获取 所有的普通指标列表数据
func GetPredictEdbInfoAllCalculate(edbInfoIdList []int) (list []*EdbInfo, err error) {
	num := len(edbInfoIdList)
	if num <= 0 {
		return
	}
	o := orm.NewOrmUsingDB("data")
	sql := ` SELECT 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) + `)
			 GROUP BY a.source_edb_info_id
			 ORDER BY a.source_edb_info_id ASC `
	_, err = o.Raw(sql, edbInfoIdList).QueryRows(&list)
	return
}

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

// GetGroupPredictEdbBySourceEdbInfoId 根据来源指标id获取配置
func GetGroupPredictEdbBySourceEdbInfoId(sourceEdbInfoId int) (items []*EdbInfo, err error) {
	o := orm.NewOrmUsingDB("data")
	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 = o.Raw(sql, sourceEdbInfoId).QueryRows(&items)
	return
}