package data_manage

import (
	"eta/eta_api/global"
	"eta/eta_api/models/mgo"
	"eta/eta_api/utils"
	"fmt"
	"strconv"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"gorm.io/gorm"
)

// GetEdbDataTableName 指标数据->存储表
func GetEdbDataTableName(source, subSource int) (tableName string) {
	switch source {
	case utils.DATA_SOURCE_THS:
		switch subSource {
		case utils.DATA_SUB_SOURCE_DATE:
			tableName = "edb_data_ths_ds"
		case utils.DATA_SUB_SOURCE_HIGH_FREQUENCY:
			tableName = "edb_data_ths_hf"
		default:
			tableName = "edb_data_ths"
		}
	case utils.DATA_SOURCE_WIND:
		if subSource == utils.DATA_SUB_SOURCE_DATE {
			tableName = "edb_data_wind_wsd"
		} else {
			tableName = "edb_data_wind"
		}
	case utils.DATA_SOURCE_PB, utils.DATA_SOURCE_PB_FINANCE: //彭博经济数据、彭博财务数据
		tableName = "edb_data_pb"
	case utils.DATA_SOURCE_CALCULATE:
		tableName = "edb_data_calculate"
	case utils.DATA_SOURCE_CALCULATE_LJZZY:
		tableName = "edb_data_calculate_ljzzy"
	case utils.DATA_SOURCE_CALCULATE_TBZ:
		tableName = "edb_data_calculate_tbz"
	case utils.DATA_SOURCE_CALCULATE_TCZ:
		tableName = "edb_data_calculate_tcz"
	case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS:
		tableName = "edb_data_calculate_nszydpjjs"
	case utils.DATA_SOURCE_MANUAL:
		tableName = "edb_data_manual"
	case utils.DATA_SOURCE_LZ:
		tableName = "edb_data_lz"
	case utils.DATA_SOURCE_YS:
		tableName = "edb_data_ys"
	case utils.DATA_SOURCE_CALCULATE_HBZ:
		tableName = "edb_data_calculate_hbz"
	case utils.DATA_SOURCE_CALCULATE_HCZ:
		tableName = "edb_data_calculate_hcz"
	case utils.DATA_SOURCE_CALCULATE_BP:
		tableName = "edb_data_calculate_bp"
	case utils.DATA_SOURCE_GL:
		tableName = "edb_data_gl"
	case utils.DATA_SOURCE_ZZ:
		tableName = "edb_data_zz"
	case utils.DATA_SOURCE_DL:
		tableName = "edb_data_dl"
	case utils.DATA_SOURCE_SH:
		tableName = "edb_data_sh"
	case utils.DATA_SOURCE_CFFEX:
		tableName = "edb_data_cffex"
	case utils.DATA_SOURCE_SHFE:
		tableName = "edb_data_ine"
	case utils.DATA_SOURCE_GIE:
		tableName = "edb_data_gie"
	case utils.DATA_SOURCE_CALCULATE_ZJPJ:
		tableName = "edb_data_calculate_zjpj"
	case utils.DATA_SOURCE_CALCULATE_TIME_SHIFT:
		tableName = "edb_data_calculate_time_shift"
	case utils.DATA_SOURCE_CALCULATE_LJZTBPJ:
		tableName = "edb_data_calculate_ljztbpj"
	case utils.DATA_SOURCE_LT:
		tableName = "edb_data_lt"
	case utils.DATA_SOURCE_COAL:
		tableName = "edb_data_coal"
	case utils.DATA_SOURCE_PYTHON:
		tableName = "edb_data_python"
	case utils.DATA_SOURCE_GOOGLE_TRAVEL:
		tableName = "edb_data_google_travel"
	case utils.DATA_SOURCE_PREDICT_CALCULATE:
		tableName = "edb_data_predict_calculate"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_TBZ:
		tableName = "edb_data_predict_calculate_tbz"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_TCZ:
		tableName = "edb_data_predict_calculate_tcz"
	case utils.DATA_SOURCE_MYSTEEL_CHEMICAL:
		tableName = "edb_data_mysteel_chemical"
	case utils.DATA_SOURCE_CALCULATE_CJJX:
		tableName = "edb_data_calculate_cjjx"
	case utils.DATA_SOURCE_EIA_STEO:
		tableName = "edb_data_eia_steo"
	case utils.DATA_SOURCE_CALCULATE_NHCC:
		tableName = "edb_data_calculate_nhcc"
	case utils.DATA_SOURCE_COM_TRADE:
		tableName = "edb_data_com_trade"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS:
		tableName = "edb_data_predict_calculate_nszydpjjs"
	case utils.DATA_SOURCE_CALCULATE_ADJUST:
		tableName = "edb_data_calculate_adjust"
	case utils.DATA_SOURCE_SCI:
		tableName = "edb_data_sci"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZZY:
		tableName = "edb_data_predict_calculate_ljzzy"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_TIME_SHIFT:
		tableName = "edb_data_predict_calculate_time_shift"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_ZJPJ:
		tableName = "edb_data_predict_calculate_zjpj"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZTBPJ:
		tableName = "edb_data_predict_calculate_ljztbpj"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_NHCC:
		tableName = "edb_data_predict_calculate_nhcc"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_CJJX:
		tableName = "edb_data_predict_calculate_cjjx"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_HBZ:
		tableName = "edb_data_predict_calculate_hbz"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_HCZ:
		tableName = "edb_data_predict_calculate_hcz"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_BP:
		tableName = "edb_data_predict_calculate_bp"
	case utils.DATA_SOURCE_CALCULATE_JP:
		tableName = "edb_data_calculate_jp"
	case utils.DATA_SOURCE_CALCULATE_NH:
		tableName = "edb_data_calculate_nh"
	case utils.DATA_SOURCE_CALCULATE_KSZS:
		tableName = "edb_data_calculate_kszs"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_JP:
		tableName = "edb_data_predict_calculate_jp"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_NH:
		tableName = "edb_data_predict_calculate_nh"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_KSZS:
		tableName = "edb_data_predict_calculate_kszs"
	case utils.DATA_SOURCE_BAIINFO:
		tableName = "edb_data_baiinfo"
	case utils.DATA_SOURCE_STOCK_PLANT:
		tableName = "edb_data_stock_plant"
	case utils.DATA_SOURCE_CALCULATE_CORRELATION:
		tableName = "edb_data_calculate_correlation"
	case utils.DATA_SOURCE_NATIONAL_STATISTICS:
		tableName = "edb_data_national_statistics"
	case utils.DATA_SOURCE_CALCULATE_LJZZJ: //累计值转季 -> 61
		tableName = "edb_data_calculate_ljzzj"
	case utils.DATA_SOURCE_CALCULATE_LJZ: //累计值 -> 62
		tableName = "edb_data_calculate_ljz"
	case utils.DATA_SOURCE_CALCULATE_LJZNCZJ: //累计值(年初至今) -> 63
		tableName = "edb_data_calculate_ljznczj"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZZJ: // 预测指标 - 累计值 -> 65
		tableName = "edb_data_predict_calculate_ljzzj"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZ: //预测指标 - 累计值转季->64
		tableName = "edb_data_predict_calculate_ljz"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_LJZNCZJ: //预测指标 - 累计值(年初至今) -> 66
		tableName = "edb_data_predict_calculate_ljznczj"
	case utils.DATA_SOURCE_CALCULATE_STANDARD_DEVIATION: //标准差->67
		tableName = "edb_data_calculate_standard_deviation"
	case utils.DATA_SOURCE_CALCULATE_PERCENTILE: //百分位->68
		tableName = "edb_data_calculate_percentile"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_STANDARD_DEVIATION: //预测标准差->69
		tableName = "edb_data_predict_ccalculate_standard_deviation"
	case utils.DATA_SOURCE_PREDICT_CALCULATE_PERCENTILE: //预测百分位->70
		tableName = "edb_data_predict_ccalculate_percentile"
	case utils.DATA_SOURCE_FUBAO: //富宝-71
		tableName = "edb_data_fubao"
	case utils.DATA_SOURCE_CALCULATE_ZSXY:
		tableName = "edb_data_calculate_zsxy" // 指数修匀->72
	case utils.DATA_SOURCE_PREDICT_CALCULATE_ZSXY:
		tableName = "edb_data_predict_calculate_zsxy" // 预测指数修匀->73
	case utils.DATA_SOURCE_CALCULATE_ZDYFX:
		tableName = "edb_data_calculate_zdyfx" // 自定义分析->74
	case utils.DATA_SOURCE_CALCULATE_RJZ: //日均值->75
		tableName = "edb_data_calculate_rjz"
	case utils.DATA_SOURCE_GFEX: //广州期货交易所->78
		tableName = "edb_data_gz"
	case utils.DATA_SOURCE_ICPI: //ICPI消费价格指数->79
		tableName = "edb_data_icpi"
	case utils.DATA_SOURCE_SCI99: //ICPI消费价格指数->85
		tableName = "edb_data_sci99"
	case utils.DATA_SOURCE_SCI_HQ:
		tableName = "edb_data_sci_hq"
	case utils.DATA_SOURCE_PREDICT: // 基础预测指标->30
		tableName = "edb_data_predict_base"
	case utils.DATA_SOURCE_LY: // 粮油商务网->86
		tableName = "edb_data_ly"
	case utils.DATA_SOURCE_TRADE_ANALYSIS: // 持仓分析->92
		tableName = "edb_data_trade_analysis"
	case utils.DATA_SOURCE_CALCULATE_STL:
		tableName = "edb_data_calculate_stl"
	default:
		edbSource := EdbSourceIdMap[source]
		if edbSource != nil {
			tableName = edbSource.TableName
		}
	}
	return
}

//计算指标->关联的基础指标表
//func GetEdbInfoCalculateTableName(source int) (tableName string) {
//	switch source {
//	case utils.DATA_SOURCE_CALCULATE:
//		tableName = "edb_info_calculate"
//	case utils.DATA_SOURCE_CALCULATE_LJZZY:
//		tableName = "edb_info_calculate_ljzzy"
//	case utils.DATA_SOURCE_CALCULATE_TBZ:
//		tableName = "edb_info_calculate_tbz"
//	case utils.DATA_SOURCE_CALCULATE_TCZ:
//		tableName = "edb_info_calculate_tcz"
//	case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS:
//		tableName = "edb_info_calculate_nszydpjjs"
//	case utils.DATA_SOURCE_CALCULATE_HBZ:
//		tableName = "edb_info_calculate_hbz"
//	case utils.DATA_SOURCE_CALCULATE_HCZ:
//		tableName = "edb_info_calculate_hcz"
//	case utils.DATA_SOURCE_CALCULATE_BP:
//		tableName = "edb_info_calculate_bp"
//	default:
//		tableName = ""
//	}
//	return
//}

type EdbDataBase struct {
	//EdbDataId     int `orm:"column(edb_data_id);pk"`
	EdbDataId     int `gorm:"column:edb_data_id;primaryKey"`
	EdbInfoId     int
	EdbCode       string
	DataTime      string
	Value         string
	Status        int
	CreateTime    time.Time
	ModifyTime    time.Time
	DataTimestamp int64
}

func (e *EdbDataBase) AfterFind(tx *gorm.DB) (err error) {
	e.DataTime = utils.GormDateStrToDateStr(e.DataTime)
	return
}

func GetEdbDataAllByEdbCode(edbCode string, source, subSource, limit int) (items []*EdbInfoSearchData, err error) {
	// 自有数据需要额外处理(从mongo获取)
	if source == utils.DATA_SOURCE_BUSINESS && utils.UseMongo {
		return GetEdbDataAllByEdbCodeByMongo(edbCode, source, subSource, limit)
	}
	if source == utils.DATA_SOURCE_THS && subSource == utils.DATA_SUB_SOURCE_HIGH_FREQUENCY && utils.UseMongo {
		return GetThsHfEdbDataAllByEdbCodeByMongo(edbCode, source, subSource, limit)
	}

	return GetEdbDataAllByEdbCodeByMysql(edbCode, source, subSource, limit)
}

func GetEdbDataAllByEdbCodeByMysql(edbCode string, source, subSource, limit int) (items []*EdbInfoSearchData, err error) {
	var pars []interface{}
	pars = append(pars, edbCode)
	//o := orm.NewOrmUsingDB("data")

	tableName := GetEdbDataTableName(source, subSource)
	sql := ` SELECT * FROM %s WHERE edb_code=? ORDER BY data_time DESC`
	if limit > 0 {
		sql += `  LIMIT ?  `
		pars = append(pars, limit)
	}
	sql = fmt.Sprintf(sql, tableName)
	//_, err = o.Raw(sql, pars...).QueryRows(&items)
	err = global.DbMap[utils.DbNameIndex].Raw(sql, pars...).Find(&items).Error
	return
}

func GetEdbDataBaseByEdbInfoId(edbInfoId int, source, subSource int) (items []*EdbDataBase, err error) {
	//o := orm.NewOrmUsingDB("data")
	tableName := GetEdbDataTableName(source, subSource)
	if source == utils.DATA_SOURCE_PREDICT {
		tableName = "edb_data_predict_base"
	}
	sql := ` SELECT * FROM %s WHERE edb_info_id=? ORDER BY data_time DESC`
	sql = fmt.Sprintf(sql, tableName)
	//_, err = o.Raw(sql, edbInfoId).QueryRows(&items)
	err = global.DbMap[utils.DbNameIndex].Raw(sql, edbInfoId).Find(&items).Error
	return
}

func GetEdbDataBaseMongoByEdbInfoId(edbInfoId int, source, subSource int) (list []*EdbDataBase, err error) {
	list = make([]*EdbDataBase, 0)

	mogDataObj := mgo.EdbDataBusiness{}
	// 构建查询条件
	queryConditions := bson.M{
		"edb_info_id": edbInfoId,
	}
	// 获取列表数据
	tmpDataList, tmpErr := mogDataObj.GetAllDataList(queryConditions, []string{"data_time"})
	if tmpErr != nil {
		err = tmpErr
		return
	}
	for k, v := range tmpDataList {

		list = append(list, &EdbDataBase{
			EdbDataId:     k + 1,
			EdbInfoId:     v.EdbInfoId,
			EdbCode:       v.EdbCode,
			DataTime:      v.DataTime.Format(utils.FormatDate),
			DataTimestamp: v.DataTimestamp,
			Value:         strconv.FormatFloat(v.Value, 'f', -1, 64),
		})
	}

	return
}

func GetEdbDataAllByEdbCodeByMongo(edbCode string, source, subSource, limit int) (list []*EdbInfoSearchData, err error) {
	list = make([]*EdbInfoSearchData, 0)

	mogDataObj := mgo.EdbDataBusiness{}
	// 构建查询条件
	queryConditions := bson.M{
		"edb_code": edbCode,
	}

	var tmpDataList []*mgo.EdbDataBusiness
	// 获取列表数据
	if limit > 0 {
		tmpDataList, err = mogDataObj.GetLimitDataList(queryConditions, int64(limit), []string{"-data_time"})
	} else {
		tmpDataList, err = mogDataObj.GetLimitDataList(queryConditions, int64(limit), []string{"-data_time"})
	}
	if err != nil {
		return
	}
	for _, v := range tmpDataList {
		list = append(list, &EdbInfoSearchData{
			DataTime: v.DataTime.Format(utils.FormatDate),
			Value:    v.Value,
		})
	}
	return
}

func GetBaseIndexInfoByEdbCode(edbCode string, source int) (item *BaseIndexInfo, err error) {
	var pars []interface{}
	pars = append(pars, edbCode)
	//o := orm.NewOrmUsingDB("data")

	tableName := GetBaseIndexTableName(source)
	if tableName == "" {
		err = fmt.Errorf("未找到对应的表")
		return
	}
	sql := ` SELECT * FROM %s WHERE index_code=? `

	sql = fmt.Sprintf(sql, tableName)
	//err = o.Raw(sql, pars).QueryRow(&item)
	err = global.DbMap[utils.DbNameIndex].Raw(sql, pars...).Find(&item).Error
	return
}

func GetBaseIndexTableName(source int) (tableName string) {
	edbSource := EdbSourceIdMap[source]
	if edbSource != nil {
		tableName = edbSource.IndexTableName
	}
	return
}
func GetEdbDataAllByEdbCodeAndSubSource(edbCode string, source, subSource, limit int) (items []*EdbInfoSearchData, err error) {
	var pars []interface{}
	pars = append(pars, edbCode)
	//o := orm.NewOrmUsingDB("data")

	tableName := GetEdbDataTableNameAndSubSource(source, subSource)
	sql := ` SELECT * FROM %s WHERE edb_code=? ORDER BY data_time DESC`
	if limit > 0 {
		sql += `  LIMIT ?  `
		pars = append(pars, limit)
	}
	sql = fmt.Sprintf(sql, tableName)
	//_, err = o.Raw(sql, pars).QueryRows(&items)
	err = global.DbMap[utils.DbNameIndex].Raw(sql, pars...).Find(&items).Error
	return
}

// GetEdbDataTableNameAndSubSource 指标数据->存储表
func GetEdbDataTableNameAndSubSource(source, subSource int) (tableName string) {
	switch source {
	case utils.DATA_SOURCE_WIND:
		if subSource == utils.DATA_SUB_SOURCE_EDB {
			tableName = "edb_data_wind"
		} else {
			tableName = "edb_data_wind_wsd"
		}
	case utils.DATA_SOURCE_THS:
		if subSource == utils.DATA_SUB_SOURCE_EDB {
			tableName = "edb_data_ths"
		} else {
			tableName = "edb_data_ths_ds"
		}
	case utils.DATA_SOURCE_YS:
		tableName = "edb_data_ys"
	default:
		edbSource := EdbSourceIdMap[source]
		if edbSource != nil {
			tableName = edbSource.TableName
		}
	}
	return
}

func GetEdbDataAllByEdbCodes(edbCodes []string, limit int) (items []*EdbInfoSearchData, err error) {
	var pars []interface{}
	pars = append(pars, edbCodes)
	//o := orm.NewOrmUsingDB("data")

	//sql := ` SELECT * FROM edb_data_ys WHERE edb_code IN (` + utils.GetOrmInReplace(len(edbCodes)) + `) ORDER BY data_time DESC`
	sql := ` SELECT * FROM edb_data_ys WHERE edb_code IN ? ORDER BY data_time DESC`
	if limit > 0 {
		sql += `  LIMIT ?  `
		pars = append(pars, limit)
	}
	//_, err = o.Raw(sql, pars).QueryRows(&items)
	err = global.DbMap[utils.DbNameIndex].Raw(sql, pars...).Find(&items).Error
	return
}

func GetAddSql(edbInfoId, edbCode, dataTime, timestampStr string, value string) (addSql string) {
	nowStr := time.Now().Format(utils.FormatDateTime)
	addSql += "("
	addSql += edbInfoId + "," + "'" + edbCode + "'" + "," + "'" + dataTime + "'" + "," + value + "," + "'" + nowStr + "'" +
		"," + "'" + nowStr + "'" + "," + "1"
	addSql += "," + "'" + timestampStr + "'"
	addSql += "),"
	return
}

func GetThsHfEdbDataAllByEdbCodeByMongo(edbCode string, source, subSource, limit int) (list []*EdbInfoSearchData, err error) {
	list = make([]*EdbInfoSearchData, 0)

	mogDataObj := mgo.EdbDataThsHf{}
	// 构建查询条件
	queryConditions := bson.M{
		"edb_code": edbCode,
	}

	var tmpDataList []*mgo.EdbDataThsHf
	// 获取列表数据
	if limit > 0 {
		tmpDataList, err = mogDataObj.GetLimitDataList(queryConditions, int64(limit), []string{"-data_time"})
	} else {
		tmpDataList, err = mogDataObj.GetLimitDataList(queryConditions, int64(limit), []string{"-data_time"})
	}
	if err != nil {
		return
	}
	for _, v := range tmpDataList {
		list = append(list, &EdbInfoSearchData{
			DataTime: v.DataTime.Format(utils.FormatDate),
			Value:    v.Value,
		})
	}
	return
}

func GetThsHfEdbDataBaseMongoByEdbInfoId(edbInfoId int, source, subSource int) (list []*EdbDataBase, err error) {
	list = make([]*EdbDataBase, 0)

	mogDataObj := mgo.EdbDataThsHf{}
	// 构建查询条件
	queryConditions := bson.M{
		"edb_info_id": edbInfoId,
	}
	// 获取列表数据
	tmpDataList, tmpErr := mogDataObj.GetAllDataList(queryConditions, []string{"data_time"})
	if tmpErr != nil {
		err = tmpErr
		return
	}
	for k, v := range tmpDataList {

		list = append(list, &EdbDataBase{
			EdbDataId:     k + 1,
			EdbInfoId:     v.EdbInfoId,
			EdbCode:       v.EdbCode,
			DataTime:      v.DataTime.Format(utils.FormatDate),
			DataTimestamp: v.DataTimestamp,
			Value:         strconv.FormatFloat(v.Value, 'f', -1, 64),
		})
	}

	return
}