package data_manage

import (
	"eta/eta_api/global"
	"eta/eta_api/utils"
	"github.com/rdlucklib/rdluck_tools/paging"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
	"time"
)

type SmmClassify struct {
	TypeName string `orm:"column(type_name)" description:"分类名称"`
	TypeCode string `orm:"column(type_code)" description:"分类名称编码"`
}

func GetSmmClassify() (items []*SmmClassify, err error) {
	sql := `SELECT CONCAT(type_2,type_3) AS type_name,CONCAT(type_2,'#',type_3) type_code  FROM base_from_smm_index GROUP BY CONCAT(type_2,type_3) ORDER BY CONCAT(type_2,type_3) ASC `
	o := global.DbMap[utils.DbNameIndex]
	err = o.Raw(sql).Find(&items).Error
	return
}

type SmmFrequency struct {
	Frequency string `description:"频度"`
}

func GetSmmFrequencyByClassifyId(classifyId int) (items []*GlFrequency, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT frequency FROM base_from_smm_index WHERE classify_id = ? `
	sql += ` GROUP BY frequency ORDER BY frequency ASC `
	err = o.Raw(sql, classifyId).Find(&items).Error
	return
}

type SmmIndex struct {
	BaseFromSmmIndexId int `gorm:"column:base_from_smm_index_id;primaryKey"`
	Interface          string
	Name               string
	IndexCode          string
	IndexName          string
	Type1              string `gorm:"column:type_1"`
	Type2              string `gorm:"column:type_2"`
	Type3              string `gorm:"column:type_3"`
	Frequency          string
	Unit               string
	ApiStartTime       string
	ApiUpdateTime      string
	StartTime          string
	FinishTime         string
	CreateTime         string
	ModifyTime         string
	IsStop             int     `description:"是否停更:1:停更,0:未停更"`
	EndValue           float64 `description:"指标的最新值"`
}

func (obj *SmmIndex) AfterFind(tx *gorm.DB) (err error) {
			obj.CreateTime = utils.GormDateStrToDateTimeStr(obj.CreateTime)
			obj.ModifyTime = utils.GormDateStrToDateTimeStr(obj.ModifyTime)
			obj.StartTime = utils.GormDateStrToDateTimeStr(obj.StartTime)
			obj.FinishTime = utils.GormDateStrToDateTimeStr(obj.FinishTime)
			obj.ApiStartTime = utils.GormDateStrToDateTimeStr(obj.ApiStartTime)
			obj.ApiUpdateTime = utils.GormDateStrToDateTimeStr(obj.ApiUpdateTime)
	return
}

type SmmIndexItem struct {
	BaseFromSmmIndexId int `orm:"column(base_from_smm_index_id);pk" gorm:"primaryKey"`
	ClassifyId         int
	ParentClassifyId   int
	Interface          string
	Name               string
	IndexCode          string
	IndexName          string
	Type1              string `gorm:"column:type_1"`
	Type2              string `gorm:"column:type_2"`
	Type3              string `gorm:"column:type_3"`
	Frequency          string
	Unit               string
	ApiStartTime       string
	ApiUpdateTime      string
	StartTime          string
	FinishTime         string
	CreateTime         string
	ModifyTime         string
	IsStop             int     `description:"是否停更:1:停更,0:未停更"`
	EndValue           float64 `description:"指标的最新值"`
}

func GetSmmIndex(condition string, pars []interface{}) (items []*SmmIndex, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT * FROM base_from_smm_index WHERE 1=1  `
	if condition != "" {
		sql += condition
	}
	sql += `ORDER BY sort ASC, base_from_smm_index_id asc`
	err = o.Raw(sql, pars...).Find(&items).Error
	return
}

// GetSmmIndexById
// @Description: 根据id获取指标信息
// @author: Roc
// @datetime 2024-01-10 14:25:26
// @param basFromSmmIndexId int
// @return item *SmmIndex
// @return err error
func GetSmmIndexById(basFromSmmIndexId int) (item *SmmIndex, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT * FROM base_from_smm_index WHERE base_from_smm_index_id = ?  `
	err = o.Raw(sql, basFromSmmIndexId).Find(&item).Error

	return
}

type SmmExportIndex struct {
	TypeName   string
	IndexCode  string
	IndexName  string
	Type1      string `gorm:"column:type_1"`
	Type2      string `gorm:"column:type_2"`
	Type3      string `gorm:"column:type_3"`
	Frequency  string
	Unit       string
	ModifyTime string
}

func GetExportSmmIndex(typeCodes []string) (items []*SmmExportIndex, err error) {
	if len(typeCodes) == 0 {
		return
	}
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT *,CONCAT(type_2, "#", type_3) AS type_name FROM base_from_smm_index WHERE CONCAT(type_2, "#", type_3) IN (` + utils.GetOrmInReplace(len(typeCodes)) + `) ORDER BY frequency ASC,index_code ASC`
	err = o.Raw(sql, typeCodes).Find(&items).Error
	return
}

func GetSmmFrequency(classifyId int) (items []*string, err error) {
	sql := `SELECT DISTINCT frequency FROM base_from_smm_index WHERE classify_id=? ORDER BY FIELD(frequency,'日度','周度','月度','季度','半年','年度') `
	o := global.DbMap[utils.DbNameIndex]
	err = o.Raw(sql, classifyId).Find(&items).Error
	return
}

func GetSmmFrequencyByCode(code string) (items []*string, err error) {
	sql := `SELECT DISTINCT frequency FROM base_from_smm_index WHERE index_code=? ORDER BY FIELD(frequency,'日度','周度','月度','季度','半年','年度') `
	o := global.DbMap[utils.DbNameIndex]
	err = o.Raw(sql, code).Find(&items).Error
	return
}

type SmmIndexList struct {
	BaseFromSmmIndexId int `gorm:"column:base_from_smm_index_id);primaryKey"`
	Interface          string
	Name               string
	IndexCode          string
	IndexName          string
	Type1              string `gorm:"column:type_1"`
	Type2              string `gorm:"column:type_2"`
	Type3              string `gorm:"column:type_3"`
	Frequency          string
	Unit               string
	ApiStartTime       string
	ApiUpdateTime      string
	StartTime          string
	FinishTime         string
	ModifyTime         string
	DataList           []*SmmIndexData    `gorm:"-"`
	Paging             *paging.PagingItem `description:"分页数据" gorm:"-"`
}

type SmmIndexData struct {
	Value    decimal.Decimal `gorm:"column:value" description:"日期"`
	DataTime string          `gorm:"column:data_time" description:"值"`
}

func (m *SmmIndexData) AfterFind(tx *gorm.DB) (err error) {
			m.DataTime = utils.GormDateStrToDateStr(m.DataTime)
	return
}
func GetSmmIndexData(indexCode string, startSize, pageSize int) (items []*SmmIndexData, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT *  FROM base_from_smm_data WHERE index_code=? ORDER BY data_time DESC LIMIT ?,? `
	err = o.Raw(sql, indexCode, startSize, pageSize).Find(&items).Error
	return
}

func GetSmmIndexDataCount(indexCode string) (count int, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT COUNT(1) AS count  FROM base_from_smm_data WHERE index_code=? `
	err = o.Raw(sql, indexCode).Scan(&count).Error
	return
}

// GetSmmItemList 模糊查询Smm数据库指标列表
func GetSmmItemList(keyword string) (items []*SmmIndexItem, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := "SELECT * FROM base_from_smm_index WHERE CONCAT(index_name,index_code) LIKE ? "
	err = o.Raw(sql, utils.GetLikeKeyword(keyword)).Find(&items).Error
	return
}

func GetSmmIndexDataByCode(indexCode string) (items []*SmmIndexData, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT *  FROM base_from_smm_data WHERE index_code=? ORDER BY data_time DESC  `
	err = o.Raw(sql, indexCode).Find(&items).Error
	return
}

func GetSmmDataMaxCount(classifyId int) (count int, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := `SELECT COALESCE(MAX(t.num), 0) AS count FROM (
				SELECT COUNT(1) AS num  FROM base_from_smm_index AS a
				INNER JOIN base_from_smm_data AS b ON a.index_code=b.index_code
				WHERE a.classify_id=?
				GROUP BY a.base_from_smm_index_id
			)AS t `
	err = o.Raw(sql, classifyId).Scan(&count).Error
	return
}

type ExportSmmDataMaxCount struct {
	TypeName string
	Count    int
}

func GetExportSmmDataMaxCount(typeCodes []string) (items []*ExportSmmDataMaxCount, err error) {
	if len(typeCodes) == 0 {
		return
	}
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT
				COALESCE(MAX(t.num), 0) AS count,
				t.type_name
			FROM
				(
					SELECT
						COUNT(1) AS num,
						CONCAT(a.type_2, "#", a.type_3) AS type_name
					FROM
						base_from_smm_index AS a
					INNER JOIN base_from_smm_data AS b ON a.index_code = b.index_code
					WHERE
						CONCAT(a.type_2, "#", a.type_3) IN (` + utils.GetOrmInReplace(len(typeCodes)) + `)
					GROUP BY
						a.base_from_smm_index_id
				) AS t
			GROUP BY
				type_name `
	err = o.Raw(sql, typeCodes).Find(&items).Error
	return
}

type ExportSmmIndexData struct {
	Value     string `orm:"column(value)" description:"日期"`
	DataTime  string `orm:"column(data_time)" description:"值"`
	IndexCode string `orm:"column(index_code)" description:"指标编码"`
}

func GetExportSmmIndexDataByCodes(indexCodes []string) (items []*ExportSmmIndexData, err error) {
	if len(indexCodes) == 0 {
		return
	}
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT index_code,data_time,value FROM base_from_smm_data WHERE index_code IN (` + utils.GetOrmInReplace(len(indexCodes)) + `) ORDER BY data_time DESC  `
	err = o.Raw(sql, indexCodes).Find(&items).Error
	return
}

// GetSmmBaseInfoList
// @Description: 获取有色数据列表
// @author: Roc
// @datetime 2024-01-10 14:28:29
// @param condition string
// @param pars []interface{}
// @param orderBy string
// @param startSize int
// @param pageSize int
// @return total int
// @return items []*BaseRefreshEdbInfo
// @return err error
func GetSmmBaseInfoList(condition string, pars []interface{}, orderBy string, startSize, pageSize int) (total int, items []*BaseRefreshEdbInfo, err error) {
	o := global.DbMap[utils.DbNameIndex]

	// 数量汇总
	totalSql := ` SELECT count(1) FROM base_from_smm_index WHERE 1=1 `
	if condition != "" {
		totalSql += condition
	}
	err = o.Raw(totalSql, pars...).Scan(&total).Error
	if err != nil {
		return
	}

	// 列表数据
	sql := ` SELECT base_from_smm_index_id as edb_info_id, classify_id,index_code,index_name,end_date,end_value,frequency,is_stop,terminal_code FROM base_from_smm_index WHERE 1=1  `
	if condition != "" {
		sql += condition
	}

	if orderBy != "" {
		sql += ` ORDER BY ` + orderBy
	} else {
		sql += ` ORDER BY base_from_smm_index_id ASC `
	}
	sql += `  LIMIT ?,? `

	pars = append(pars, startSize, pageSize)
	err = o.Raw(sql, pars...).Find(&items).Error
	return
}

// ModifySmmUpdateStatus
// @Description:  修改有色数据停更状态
// @author: Roc
// @datetime 2024-01-08 16:23:31
// @param edbIdList []int
// @param indexCodeList []string
// @param isStop int
// @return err error
func ModifySmmUpdateStatus(edbIdList []int, indexCodeList []string, isStop int) (err error) {
	idNum := len(edbIdList)
	if idNum <= 0 {
		return
	}
	o := global.DbMap[utils.DbNameIndex].Begin()
	defer func() {
		if err != nil {
			_ = o.Rollback()
			return
		}
		_ = o.Commit()
	}()

	// 更改数据源的更新状态
	sql := ` UPDATE base_from_smm_index SET is_stop = ? WHERE base_from_smm_index_id IN (` + utils.GetOrmInReplace(idNum) + `) `
	err = o.Exec(sql, isStop, edbIdList).Error
	if err != nil {
		return
	}

	codeNum := len(indexCodeList)
	if codeNum <= 0 {
		// 需要通过指标id列表查找code列表
		sql := ` SELECT index_code FROM base_from_smm_index WHERE base_from_smm_index_id IN (` + utils.GetOrmInReplace(idNum) + `) `
		err = o.Raw(sql, edbIdList).Scan(&indexCodeList).Error
		if err != nil {
			return
		}
	}

	codeNum = len(indexCodeList)
	// 查出来的编码是空的话,那么就直接返回了
	if codeNum <= 0 {
		return
	}

	// 更改指标的更新状态
	sql = ` UPDATE edb_info SET no_update = ?, set_update_time=? WHERE source = ? AND sub_source= ? AND edb_code IN (` + utils.GetOrmInReplace(codeNum) + `) `
	err = o.Exec(sql, isStop, time.Now(), utils.DATA_SOURCE_YS, 0, indexCodeList).Error
	if err != nil {
		return
	}

	return
}