package data_manage

import (
	"eta/eta_api/global"
	"eta/eta_api/utils"
	"fmt"
	"strings"
	"time"

	"github.com/rdlucklib/rdluck_tools/paging"
)

// BaseFromRadishResearchIndex 萝卜投研数据
type BaseFromRadishResearchIndex struct {
	BaseFromRadishResearchIndexId int       `orm:"column(base_from_radish_research_index_id);pk" gorm:"primaryKey"`
	IndexCode                     string    `description:"指标编码"`
	IndexName                     string    `description:"指标名称"`
	ClassifyId                    int       `description:"分类ID"`
	Unit                          string    `description:"单位"`
	Source                        string    `description:"数据来源"`
	Frequency                     string    `description:"频度"`
	StartDate                     time.Time `description:"开始日期"`
	EndDate                       time.Time `description:"结束日期"`
	Sort                          int       `description:"排序"`
	IsStop                        int       `description:"是否停更:0-否;1-停更"`
	TerminalCode                  string    `description:"所属终端编码"`
	EdbExist                      int       `description:"指标库是否已添加指标:0-否;1-是"`
	FilePath                      string    `description:"文件存储路径"`
	LatestValue                   float64   `description:"数据最新值"`
	CreateTime                    time.Time `description:"创建时间"`
	ModifyTime                    time.Time `description:"修改时间"`
}

func (m *BaseFromRadishResearchIndex) TableName() string {
	return "base_from_radish_research_index"
}

type BaseFromRadishResearchIndexCols struct {
	PrimaryId    string
	IndexCode    string
	IndexName    string
	ClassifyId   string
	Unit         string
	Source       string
	Frequency    string
	StartDate    string
	EndDate      string
	Sort         string
	IsStop       string
	TerminalCode string
	EdbExist     string
	FilePath     string
	LatestValue  string
	CreateTime   string
	ModifyTime   string
}

func (m *BaseFromRadishResearchIndex) Cols() BaseFromRadishResearchIndexCols {
	return BaseFromRadishResearchIndexCols{
		PrimaryId:    "base_from_radish_research_index_id",
		IndexCode:    "index_code",
		IndexName:    "index_name",
		ClassifyId:   "classify_id",
		Unit:         "unit",
		Source:       "source",
		Frequency:    "frequency",
		StartDate:    "start_date",
		EndDate:      "end_date",
		Sort:         "sort",
		IsStop:       "is_stop",
		EdbExist:     "edb_exist",
		TerminalCode: "terminal_code",
		FilePath:     "file_path",
		LatestValue:  "latest_value",
		CreateTime:   "create_time",
		ModifyTime:   "modify_time",
	}
}

func (m *BaseFromRadishResearchIndex) Create() (err error) {
	o := global.DbMap[utils.DbNameIndex]
	err = o.Create(m).Error
	return
}

func (m *BaseFromRadishResearchIndex) CreateMulti(items []*BaseFromRadishResearchIndex) (err error) {
	if len(items) == 0 {
		return
	}
	o := global.DbMap[utils.DbNameIndex]
	err = o.CreateInBatches(items, utils.MultiAddNum).Error
	return
}

func (m *BaseFromRadishResearchIndex) Update(cols []string) (err error) {
	o := global.DbMap[utils.DbNameIndex]
	err = o.Select(cols).Updates(m).Error
	return
}

func (m *BaseFromRadishResearchIndex) Remove() (err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
	err = o.Exec(sql, m.BaseFromRadishResearchIndexId).Error
	return
}

func (m *BaseFromRadishResearchIndex) MultiRemove(ids []int) (err error) {
	if len(ids) == 0 {
		return
	}
	o := global.DbMap[utils.DbNameIndex]
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.Cols().PrimaryId, utils.GetOrmInReplace(len(ids)))
	err = o.Exec(sql, ids).Error
	return
}

func (m *BaseFromRadishResearchIndex) RemoveByCondition(condition string, pars []interface{}) (err error) {
	if condition == "" {
		return
	}
	o := global.DbMap[utils.DbNameIndex]
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s`, m.TableName(), condition)
	err = o.Exec(sql, pars...).Error
	return
}

func (m *BaseFromRadishResearchIndex) GetItemById(id int) (item *BaseFromRadishResearchIndex, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId)
	err = o.Raw(sql, id).First(&item).Error
	return
}

func (m *BaseFromRadishResearchIndex) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *BaseFromRadishResearchIndex, err error) {
	o := global.DbMap[utils.DbNameIndex]
	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...).First(&item).Error
	return
}

func (m *BaseFromRadishResearchIndex) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
	err = o.Raw(sql, pars...).Scan(&count).Error
	return
}

func (m *BaseFromRadishResearchIndex) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*BaseFromRadishResearchIndex, err error) {
	o := global.DbMap[utils.DbNameIndex]
	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...).Find(&items).Error
	return
}

func (m *BaseFromRadishResearchIndex) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*BaseFromRadishResearchIndex, err error) {
	o := global.DbMap[utils.DbNameIndex]
	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)
	pars = append(pars, startSize, pageSize)
	err = o.Raw(sql, pars...).Find(&items).Error
	return
}

// BaseFromRadishResearchIndexItem 萝卜投研数据信息
type BaseFromRadishResearchIndexItem struct {
	IndexId     int     `description:"指标ID"`
	ClassifyId  int     `description:"分类ID"`
	IndexCode   string  `description:"指标编码"`
	IndexName   string  `description:"指标名称"`
	Unit        string  `description:"单位"`
	Source      string  `description:"数据来源"`
	Frequency   string  `description:"频度"`
	StartDate   string  `description:"开始日期"`
	EndDate     string  `description:"结束日期"`
	Sort        int     `description:"排序"`
	LatestValue float64 `description:"最新值"`
	EdbExist    int     `description:"是否加入指标:0-未加入;1-已加入"`
	CreateTime  string  `description:"创建时间"`
	ModifyTime  string  `description:"修改时间"`
}

func (m *BaseFromRadishResearchIndex) Format2Item() (item *BaseFromRadishResearchIndexItem) {
	item = new(BaseFromRadishResearchIndexItem)
	item.ClassifyId = m.ClassifyId
	item.IndexId = m.BaseFromRadishResearchIndexId
	item.IndexCode = m.IndexCode
	item.IndexName = m.IndexName
	item.Unit = m.Unit
	item.Source = m.Source
	item.Frequency = m.Frequency
	item.StartDate = utils.TimeTransferString(utils.FormatDate, m.StartDate)
	item.EndDate = utils.TimeTransferString(utils.FormatDate, m.EndDate)
	item.Sort = m.Sort
	item.LatestValue = m.LatestValue
	item.EdbExist = m.EdbExist
	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, m.CreateTime)
	item.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, m.ModifyTime)
	return
}

// BaseFromRadishResearchIndexDetail 指标详情
type BaseFromRadishResearchIndexDetail struct {
	*BaseFromRadishResearchIndexItem
	DataList []*BaseFromRadishResearchDataItem
}

func (m *BaseFromRadishResearchIndex) UpdateClassifyMulti(ids []int, classifyId int) (err error) {
	if len(ids) == 0 || classifyId <= 0 {
		return
	}
	o := global.DbMap[utils.DbNameIndex]
	sql := fmt.Sprintf(`UPDATE %s SET %s = ?, %s = NOW() WHERE %s IN (%s)`, m.TableName(), m.Cols().ClassifyId, m.Cols().ModifyTime, m.Cols().PrimaryId, utils.GetOrmInReplace(len(ids)))
	err = o.Exec(sql, classifyId, ids).Error
	return
}

// RadishResearchSearchEdbReq 搜索指标请求体
//type RadishResearchSearchEdbReq struct {
//	StockCode string `form:"StockCode" description:"证券代码" `
//	EdbCode   string `form:"EdbCode" description:"指标代码"`
//	StartTime string `form:"StartTime" description:"每日数据开始时间"`
//	EndTime   string `form:"EndTime" description:"每日数据结束时间"`
//	Interval  int    `form:"Interval" description:"时间周期"`
//	Fill      string `form:"Fill" description:"非交易间隔处理"`
//	CPS       string `form:"CPS" description:"复权方式"`
//	BaseDate  string `form:"BaseDate" description:"复权基点"`
//}

// RadishResearchExistCheckResp 指标存在校验响应
//type RadishResearchExistCheckResp struct {
//	ExistAll   bool                            `description:"指标是否全部存在: true-是; false-否"`
//	ExistIndex []RadishResearchExistCheckIndex `description:"已存在的指标信息"`
//}

// RadishResearchExistCheckIndex 指标存在校验-指标信息
//type RadishResearchExistCheckIndex struct {
//	IndexId   int    `description:"指标ID"`
//	IndexCode string `description:"指标编码"`
//	IndexName string `description:"指标名称"`
//}

// RadishResearchSearchEdbResp 响应体
//type RadishResearchSearchEdbResp struct {
//	StockCode string                        `description:"证券代码" `
//	EdbCode   string                        `description:"指标代码"`
//	IndexName string                        `description:"指标名称"`
//	Frequency int                           `description:"频度: 1-60"`
//	IndexData []RadishResearchSearchEdbData `description:"指标数据"`
//}

//type RadishResearchSearchEdbData struct {
//	DataTime string
//	Value    string
//}

// RadishResearchIndexWithData 萝卜投研指标
//type RadishResearchIndexWithData struct {
//	StockCode string                     `description:"证券代码"`
//	EdbCode   string                     `description:"指标代码"`
//	IndexData []*RadishResearchIndexData `description:"指标数据"`
//}

// RadishResearchIndexData 萝卜投研指标数据
//type RadishResearchIndexData struct {
//	DataTime time.Time `description:"数据时间"`
//	Value    float64   `description:"数据值"`
//}

// RadishResearchIndexDataLibResp 萝卜投研指标-指标库响应
//type RadishResearchIndexDataLibResp struct {
//	Ret     int
//	Msg     string
//	ErrMsg  string
//	ErrCode string
//	Data    []*RadishResearchIndexWithData
//	Success bool `description:"true 执行成功,false 执行失败"`
//}

// RadishResearchAddEdbReq 新增指标请求体
//type RadishResearchAddEdbReq struct {
//	StartTime string                            `description:"每日数据开始时间"`
//	EndTime   string                            `description:"每日数据结束时间"`
//	Interval  int                               `description:"时间周期"`
//	Fill      string                            `description:"非交易间隔处理"`
//	CPS       string                            `description:"复权方式"`
//	BaseDate  string                            `description:"复权基点"`
//	IndexList []*RadishResearchBaseAddIndexItem `description:"指标信息"`
//}

//type RadishResearchBaseAddIndexItem struct {
//	ClassifyId int    `description:"分类ID"`
//	Unit       string `description:"单位"`
//	IndexName  string `description:"指标名称"`
//	Frequency  string `description:"频度"`
//	StockCode  string `description:"证券代码"`
//	EdbCode    string `description:"指标代码"`
//}

//type RadishResearchBaseAddReq struct {
//	StartTime                      string `description:"每日数据开始时间"`
//	EndTime                        string `description:"每日数据结束时间"`
//	Interval                       int    `description:"时间周期"`
//	Fill                           string `description:"非交易间隔处理"`
//	CPS                            string `description:"复权方式"`
//	BaseDate                       string `description:"复权基点"`
//	SysAdminId                     int    `description:"创建人ID"`
//	SysAdminName                   string `description:"创建人姓名"`
//	RadishResearchBaseAddIndexItem `description:"指标信息"`
//}

// RadishResearchIndexEditReq 编辑指标请求
type RadishResearchIndexEditReq struct {
	IndexId    int `description:"指标ID"`
	ClassifyId int `description:"分类ID"`
}

// RadishResearchIndexRemoveReq 删除指标请求
type RadishResearchIndexRemoveReq struct {
	IndexId int `description:"指标ID"`
}

// RadishResearchIndexListChoiceReq 指标列表选择请求
type RadishResearchIndexListChoiceReq struct {
	ClassifyId   string `form:"ClassifyId" description:"分类ID(多选)"`
	IncludeChild bool   `form:"IncludeChild" description:"是否包含子分类"`
	Frequency    string `form:"Frequency" description:"频度(多选)"`
	SysAdminId   string `form:"SysAdminId" description:"创建人ID(多选)"`
	Keywords     string `form:"Keywords" description:"关键词: 指标ID/指标名称"`
	ListIds      string `form:"ListIds" description:"列表选择项/排除项(全选为true时为排除项)"`
	SelectAll    bool   `form:"SelectAll" description:"是否全选: true/false"`
}

// RadishResearchIndexListChoiceItem 指标列表选择响应
type RadishResearchIndexListChoiceItem struct {
	IndexId   int    `description:"指标ID"`
	IndexCode string `description:"指标编码"`
	IndexName string `description:"指标名称"`
}

// RadishResearchIndexMultiOptReq 指标批量操作请求
type RadishResearchIndexMultiOptReq struct {
	IndexIds       []int `description:"指标IDs"`
	OptType        int   `description:"操作类型: 1-移动分类; 2-删除; 3-刷新"`
	MoveClassifyId int   `description:"移动至分类ID"`
	RefreshType    int   `description:"刷新类型: 1-最近6小时; 2-全部刷新"`
}

// RadishResearchIndexListForm 指标列表表单
type RadishResearchIndexListForm struct {
	PageSize       int    `form:"PageSize" description:"每页数据量"`
	CurrentIndex   int    `form:"CurrentIndex" description:"页码"`
	ClassifyId     int    `form:"ClassifyId" description:"分类ID(查询结果包含所有子分类指标)"`
	ClassifyIds    string `form:"ClassifyIds" description:"分类IDs"`
	IgnoreEdbExist bool   `form:"IgnoreEdbExist" description:"忽略已加入指标库的"`
	Frequencies    string `form:"Frequencies" description:"频度(多选)"`
	Keyword        string `form:"Keyword" description:"关键词-指标ID/指标名称"`
}

type RadishResearchIndexPageListResp struct {
	List   []*BaseFromRadishResearchIndexItem
	Paging *paging.PagingItem `description:"分页数据"`
}

func GetRadishResearchIndexById(indexId int) (item *BaseFromRadishResearchIndex, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT * FROM base_from_radish_research_index WHERE base_from_radish_research_index_id = ?`
	err = o.Raw(sql, indexId).First(&item).Error
	return
}

// UpdateRadishResearchIndexSortByClassifyId 根据分类id更新排序
func UpdateRadishResearchIndexSortByClassifyId(classifyId, nowSort int, prevEdbInfoId int, updateSort string) (err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := ` update base_from_radish_research_index set sort = ` + updateSort + ` WHERE classify_id=?`
	if prevEdbInfoId > 0 {
		sql += ` AND ( sort > ? or ( base_from_radish_research_index_id > ` + fmt.Sprint(prevEdbInfoId) + ` and sort=` + fmt.Sprint(nowSort) + ` )) `
	} else {
		sql += ` AND ( sort > ? )`
	}
	err = o.Exec(sql, classifyId, nowSort).Error
	return
}

// GetRadishResearchIndexMaxSortByClassifyId 获取分类下指标的最大的排序数
func GetRadishResearchIndexMaxSortByClassifyId(classifyId int) (sort int, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := `SELECT COALESCE(MAX(sort), 0) AS sort FROM base_from_radish_research_index WHERE classify_id = ?`
	err = o.Raw(sql, classifyId).Scan(&sort).Error
	return
}

// GetFirstRadishResearchIndexByClassifyId 获取当前分类下,且排序数相同 的排序第一条的数据
func GetFirstRadishResearchIndexByClassifyId(classifyId int) (item *BaseFromRadishResearchIndex, err error) {
	o := global.DbMap[utils.DbNameIndex]
	sql := ` SELECT * FROM base_from_radish_research_index WHERE classify_id = ? ORDER BY sort ASC,base_from_radish_research_index_id ASC LIMIT 1`
	err = o.Raw(sql, classifyId).First(&item).Error
	return
}

type RadishResearchIndexConvert2EdbRule struct {
	ConvertType  int `description:"转换类型: 1-指定时间值; 2-区间计算值"`
	ConvertFixed struct {
		FixedDay  int    `description:"指定时间值日期: 1-当日; 2-前一日"`
		FixedTime string `description:"指定时间值时点(HH:mm:ss)"`
	} `description:"指定时间值"`
	ConvertArea struct {
		StartDay      int    `description:"起始时间日期: 1-当日; 2-前一日"`
		StartTime     string `description:"起始时间时点(HH:mm:ss)"`
		EndDay        int    `description:"截止时间日期: 1-当日; 2-前一日"`
		EndTime       string `description:"截止时间时点(HH:mm:ss)"`
		CalculateType int    `description:"计算类型: 1-区间均值; 2-最大值; 3-最小值"`
	} `description:"区间计算值"`
}

// RadishResearchIndexMultiSave2EdbPreReq 批量添加指标库请求
type RadishResearchIndexMultiSave2EdbPreReq struct {
	ConvertRule RadishResearchIndexConvert2EdbRule
	IndexIds    []int `description:"指标IDs"`
}

type RadishResearchIndexMultiSave2EdbReq struct {
	ConvertRule RadishResearchIndexConvert2EdbRule
	NewIndexes  []*RadishResearchIndexMultiSave2EdbPreItem `description:"新增指标"`
}

type RadishResearchIndexMultiSave2EdbLibReq struct {
	ConvertRule RadishResearchIndexConvert2EdbRule
	NewIndex    *RadishResearchIndexMultiSave2EdbPreItem `description:"新增指标"`
}

// RadishResearchIndexMultiSave2EdbPreItem 批量新增指标库信息
type RadishResearchIndexMultiSave2EdbPreItem struct {
	IndexId      int    `description:"指标ID"`
	IndexCode    string `description:"指标编码"`
	IndexName    string `description:"原指标名称"`
	NewIndexName string `description:"新指标名称"`
	StockCode    string `description:"证券代码"`
	EdbCode      string `description:"指标代码"`
	Unit         string `description:"单位"`
	Frequency    string `description:"原频度"`
	NewFrequency string `description:"新频度(固定日度)"`
	ClassifyId   int    `description:"指标库分类ID"`
	SysAdminId   int    `description:"创建人ID"`
	SysAdminName string `description:"创建人姓名"`
	Tips         string `description:"提示信息"`
	ErrMsg       string `description:"错误信息"`
}

type RadishResearchIndexMultiSave2EdbResp struct {
	Exist   []*RadishResearchIndexMultiSave2EdbPreItem `description:"已存在的指标"`
	Success []*RadishResearchIndexMultiSave2EdbPreItem `description:"添加成功的指标"`
	Fail    []*RadishResearchIndexMultiSave2EdbPreItem `description:"添加失败的指标"`
}

type RadishResearchIndexMultiOptResp struct {
	Success []*RadishResearchIndexBaseInfo `description:"操作成功的指标"`
	Fail    []*RadishResearchIndexBaseInfo `description:"操作失败的指标"`
}

type RadishResearchIndexBaseInfo struct {
	IndexId   int    `description:"指标ID"`
	IndexCode string `description:"指标编码"`
	IndexName string `description:"指标名称"`
}

func (m *BaseFromRadishResearchIndex) RemoveIndexAndData(indexCode string) (err error) {
	tx := global.DbMap[utils.DbNameIndex].Begin()
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			return
		}
		_ = tx.Commit()
	}()

	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().IndexCode)
	e := tx.Exec(sql, indexCode).Error
	if e != nil {
		err = fmt.Errorf("delete index err: %s", e.Error())
		return
	}

	dataOb := new(BaseFromRadishResearchData)
	sql = fmt.Sprintf(`DELETE FROM %s WHERE %s = ?`, dataOb.TableName(), dataOb.Cols().IndexCode)
	e = tx.Exec(sql, indexCode).Error
	if e != nil {
		err = fmt.Errorf("delete index data err: %s", e.Error())
		return
	}
	return
}

// RadishResearchIndexSelectReq 批量加入指标-选择指标
type RadishResearchIndexSelectReq struct {
	ClassifyIds []int    `description:"分类IDs"`
	Frequencies []string `description:"频度"`
	Keyword     string   `description:"关键词-指标ID/指标名称"`
	IndexCodes  []string `description:"SelectAll-true: IndexCodes为排除的指标, SelectAll-false: IndexCodes为选择的指标"`
	SelectAll   bool     `description:"列表全选"`
}

// UpdateEdbExists 更新是否加入指标库字段
func (m *BaseFromRadishResearchIndex) UpdateEdbExists(exist int, indexCodes []string) (err error) {
	if len(indexCodes) == 0 {
		return
	}
	o := global.DbMap[utils.DbNameIndex]
	sql := fmt.Sprintf(`UPDATE %s SET %s = ? WHERE %s IN ?`, m.TableName(), m.Cols().EdbExist, m.Cols().IndexCode)
	err = o.Exec(sql, exist, indexCodes).Error
	return
}