package future_good

import (
	"errors"
	"eta/eta_index_lib/utils"
	"github.com/beego/beego/v2/client/orm"
	"time"
)

type FutureGoodEdbInfo struct {
	FutureGoodEdbInfoId int       `orm:"column(future_good_edb_info_id);pk"`
	FutureGoodEdbCode   string    `description:"期货指标code"`
	FutureGoodEdbName   string    `description:"期货指标名称"`
	FutureGoodEdbNameEn string    `description:"期货指标英文名称"`
	ParentId            int       `description:"上级期货id"`
	RegionType          string    `description:"交易所来源,海外还是国内"`
	Exchange            string    `description:"所属交易所"`
	FutureGoodEdbType   int       `description:"指标类型,1:年月是固定的合约;2:只有M+N期的合约,未固定年月"`
	DateSourceId        int       `description:"画图时,日期来源的指标id"`
	Year                int       `description:"所属年份"`
	Month               int       `description:"所属月份"`
	StartDate           string    `description:"起始日期"`
	EndDate             string    `description:"终止日期"`
	MinValue            float64   `description:"最小值"`
	MaxValue            float64   `description:"最大值"`
	LatestValue         float64   `description:"数据最新的值"`
	LatestDate          time.Time `description:"数据最新的日期"`
	ServerUrl           string    `description:"服务器地址"`
	TerminalCode        string    `description:"终端编码,用于配置在机器上"`
	CreateTime          time.Time
	ModifyTime          time.Time
}

// GetFutureGoodEdbInfo 期货指标
func GetFutureGoodEdbInfo(edbInfoId int) (item *FutureGoodEdbInfo, err error) {
	o := orm.NewOrm()
	sql := `SELECT * FROM future_good_edb_info WHERE future_good_edb_info_id = ? `
	sql += ` ORDER BY future_good_edb_info_id DESC `
	err = o.Raw(sql, edbInfoId).QueryRow(&item)
	return
}

// GetFutureGoodEdbInfoByCode 根据指标code获取指标信息
func GetFutureGoodEdbInfoByCode(edbCode string) (item *FutureGoodEdbInfo, err error) {
	o := orm.NewOrm()
	sql := `SELECT * FROM future_good_edb_info  WHERE future_good_edb_code = ? limit 1 `
	err = o.Raw(sql, edbCode).QueryRow(&item)
	return
}

// GetFutureGoodEdbInfoList 获取指标数据列表
func GetFutureGoodEdbInfoList(condition string, pars []interface{}) (list []*FutureGoodEdbInfo, err error) {
	o := orm.NewOrm()
	sql := `SELECT * FROM future_good_edb_info WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += `ORDER BY future_good_edb_info_id DESC `
	_, err = o.Raw(sql, pars).QueryRows(&list)
	return
}

// GetAllFutureGoodEdbInfoList 获取指标数据列表
func GetAllFutureGoodEdbInfoList() (list []*FutureGoodEdbInfo, err error) {
	o := orm.NewOrm()
	sql := `SELECT * FROM future_good_edb_info  ORDER BY future_good_edb_info_id DESC `
	_, err = o.Raw(sql).QueryRows(&list)
	return
}

// AddFutureGoodEdbInfo 添加期货数据库指标
func AddFutureGoodEdbInfo(item *FutureGoodEdbInfo) (err error) {
	o := orm.NewOrm()
	lastId, err := o.Insert(item)
	if err != nil {
		return
	}
	item.FutureGoodEdbInfoId = int(lastId)
	return
}

// GetChildFutureGoodEdbInfoListByParentId 根据父级ID获取下面所有的指标数据列表
func GetChildFutureGoodEdbInfoListByParentId(parentId int) (list []*FutureGoodEdbInfo, err error) {
	o := orm.NewOrm()
	sql := `SELECT * FROM future_good_edb_info WHERE parent_id = ? ORDER BY future_good_edb_info_id ASC `
	_, err = o.Raw(sql, parentId).QueryRows(&list)
	return
}

// Update 更新指标基础信息
func (FutureGoodEdbInfo *FutureGoodEdbInfo) Update(cols []string) (err error) {
	o := orm.NewOrm()
	_, err = o.Update(FutureGoodEdbInfo, cols...)
	return
}

// UnifiedModifyEdbInfoMaxAndMinInfo 统一修改指标的最大最小值
func UnifiedModifyEdbInfoMaxAndMinInfo(futureGoodEdbInfo *FutureGoodEdbInfo) (err error, errMsg string) {
	// 修改最大最小值
	maxAndMinItem, err := GetEdbInfoMaxAndMinInfo(futureGoodEdbInfo.FutureGoodEdbCode)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			err = nil
			return
		}

		errMsg = "刷新期货指标失败!"
		err = errors.New("获取期货指标最大最小值失败,err:" + err.Error())
		return
	}

	if maxAndMinItem != nil {
		o := orm.NewOrm()
		sql := ` UPDATE future_good_edb_info SET start_date=?,end_date=?,min_value=?,max_value=?,latest_date=?,latest_value=?,modify_time=NOW() WHERE future_good_edb_info_id=? `
		_, err = o.Raw(sql, maxAndMinItem.MinDate, maxAndMinItem.MaxDate, maxAndMinItem.MinValue, maxAndMinItem.MaxValue, maxAndMinItem.MaxDate, maxAndMinItem.LatestValue, futureGoodEdbInfo.FutureGoodEdbInfoId).Exec()
		if err != nil {
			errMsg = "刷新指标失败!"
			err = errors.New("修改指标最大最小值失败,err:" + err.Error())
			return
		}
	}
	return
}

// FutureGoodEdbInfoMaxAndMinInfo 指标最新数据记录结构体
type FutureGoodEdbInfoMaxAndMinInfo struct {
	MinDate     string  `description:"最小日期"`
	MaxDate     string  `description:"最大日期"`
	MinValue    float64 `description:"最小值"`
	MaxValue    float64 `description:"最大值"`
	LatestValue float64 `description:"最新值"`
	LatestDate  string  `description:"实际数据最新日期"`
}

// GetEdbInfoMaxAndMinInfo 获取指标的最新数据记录信息
func GetEdbInfoMaxAndMinInfo(futureGoodEdbCode string) (item *FutureGoodEdbInfoMaxAndMinInfo, err error) {
	o := orm.NewOrm()
	sql := ``
	sql = ` SELECT MIN(data_time) AS min_date,MAX(data_time) AS max_date,MIN(close) AS min_value,MAX(close) AS max_value FROM future_good_edb_data WHERE future_good_edb_code=? `
	err = o.Raw(sql, futureGoodEdbCode).QueryRow(&item)

	var latest_value float64
	sql = ` SELECT close AS latest_value FROM future_good_edb_data WHERE future_good_edb_code=? ORDER BY data_time DESC LIMIT 1 `
	err = o.Raw(sql, futureGoodEdbCode).QueryRow(&latest_value)
	item.LatestValue = latest_value
	return
}