package models

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

// FactorEdbSeriesCalculateData 因子指标系列-指标计算数据表
type FactorEdbSeriesCalculateData struct {
	FactorEdbSeriesCalculateDataId int       `orm:"column(factor_edb_series_calculate_data_id);pk"`
	FactorEdbSeriesId              int       `description:"因子指标系列ID"`
	EdbInfoId                      int       `description:"指标ID"`
	EdbCode                        string    `description:"指标编码"`
	DataTime                       time.Time `description:"数据日期"`
	Value                          float64   `description:"数据值"`
	CreateTime                     time.Time `description:"创建时间"`
	ModifyTime                     time.Time `description:"修改时间"`
	DataTimestamp                  int64     `description:"数据日期时间戳"`
}

func (m *FactorEdbSeriesCalculateData) TableName() string {
	return "factor_edb_series_calculate_data"
}

type FactorEdbSeriesCalculateDataCols struct {
	PrimaryId         string
	FactorEdbSeriesId string
	EdbInfoId         string
	EdbCode           string
	DataTime          string
	Value             string
	CreateTime        string
	ModifyTime        string
	DataTimestamp     string
}

func (m *FactorEdbSeriesCalculateData) Cols() FactorEdbSeriesCalculateDataCols {
	return FactorEdbSeriesCalculateDataCols{
		PrimaryId:         "factor_edb_series_calculate_data_id",
		FactorEdbSeriesId: "factor_edb_series_id",
		EdbInfoId:         "edb_info_id",
		EdbCode:           "edb_code",
		DataTime:          "data_time",
		Value:             "value",
		CreateTime:        "create_time",
		ModifyTime:        "modify_time",
		DataTimestamp:     "data_timestamp",
	}
}

func (m *FactorEdbSeriesCalculateData) Create() (err error) {
	o := orm.NewOrm()
	id, err := o.Insert(m)
	if err != nil {
		return
	}
	m.FactorEdbSeriesCalculateDataId = int(id)
	return
}

func (m *FactorEdbSeriesCalculateData) CreateMulti(items []*FactorEdbSeriesCalculateData) (err error) {
	if len(items) == 0 {
		return
	}
	o := orm.NewOrm()
	_, err = o.InsertMulti(500, items)
	return
}

func (m *FactorEdbSeriesCalculateData) Update(cols []string) (err error) {
	o := orm.NewOrm()
	_, err = o.Update(m, cols...)
	return
}

func (m *FactorEdbSeriesCalculateData) Remove() (err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
	_, err = o.Raw(sql, m.FactorEdbSeriesCalculateDataId).Exec()
	return
}

func (m *FactorEdbSeriesCalculateData) MultiRemove(ids []int) (err error) {
	if len(ids) == 0 {
		return
	}
	o := orm.NewOrm()
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.Cols().PrimaryId, utils.GetOrmInReplace(len(ids)))
	_, err = o.Raw(sql, ids).Exec()
	return
}

func (m *FactorEdbSeriesCalculateData) RemoveByCondition(condition string, pars []interface{}) (err error) {
	if condition == "" {
		return
	}
	o := orm.NewOrm()
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s`, m.TableName(), condition)
	_, err = o.Raw(sql, pars).Exec()
	return
}

func (m *FactorEdbSeriesCalculateData) GetItemById(id int) (item *FactorEdbSeriesCalculateData, err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
	err = o.Raw(sql, id).QueryRow(&item)
	return
}

func (m *FactorEdbSeriesCalculateData) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *FactorEdbSeriesCalculateData, err error) {
	o := orm.NewOrm()
	order := ``
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order)
	err = o.Raw(sql, pars).QueryRow(&item)
	return
}

func (m *FactorEdbSeriesCalculateData) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
	err = o.Raw(sql, pars).QueryRow(&count)
	return
}

func (m *FactorEdbSeriesCalculateData) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*FactorEdbSeriesCalculateData, err error) {
	o := orm.NewOrm()
	fields := strings.Join(fieldArr, ",")
	if len(fieldArr) == 0 {
		fields = `*`
	}
	order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime)
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
	_, err = o.Raw(sql, pars).QueryRows(&items)
	return
}

func (m *FactorEdbSeriesCalculateData) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*FactorEdbSeriesCalculateData, err error) {
	o := orm.NewOrm()
	fields := strings.Join(fieldArr, ",")
	if len(fieldArr) == 0 {
		fields = `*`
	}
	order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime)
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
	return
}

// FactorEdbSeriesCalculateDataItem 因子指标系列-计算数据信息
type FactorEdbSeriesCalculateDataItem struct {
	DataId            int     `description:"数据ID"`
	FactorEdbSeriesId int     `description:"因子指标系列ID"`
	EdbInfoId         int     `description:"指标ID"`
	EdbCode           string  `description:"指标编码"`
	DataTime          string  `description:"数据日期"`
	Value             float64 `description:"数据值"`
}

func (m *FactorEdbSeriesCalculateData) Format2Item() (item *FactorEdbSeriesCalculateDataItem) {
	item = new(FactorEdbSeriesCalculateDataItem)
	item.DataId = m.FactorEdbSeriesCalculateDataId
	item.FactorEdbSeriesId = m.FactorEdbSeriesId
	item.EdbInfoId = m.EdbInfoId
	item.EdbCode = m.EdbCode
	return
}

// TransEdbSeriesCalculateData2EdbDataList 转换数据格式
func TransEdbSeriesCalculateData2EdbDataList(items []*FactorEdbSeriesCalculateData) (list []*EdbInfoSearchData) {
	list = make([]*EdbInfoSearchData, 0)
	for _, v := range items {
		list = append(list, &EdbInfoSearchData{
			DataTime: v.DataTime.Format(utils.FormatDate),
			Value:    v.Value,
		})
	}
	return
}