package models

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

// 指标检索数据
type EdbDataItem struct {
	EdbCode   string `description:"指标编码"`
	StartDate string `description:"起始日期"`
	EndDate   string `description:"终止日期"`
	EdbName   string `description:"指标名称"`
	Unit      string `description:"单位"`
	Frequency string `description:"频率"`
	DataList  []*EdbData
}

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

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 + "'"
	addSql += "," + "'" + timestampStr + "'"
	addSql += "),"
	return
}

type AddEdbInfoReq struct {
	EdbCode   string `description:"指标编码"`
	Source    int    `description:"指标来源ID"`
	StockCode string `description:"证券代码"`
}

// GetEdbInfoCountByCondition 获取指标数量
func GetEdbInfoCountByCondition(condition string, pars []interface{}) (count int, err error) {
	o := orm.NewOrm()
	sql := ` SELECT COUNT(1) AS count FROM edb_info WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	err = o.Raw(sql, pars).QueryRow(&count)
	return
}

// GetEdbDataAllByEdbCode 根据指标编码获取指标数据列表
func GetEdbDataAllByEdbCode(edbCode string, source, subSource, limit int) (items []*EdbInfoSearchData, err error) {
	var pars []interface{}
	pars = append(pars, edbCode)
	o := orm.NewOrm()

	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)
	return
}

func GetEdbDataByCondition(source, subSource int, condition string, pars []interface{}) (items []*EdbInfoSearchData, err error) {
	o := orm.NewOrm()
	tableName := GetEdbDataTableName(source, subSource)
	sql := ` SELECT * FROM %s WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += ` ORDER BY data_time DESC `
	sql = fmt.Sprintf(sql, tableName)
	_, err = o.Raw(sql, pars).QueryRows(&items)
	return
}

// GetEdbDataByDate 根据数据日期获取指标数据
func GetEdbDataByDate(source, subSource int, edbCode, dataTime string) (item *EdbInfoSearchData, err error) {
	o := orm.NewOrm()
	tableName := GetEdbDataTableName(source, subSource)
	sql := ` SELECT * FROM %s WHERE 1=1 AND edb_code = ? AND data_time =? ORDER BY data_time DESC `
	sql = fmt.Sprintf(sql, tableName)
	err = o.Raw(sql, edbCode, dataTime).QueryRow(&item)
	return
}

func ModifyEdbDataById(source, subSource, edbDataId int, value string) (err error) {
	o := orm.NewOrm()
	tableName := GetEdbDataTableName(source, subSource)
	sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_data_id=? `
	sql = fmt.Sprintf(sql, tableName)
	_, err = o.Raw(sql, value, edbDataId).Exec()
	return
}

func DeleteEdbDataById(source, subSource, edbDataId int) (err error) {
	sql := ` DELETE FROM %s WHERE edb_data_id=? `
	tableName := GetEdbDataTableName(source, subSource)
	sql = fmt.Sprintf(sql, tableName)

	o := orm.NewOrm()
	_, err = o.Raw(sql, edbDataId).Exec()
	return
}

type RefreshEdbInfoReq struct {
	EdbInfoId int    `description:"指标ID"`
	EdbCode   string `description:"指标编码"`
	StartDate string `description:"开始日期"`
	Source    int    `description:"指标来源ID"`
}

// GetAllEdbDataList 获取所有的指标数据列表
func GetAllEdbDataList(edbInfoId, source, subSource int) (existDataList []*EdbData, err error) {
	o := orm.NewOrm()
	dataTableName := GetEdbDataTableName(source, subSource)
	fmt.Println("dataTableName:", dataTableName)
	sql := `SELECT * FROM %s WHERE edb_info_id=? order by data_time asc`
	sql = fmt.Sprintf(sql, dataTableName)
	_, err = o.Raw(sql, edbInfoId).QueryRows(&existDataList)
	return
}

// GetAllEdbDataListByTo 获取所有的指标数据列表
func GetAllEdbDataListByTo(to orm.TxOrmer, edbInfoId, source, subSource int) (existDataList []*EdbData, err error) {
	dataTableName := GetEdbDataTableName(source, subSource)
	fmt.Println("dataTableName:", dataTableName)
	sql := `SELECT * FROM %s WHERE edb_info_id=? order by data_time asc`
	sql = fmt.Sprintf(sql, dataTableName)
	_, err = to.Raw(sql, edbInfoId).QueryRows(&existDataList)
	return
}

// GetFinalLastByTo 获取所有的指标数据列表
func GetFinalLastByTo(to orm.TxOrmer, edbInfoId, source, subSource int, latestDate string) (finalLast EdbInfoSearchData, err error) {
	dataTableName := GetEdbDataTableName(source, subSource)
	sql := fmt.Sprintf(` SELECT data_time , value FROM %s WHERE edb_info_id=? and data_time<=? ORDER BY data_time DESC `, dataTableName)
	err = to.Raw(sql, edbInfoId, latestDate).QueryRow(&finalLast)
	if err != nil && err.Error() != utils.ErrNoRow() {
		return
	}
	return
}

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

type EdbDataList struct {
	EdbDataId     int     `description:" 指标数据ID"`
	EdbInfoId     int     `description:"指标ID"`
	DataTime      string  //`json:"-" description:"数据日期"`
	DataTimestamp int64   `description:"数据日期"`
	Value         float64 `description:"数据值"`
}

func GetEdbDataList(source, subSource, endInfoId int, startDate, endDate string) (list []*EdbDataList, err error) {
	tableName := GetEdbDataTableName(source, subSource)
	if tableName == "" {
		err = errors.New("无效的渠道：" + strconv.Itoa(source))
		list = make([]*EdbDataList, 0)
		return list, err
	}
	var pars []interface{}
	sql := `SELECT edb_data_id,edb_info_id,data_time,value,data_timestamp FROM %s WHERE edb_info_id=? `
	if startDate != "" {
		sql += ` AND data_time>=? `
		pars = append(pars, startDate)
	}
	if endDate != "" {
		sql += ` AND data_time<=? `
		pars = append(pars, endDate)
	}

	sql += ` ORDER BY data_time ASC `
	sql = fmt.Sprintf(sql, tableName)
	o := orm.NewOrm()
	_, err = o.Raw(sql, endInfoId, pars).QueryRows(&list)
	return
}
