package models

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

type EdbInfo struct {
	EdbInfoId        int    `orm:"column(edb_info_id);pk"`
	EdbInfoType      int    `description:"指标类型,0:普通指标,1:预测指标"`
	SourceName       string `description:"来源名称"`
	Source           int    `description:"来源id"`
	EdbCode          string `description:"指标编码"`
	EdbName          string `description:"指标名称"`
	EdbNameEn        string `description:"英文指标名称"`
	EdbNameSource    string `description:"指标名称来源"`
	Frequency        string `description:"频率"`
	Unit             string `description:"单位"`
	UnitEn           string `description:"英文单位"`
	StartDate        string `description:"起始日期"`
	EndDate          string `description:"终止日期"`
	ClassifyId       int    `description:"分类id"`
	SysUserId        int
	SysUserRealName  string
	UniqueCode       string `description:"指标唯一编码"`
	CreateTime       time.Time
	ModifyTime       time.Time
	MinValue         float64 `description:"指标最小值"`
	MaxValue         float64 `description:"指标最大值"`
	CalculateFormula string  `description:"计算公式"`
	EdbType          int     `description:"指标类型:1:基础指标,2:计算指标"`
	Sort             int     `description:"排序字段"`
	LatestDate       string  `description:"数据最新日期(实际日期)"`
	LatestValue      float64 `description:"数据最新值(实际值)"`
	EndValue         float64 `description:"数据的最新值(预测日期的最新值)"`
	MoveType         int     `description:"移动方式:1:领先(默认),2:滞后"`
	MoveFrequency    string  `description:"移动频度"`
	NoUpdate         int8    `description:"是否停止更新,0:继续更新;1:停止更新"`
	ServerUrl        string  `description:"服务器地址"`
	ChartImage       string  `description:"图表图片"`
	Calendar         string  `description:"公历/农历" orm:"default(公历);"`
	DataDateType     string  `orm:"column(data_date_type);size(255);null;default(交易日)"`
	ManualSave       int     `description:"是否有手动保存过上下限: 0-否; 1-是"`
	EmptyType        int     `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"`
	MaxEmptyType     int     `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"`
	TerminalCode     string  `description:"终端编码,用于配置在机器上"`
	DataUpdateTime   string  `description:"最近一次数据发生变化的时间"`
	ErDataUpdateDate string  `description:"本次更新,数据发生变化的最早日期"`
	SourceIndexName  string  `description:"数据源中的指标名称"`
	SubSource        int     `description:"子数据来源:0:经济数据库,1:日期序列"`
	SubSourceName    string  `description:"子数据来源名称"`
	IndicatorCode    string  `description:"指标代码"`
	StockCode        string  `description:"证券代码"`
	Extra            string  `description:"指标额外配置"`
	IsJoinPermission int     `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
}

type EdbInfoFullClassify struct {
	*EdbInfo
	CorrelationStr string `description:"相关性系数字符串"`
	HaveOperaAuth  bool   `description:"是否有数据权限,默认:false"`
}

func AddEdbInfo(item *EdbInfo) (lastId int64, err error) {
	o := orm.NewOrmUsingDB("data")
	lastId, err = o.Insert(item)
	return
}

// 更新指标信息
func (e *EdbInfo) Update(col []string) (err error) {
	o := orm.NewOrmUsingDB("data")
	_, err = o.Update(e, col...)
	return
}

type BaseEdbNameItem struct {
	EdbInfoId     int    `description:"指标id"`
	EdbInfoType   int    `description:"指标类型,0:普通指标,1:预测指标"`
	SourceName    string `description:"来源名称"`
	Source        int    `description:"来源id"`
	EdbCode       string `description:"指标编码"`
	EdbName       string `description:"指标名称"`
	Frequency     string `description:"频率"`
	Unit          string `description:"单位"`
	HaveOperaAuth bool   `description:"是否有数据权限,默认:false"`
}

type BaseEdbInfoResp struct {
	List []*BaseEdbNameItem
}

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

type StockInfo struct {
	StockCode string
	EdbCode   string
	DataList  []*EdbInfoSearchData
}

type EdbInfoSearchData struct {
	DataTime string  `description:"数据日期"`
	Value    float64 `description:"数据"`
}

type BaseIndexInfo struct {
	IndexName string `description:"数据日期"`
	Unit      string `description:"单位"`
	Frequency string `description:"频率"`
}

type EdbInfoSearchResp struct {
	SearchItem      *EdbInfoSearch `description:"指标分类"`
	Status          int            `description:"1:数据已存在于弘则数据库,2:新数据,3:数据已存在于弘则数据库,但是当前账号无权限"`
	StockSearchList []*EdbInfoSearch
}

func GetEdbInfoByEdbCode(source int, edbCode string) (item *EdbInfo, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` SELECT * FROM edb_info WHERE source=? AND edb_code=? `
	err = o.Raw(sql, source, edbCode).QueryRow(&item)
	return
}

func GetEdbInfoById(edbInfoId int) (item *EdbInfo, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` SELECT * FROM edb_info WHERE edb_info_id=? `
	err = o.Raw(sql, edbInfoId).QueryRow(&item)
	return
}

// GetEdbInfoByUniqueCode
// @Description: 根据uniqueCode获取指标详情
// @author: Roc
// @datetime 2024-01-18 13:40:01
// @param uniqueCode string
// @return item *EdbInfo
// @return err error
func GetEdbInfoByUniqueCode(uniqueCode string) (item *EdbInfo, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` SELECT * FROM edb_info WHERE unique_code=? `
	err = o.Raw(sql, uniqueCode).QueryRow(&item)
	return
}

// GetEdbInfoByIdList 根据指标id集合 获取 指标列表
func GetEdbInfoByIdList(edbInfoIdList []int) (items []*EdbInfo, err error) {
	num := len(edbInfoIdList)
	if num <= 0 {
		return
	}
	o := orm.NewOrmUsingDB("data")
	sql := ` SELECT * FROM edb_info WHERE edb_info_id in (` + utils.GetOrmInReplace(num) + `) `
	_, err = o.Raw(sql, edbInfoIdList).QueryRows(&items)
	return
}

func DeleteEdbInfo(edbInfoId int) (err error) {
	o := orm.NewOrmUsingDB("data")
	to, err := o.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			_ = to.Rollback()
		} else {
			_ = to.Commit()
		}
	}()

	// 删除指标信息
	sql := ` DELETE FROM edb_info WHERE edb_info_id=? `
	_, err = to.Raw(sql, edbInfoId).Exec()
	if err != nil {
		return
	}

	// 删除计算指标的关系
	sql = ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id=? `
	_, err = to.Raw(sql, edbInfoId).Exec()

	return
}

func GetEdbInfoCountByCondition(condition string, pars []interface{}) (count int, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` SELECT COUNT(1) AS count FROM edb_info WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	err = o.Raw(sql, pars).QueryRow(&count)
	return
}

type EditEdbInfoReq struct {
	EdbInfoId        int    `description:"指标ID"`
	EdbName          string `description:"指标名称"`
	Frequency        string `description:"频率"`
	Unit             string `description:"单位"`
	ClassifyId       int    `description:"分类id"`
	CalculateFormula string `description:"计算公式"`
}

type EditEdbEnInfoReq struct {
	EdbInfoId int    `description:"指标ID"`
	EdbNameEn string `description:"英文指标名称"`
	UnitEn    string `description:"英文单位"`
}

func ModifyEdbInfo(item *EditEdbInfoReq) (err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` UPDATE  edb_info
			SET
			  edb_name =?,
			  edb_name_source =?,
			  frequency = ?,
			  unit = ?,
			  classify_id = ?,
			  modify_time = NOW()
			WHERE edb_info_id = ?`
	_, err = o.Raw(sql, item.EdbName, item.EdbName, item.Frequency, item.Unit, item.ClassifyId, item.EdbInfoId).Exec()
	return
}

// ModifyEdbEnInfo 修改指标英文信息
func ModifyEdbEnInfo(item *EditEdbEnInfoReq) (err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` UPDATE  edb_info
			SET
			  edb_name_en =?,
			  unit_en = ?,
			  modify_time = NOW()
			WHERE edb_info_id = ?`
	_, err = o.Raw(sql, item.EdbNameEn, item.UnitEn, item.EdbInfoId).Exec()
	return
}

type EdbInfoList struct {
	EdbInfoId        int                     `orm:"column(edb_info_id);pk"`
	EdbInfoType      int                     `description:"指标类型,0:普通指标,1:预测指标"`
	SourceName       string                  `description:"来源名称"`
	Source           int                     `description:"来源id"`
	EdbCode          string                  `description:"指标编码"`
	EdbNameEn        string                  `description:"英文指标名称"`
	EdbName          string                  `description:"指标名称"`
	Frequency        string                  `description:"频率"`
	FrequencyEn      string                  `description:"英文频率"`
	Unit             string                  `description:"单位"`
	UnitEn           string                  `description:"英文单位"`
	StartDate        string                  `description:"起始日期"`
	EndDate          string                  `description:"终止日期"`
	LatestDate       string                  `description:"数据最新日期(实际日期)"`
	LatestValue      float64                 `description:"数据最新值(实际值)"`
	EndValue         float64                 `description:"数据的最新值(预测日期的最新值)"`
	ClassifyId       int                     `description:"分类id"`
	UniqueCode       string                  `description:"指标唯一编码"`
	SysUserId        int                     `description:"创建人id"`
	SysUserRealName  string                  `description:"创建人姓名"`
	ModifyTime       string                  `description:"最新修改时间"`
	CreateTime       string                  `description:"创建时间"`
	EdbNameAlias     string                  `json:"-" description:"指标名称,别名"`
	EdbType          int                     `description:"指标类型:1:基础指标,2:计算指标"`
	ChartImage       string                  `description:"图表图片"`
	RuleType         int                     `description:"预测规则,1:最新,2:固定值"`
	FixedValue       float64                 `description:"固定值"`
	DataList         []*EdbData              `description:"实际指标数据"`
	PredictDataList  []*EdbData              `description:"预测指标数据"`
	IsEnEdb          bool                    `description:"是否展示英文标识"`
	DataInsertConfig EdbDataInsertConfigItem `description:"指标数据插入配置"`
	DataDateType     string                  `description:"数据日期类型,枚举值:交易日、自然日"`
	EmptyType        int                     `description:"空值处理类型(0查找前后35天,1不计算,2前值填充,3后值填充,4等于0)"`
	MaxEmptyType     int                     `description:"MAX、MIN公式空值处理类型(1、等于0;2、跳过空值)"`
	SubSource        int                     `description:"子数据来源:0:经济数据库,1:日期序列"`
	SubSourceName    string                  `description:"子数据来源名称"`
	IndicatorCode    string                  `description:"指标代码"`
	StockCode        string                  `description:"证券代码"`
	NoUpdate         int8                    `description:"是否停止更新,0:继续更新;1:停止更新"`
	IsJoinPermission int                     `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
	HaveOperaAuth    bool                    `description:"是否有数据权限,默认:false"`
}

type EdbDataInsertConfigItem struct {
	Date     string `description:"插入的日期"`
	RealDate string `description:"实际最晚的日期"`
	Value    string `description:"插入的值"`
}

type EdbData struct {
	EdbDataId int `orm:"column(edb_data_id);pk"`
	EdbInfoId int
	DataTime  string
	Value     float64
}

type EdbInfoListResp struct {
	Item *EdbInfoList
}