package data_manage

import (
	"eta/eta_api/utils"
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"github.com/rdlucklib/rdluck_tools/paging"
	"strings"
	"time"
)

// TODO:有时间还是放在配置里面吧...
var (
	ThsHfPeriodArr = []int{1, 3, 5, 10, 15, 30, 60}                                                                                                                                // 时间周期
	ThsHfCPSArr    = []string{"no", "forward1", "forward2", "forward3", "forward4", "backward1", "backward2", "backward3", "backward4"}                                            // 复权方式
	ThsHfFillArr   = []string{"Original", "Previous", "Blank"}                                                                                                                     // 非交易间隔处理
	ThsHfEdbCodeCn = map[string]string{"open": "开盘价", "close": "收盘价", "high": "最高价", "low": "最低价", "avgprice": "均价", "volume": "成交价", "amt": "成交额", "pct_chg": "涨跌幅", "oi": "持仓量"} // 可选指标代码对应中文
)

// BaseFromThsHfIndex 同花顺高频数据
type BaseFromThsHfIndex struct {
	BaseFromThsHfIndexId    int       `orm:"column(base_from_ths_hf_index_id);pk"`
	BaseFromThsHfClassifyId int       `description:"分类ID"`
	IndexCode               string    `description:"指标编码"`
	IndexName               string    `description:"指标名称"`
	Unit                    string    `description:"单位"`
	Source                  string    `description:"数据来源"`
	Frequency               string    `description:"频度"`
	StartDate               time.Time `description:"开始日期(至时分秒)"`
	EndDate                 time.Time `description:"结束日期(至时分秒)"`
	Describe                string    `description:"指标描述"`
	Sort                    int       `description:"排序"`
	IsStop                  int       `description:"是否停更:0-否;1-停更"`
	TerminalCode            string    `description:"所属终端编码"`
	StockCode               string    `description:"证券代码"`
	Indicator               string    `description:"同花顺指标代码"`
	ApiPars                 string    `description:"API请求参数"`
	LatestValue             float64   `description:"最新值"`
	SysUserId               int       `description:"创建人ID"`
	SysUserRealName         string    `description:"创建人姓名"`
	CreateTime              time.Time `description:"创建时间"`
	ModifyTime              time.Time `description:"修改时间"`
}

func (m *BaseFromThsHfIndex) TableName() string {
	return "base_from_ths_hf_index"
}

type BaseFromThsHfIndexCols struct {
	PrimaryId               string
	BaseFromThsHfClassifyId string
	IndexCode               string
	IndexName               string
	Unit                    string
	Source                  string
	Frequency               string
	StartDate               string
	EndDate                 string
	Describe                string
	Sort                    string
	IsStop                  string
	TerminalCode            string
	StockCode               string
	Indicator               string
	ApiPars                 string
	LatestValue             string
	SysUserId               string
	SysUserRealName         string
	CreateTime              string
	ModifyTime              string
}

func (m *BaseFromThsHfIndex) Cols() BaseFromThsHfIndexCols {
	return BaseFromThsHfIndexCols{
		PrimaryId:               "base_from_ths_hf_index_id",
		BaseFromThsHfClassifyId: "base_from_ths_hf_classify_id",
		IndexCode:               "index_code",
		IndexName:               "index_name",
		Unit:                    "unit",
		Source:                  "source",
		Frequency:               "frequency",
		StartDate:               "start_date",
		EndDate:                 "end_date",
		Describe:                "describe",
		Sort:                    "sort",
		IsStop:                  "is_stop",
		TerminalCode:            "terminal_code",
		StockCode:               "stock_code",
		Indicator:               "indicator",
		ApiPars:                 "api_pars",
		LatestValue:             "latest_value",
		SysUserId:               "sys_user_id",
		SysUserRealName:         "sys_user_real_name",
		CreateTime:              "create_time",
		ModifyTime:              "modify_time",
	}
}

func (m *BaseFromThsHfIndex) Create() (err error) {
	o := orm.NewOrmUsingDB("data")
	id, err := o.Insert(m)
	if err != nil {
		return
	}
	m.BaseFromThsHfIndexId = int(id)
	return
}

func (m *BaseFromThsHfIndex) CreateMulti(items []*BaseFromThsHfIndex) (err error) {
	if len(items) == 0 {
		return
	}
	o := orm.NewOrmUsingDB("data")
	_, err = o.InsertMulti(len(items), items)
	return
}

func (m *BaseFromThsHfIndex) Update(cols []string) (err error) {
	o := orm.NewOrmUsingDB("data")
	_, err = o.Update(m, cols...)
	return
}

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

func (m *BaseFromThsHfIndex) MultiRemove(ids []int) (err error) {
	if len(ids) == 0 {
		return
	}
	o := orm.NewOrmUsingDB("data")
	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 *BaseFromThsHfIndex) RemoveByCondition(condition string, pars []interface{}) (err error) {
	if condition == "" {
		return
	}
	o := orm.NewOrmUsingDB("data")
	sql := fmt.Sprintf(`DELETE FROM %s WHERE %s`, m.TableName(), condition)
	_, err = o.Raw(sql, pars).Exec()
	return
}

func (m *BaseFromThsHfIndex) GetItemById(id int) (item *BaseFromThsHfIndex, err error) {
	o := orm.NewOrmUsingDB("data")
	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 *BaseFromThsHfIndex) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *BaseFromThsHfIndex, err error) {
	o := orm.NewOrmUsingDB("data")
	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 *BaseFromThsHfIndex) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
	o := orm.NewOrmUsingDB("data")
	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 *BaseFromThsHfIndex) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*BaseFromThsHfIndex, err error) {
	o := orm.NewOrmUsingDB("data")
	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 *BaseFromThsHfIndex) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*BaseFromThsHfIndex, err error) {
	o := orm.NewOrmUsingDB("data")
	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
}

// BaseFromThsHfIndexItem 同花顺高频数据信息
type BaseFromThsHfIndexItem 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:"结束日期(至时分秒)"`
	Describe     string  `description:"指标描述"`
	Sort         int     `description:"排序"`
	StockCode    string  `description:"证券代码"`
	Indicator    string  `description:"同花顺指标代码"`
	LatestValue  float64 `description:"最新值"`
	ClassifyPath string  `description:"完整分类路径"`
	CreateTime   string  `description:"创建时间"`
	ModifyTime   string  `description:"修改时间"`
}

func (m *BaseFromThsHfIndex) Format2Item() (item *BaseFromThsHfIndexItem) {
	item = new(BaseFromThsHfIndexItem)
	item.ClassifyId = m.BaseFromThsHfClassifyId
	item.IndexId = m.BaseFromThsHfIndexId
	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.FormatDateTime, m.StartDate)
	item.EndDate = utils.TimeTransferString(utils.FormatDateTime, m.EndDate)
	item.Describe = m.Describe
	item.Sort = m.Sort
	item.StockCode = m.StockCode
	item.Indicator = m.Indicator
	item.LatestValue = m.LatestValue
	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, m.CreateTime)
	item.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, m.ModifyTime)
	return
}

func (m *BaseFromThsHfIndex) UpdateClassifyMulti(ids []int, classifyId int) (err error) {
	if len(ids) == 0 || classifyId <= 0 {
		return
	}
	o := orm.NewOrmUsingDB("data")
	sql := fmt.Sprintf(`UPDATE %s SET %s = ?, %s = NOW() WHERE %s IN (%s)`, m.TableName(), m.Cols().BaseFromThsHfClassifyId, m.Cols().ModifyTime, m.Cols().PrimaryId, utils.GetOrmInReplace(len(ids)))
	_, err = o.Raw(sql, classifyId, ids).Exec()
	return
}

// ThsHfSearchEdbReq 搜索指标请求体
type ThsHfSearchEdbReq 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:"复权基点"`
}

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

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

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

type ThsHfSearchEdbData struct {
	DataTime string
	Value    string
}

// ThsHfIndexWithData 同花顺高频指标
type ThsHfIndexWithData struct {
	StockCode string            `description:"证券代码"`
	EdbCode   string            `description:"指标代码"`
	IndexData []*ThsHfIndexData `description:"指标数据"`
}

// ThsHfIndexData 同花顺高频指标数据
type ThsHfIndexData struct {
	DataTime time.Time `description:"数据时间(2006-01-02 15:04)"`
	Value    float64   `description:"数据值"`
}

// ThsHfIndexDataLibResp 同花顺高频指标-指标库响应
type ThsHfIndexDataLibResp struct {
	Ret     int
	Msg     string
	ErrMsg  string
	ErrCode string
	Data    []*ThsHfIndexWithData
	Success bool `description:"true 执行成功,false 执行失败"`
}

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

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

type ThsHfBaseAddReq 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:"创建人姓名"`
	ThsHfBaseAddIndexItem `description:"指标信息"`
}

// ThsHfIndexEditReq 编辑指标请求
type ThsHfIndexEditReq struct {
	IndexId    int    `description:"指标ID"`
	IndexName  string `description:"指标名称"`
	ClassifyId int    `description:"分类ID"`
	Unit       string `description:"单位"`
}

// ThsHfIndexOptReq 指标操作请求
type ThsHfIndexOptReq struct {
	IndexId int `description:"指标ID"`
}

// ThsHfIndexListChoiceReq 指标列表选择请求
type ThsHfIndexListChoiceReq 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"`
}

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

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

// ThsHfIndexListForm 指标列表表单
type ThsHfIndexListForm struct {
	PageSize     int    `form:"PageSize" description:"每页数据量"`
	CurrentIndex int    `form:"CurrentIndex" description:"页码"`
	SortField    int    `form:"SortField" description:"排序字段: 1-指标开始时间; 2-指标最新时间; 3-更新时间; 4-最新值"`
	SortType     int    `form:"SortType" description:"排序类型: 1-升序; 2-降序"`
	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/指标名称"`
}

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

func GetThsHfIndexById(indexId int) (item *BaseFromThsHfIndex, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` SELECT * FROM base_from_ths_hf_index WHERE base_from_ths_hf_index_id = ?`
	err = o.Raw(sql, indexId).QueryRow(&item)
	return
}

// UpdateThsHfIndexSortByClassifyId 根据分类id更新排序
func UpdateThsHfIndexSortByClassifyId(classifyId, nowSort int, prevEdbInfoId int, updateSort string) (err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` update base_from_ths_hf_index set sort = ` + updateSort + ` WHERE base_from_ths_hf_classify_id=?`
	if prevEdbInfoId > 0 {
		sql += ` AND ( sort > ? or ( base_from_ths_hf_index_id > ` + fmt.Sprint(prevEdbInfoId) + ` and sort=` + fmt.Sprint(nowSort) + ` )) `
	} else {
		sql += ` AND ( sort > ? )`
	}
	_, err = o.Raw(sql, classifyId, nowSort).Exec()
	return
}

// GetThsHfIndexMaxSortByClassifyId 获取分类下指标的最大的排序数
func GetThsHfIndexMaxSortByClassifyId(classifyId int) (sort int, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := `SELECT Max(sort) AS sort FROM base_from_ths_hf_index WHERE base_from_ths_hf_classify_id = ?`
	err = o.Raw(sql, classifyId).QueryRow(&sort)
	return
}

// GetFirstThsHfIndexByClassifyId 获取当前分类下,且排序数相同 的排序第一条的数据
func GetFirstThsHfIndexByClassifyId(classifyId int) (item *BaseFromThsHfIndex, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := ` SELECT * FROM base_from_ths_hf_index WHERE base_from_ths_hf_classify_id = ? order by sort asc,base_from_ths_hf_index_id asc limit 1`
	err = o.Raw(sql, classifyId).QueryRow(&item)
	return
}

type ThsHfIndexConvert2EdbRule 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:"区间计算值"`
}

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

type ThsHfIndexMultiSave2EdbReq struct {
	ConvertRule ThsHfIndexConvert2EdbRule
	NewIndexes  []*ThsHfIndexMultiSave2EdbPreItem `description:"新增指标"`
}

type ThsHfIndexMultiSave2EdbLibReq struct {
	ConvertRule ThsHfIndexConvert2EdbRule
	NewIndex    *ThsHfIndexMultiSave2EdbPreItem `description:"新增指标"`
}

// ThsHfIndexMultiSave2EdbPreItem 批量新增指标库信息
type ThsHfIndexMultiSave2EdbPreItem 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 ThsHfIndexMultiSave2EdbResp struct {
	Exist   []*ThsHfIndexMultiSave2EdbPreItem `description:"已存在的指标"`
	Success []*ThsHfIndexMultiSave2EdbPreItem `description:"添加成功的指标"`
	Fail    []*ThsHfIndexMultiSave2EdbPreItem `description:"添加失败的指标"`
}

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

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