package models

import (
	"eta/eta_index_lib/models/mgo"
	"eta/eta_index_lib/utils"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"time"

	"github.com/beego/beego/v2/client/orm"
)

// BaseFromBusinessIndex
// @Description: 外部指标(商家系统)表
type BaseFromBusinessIndex struct {
	BaseFromBusinessIndexId int64     `orm:"column(base_from_business_index_id);pk"`
	IndexCode               string    `description:"指标编码"`
	IndexName               string    `description:"指标名称"`
	Unit                    string    `description:"单位"`
	Frequency               string    `description:"频度"`
	Source                  int       `description:"数据来源"`
	SourceName              string    `description:"数据来源名称"`
	StartDate               time.Time `description:"开始日期"`
	EndDate                 time.Time `description:"结束日期"`
	Remark                  string    `description:"备注字段"`
	BaseModifyTime          time.Time `description:"基础信息(名称,单位,频度)变更时间"`
	DataUpdateTime          time.Time `description:"最近一次数据发生变化的时间"`
	CreateTime              time.Time `description:"创建时间"`
	ModifyTime              time.Time `description:"修改时间"`
}

// BaseFromBusinessIndexResp
// @Description: 外部指标(商家系统)表
type BaseFromBusinessIndexResp struct {
	IndexCode  string `description:"指标编码"`
	IndexName  string `description:"指标名称"`
	Unit       string `description:"单位"`
	Frequency  string `description:"频度"`
	SourceName string `description:"数据来源名称"`
}

// EdbBusinessSource
// @Description: 自有数据(商家)指标来源
type EdbBusinessSource struct {
	EdbBusinessSourceId int64     `orm:"column(edb_business_source_id);pk"`
	SourceName          string    `description:"来源名称"` // 来源名称
	CreateTime          time.Time `description:"创建时间"` // 创建时间
}

// AddBusinessIndexReq
// @Description:  添加外部指标(商家)请求
type AddBusinessIndexReq struct {
	IndexCode  string               `description:"指标编码"`
	IndexName  string               `description:"指标名称"`
	Unit       string               `description:"单位"`
	Frequency  string               `description:"频度"`
	SourceName string               `description:"数据来源名称"`
	Remark     string               `description:"备注字段"`
	DataList   []AddBusinessDataReq `description:"指标数据"`
}

// AddBusinessDataReq
// @Description: 外部指标(商家系统)数据
type AddBusinessDataReq struct {
	Value float64 `description:"值"`
	Date  string  `description:"日期"`
}

// DelBusinessIndexReq
// @Description:  删除外部指标(商家)请求
type DelBusinessIndexReq struct {
	IndexCodeList []string `description:"指标编码"`
}

// DelBusinessIndexDataReq
// @Description:  删除外部指标(商家)明细数据请求
type DelBusinessIndexDataReq struct {
	IndexCode string `description:"指标编码"`
	StartDate string `description:"开始日期"`
	EndDate   string `description:"结束日期"`
}

// GetIndexItem
// @Description: 根据指标编码获取自有数据指标
// @author: Roc
// @receiver m
// @datetime 2024-05-31 16:29:30
// @param indexCode string
// @return item *BaseFromBusinessIndex
// @return err error
func (m *BaseFromBusinessIndex) GetIndexItem(indexCode string) (item *BaseFromBusinessIndex, err error) {
	o := orm.NewOrm()
	sql := `SELECT * FROM base_from_business_index WHERE index_code = ? `
	err = o.Raw(sql, indexCode).QueryRow(&item)
	return
}

// GetIndexItemList
// @Description: 根据指标编码列表获取自有数据指标列表
// @author: Roc
// @receiver m
// @datetime 2024-05-31 16:29:12
// @param indexCodeList []string
// @return items []*BaseFromBusinessIndex
// @return err error
func (m *BaseFromBusinessIndex) GetIndexItemList(indexCodeList []string) (items []*BaseFromBusinessIndex, err error) {
	num := len(indexCodeList)
	if num <= 0 {
		return
	}
	o := orm.NewOrm()
	sql := `SELECT * FROM base_from_business_index WHERE index_code in (` + utils.GetOrmInReplace(num) + `) `
	_, err = o.Raw(sql, indexCodeList).QueryRows(&items)

	return
}

// DelIndexItemList
// @Description: 根据指标编码列表删除自有数据指标
// @author: Roc
// @receiver m
// @datetime 2024-05-31 16:36:52
// @param indexCodeList []string
// @return err error
func (m *BaseFromBusinessIndex) DelIndexItemList(indexCodeList []string) (err error) {
	num := len(indexCodeList)
	if num <= 0 {
		return
	}
	o := orm.NewOrm()
	sql := `DELETE FROM base_from_business_index WHERE index_code in (` + utils.GetOrmInReplace(num) + `) `
	_, err = o.Raw(sql, indexCodeList).Exec()

	return
}

// GetMaxId
// @Description: 获取自有数据库中的最大id
// @author: Roc
// @receiver m
// @datetime 2024-05-31 13:11:34
// @return maxId int
// @return err error
func (m *BaseFromBusinessIndex) GetMaxId() (maxId int, err error) {
	o := orm.NewOrm()
	sql := `SELECT max(base_from_business_index_id) id FROM base_from_business_index limit 1`
	err = o.Raw(sql).QueryRow(&maxId)
	return
}

// Add 新增
func (m *BaseFromBusinessIndex) Add() (err error) {
	o := orm.NewOrm()
	lastId, err := o.Insert(m)
	if err != nil {
		return
	}
	m.BaseFromBusinessIndexId = lastId

	return
}

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

func (m *BaseFromBusinessIndex) Del() (err error) {
	o := orm.NewOrm()
	_, err = o.Delete(m)
	return
}

func (m *BaseFromBusinessIndex) UpdateIndex(item *BaseFromBusinessIndex, updateCols []string) (err error) {
	if item == nil {
		return
	}
	if len(updateCols) == 0 {
		return
	}
	o := orm.NewOrm()
	_, err = o.Update(item, updateCols...)
	return
}

// GetEdbBusinessSourceItem
// @Description: 根据来源名称获取来源信息
// @author: Roc
// @receiver m
// @datetime 2024-04-25 18:09:03
// @param sourceName string
// @return item *EdbBusinessSource
// @return err error
func (m *EdbBusinessSource) GetEdbBusinessSourceItem(sourceName string) (item *EdbBusinessSource, err error) {
	o := orm.NewOrm()
	sql := `SELECT * FROM edb_business_source WHERE source_name = ? `
	err = o.Raw(sql, sourceName).QueryRow(&item)
	return
}

// Add 新增
func (m *EdbBusinessSource) Add() (err error) {
	o := orm.NewOrm()
	lastId, err := o.Insert(m)
	if err != nil {
		return
	}
	m.EdbBusinessSourceId = lastId

	return
}

// GetEdbInfoMaxAndMinInfo
// @Description: 获取指标的最新数据记录信息
// @author: Roc
// @receiver m
// @datetime 2024-07-02 14:50:50
// @param edbCode string
// @return item *EdbInfoMaxAndMinInfo
// @return err error
func (m BaseFromBusinessIndex) GetEdbInfoMaxAndMinInfo(edbCode string) (item *EdbInfoMaxAndMinInfo, err error) {
	if utils.UseMongo {
		return m.getEdbInfoMaxAndMinInfoByMongo(edbCode)
	} else {
		return m.getEdbInfoMaxAndMinInfoByMysql(edbCode)
	}

	return
}

// getEdbInfoMaxAndMinInfoByMongo
// @Description: 获取指标的最新数据记录信息(从mongo中获取)
// @author: Roc
// @receiver m
// @datetime 2024-07-02 14:41:20
// @param edbCode string
// @return item *EdbInfoMaxAndMinInfo
// @return err error
func (m BaseFromBusinessIndex) getEdbInfoMaxAndMinInfoByMongo(edbCode string) (item *EdbInfoMaxAndMinInfo, err error) {
	mogDataObj := new(mgo.BaseFromBusinessData)
	pipeline := []bson.M{
		{"$match": bson.M{"index_code": edbCode}},
		{"$group": bson.M{
			"_id":       nil,
			"min_date":  bson.M{"$min": "$data_time"},
			"max_date":  bson.M{"$max": "$data_time"},
			"min_value": bson.M{"$min": "$value"},
			"max_value": bson.M{"$max": "$value"},
		}},
		{"$project": bson.M{"_id": 0}}, // 可选,如果不需要_id字段
	}
	result, err := mogDataObj.GetEdbInfoMaxAndMinInfo(pipeline)
	if err != nil {
		fmt.Println("BaseFromBusinessIndex GetEdbInfoMaxAndMinInfo Err:" + err.Error())
		return
	}

	if !result.MaxDate.IsZero() {
		whereQuery := bson.M{"index_code": edbCode, "data_time": result.MaxDate}
		selectParam := bson.D{{"value", 1}, {"_id", 0}}
		latestValue, tmpErr := mogDataObj.GetLatestValue(whereQuery, selectParam)
		if tmpErr != nil {
			err = tmpErr
			return
		}
		result.LatestValue = latestValue.Value
		result.EndValue = latestValue.Value
	}

	item = &EdbInfoMaxAndMinInfo{
		MinDate:     result.MinDate.Format(utils.FormatDate),
		MaxDate:     result.MaxDate.Format(utils.FormatDate),
		MinValue:    result.MinValue,
		MaxValue:    result.MaxValue,
		LatestValue: result.LatestValue,
		LatestDate:  result.LatestDate.Format(utils.FormatDate),
		EndValue:    result.EndValue,
	}

	return
}

// getEdbInfoMaxAndMinInfoByMysql
// @Description: 获取指标的最新数据记录信息(从mysql中获取)
// @author: Roc
// @receiver m
// @datetime 2024-07-02 14:49:58
// @param edbCode string
// @return item *EdbInfoMaxAndMinInfo
// @return err error
func (m BaseFromBusinessIndex) getEdbInfoMaxAndMinInfoByMysql(edbCode string) (item *EdbInfoMaxAndMinInfo, err error) {
	dataObj := BaseFromBusinessData{}
	result, err := dataObj.GetEdbInfoMaxAndMinInfo(edbCode)
	if err != nil {
		return
	}

	item = &EdbInfoMaxAndMinInfo{
		MinDate:     result.MinDate,
		MaxDate:     result.MaxDate,
		MinValue:    result.MinValue,
		MaxValue:    result.MaxValue,
		LatestValue: result.LatestValue,
		LatestDate:  result.LatestDate,
		EndValue:    result.EndValue,
	}

	return
}

// ModifyIndexMaxAndMinInfo
// @Description: 修改最大值和最小值信息
// @author: Roc
// @receiver m
// @datetime 2024-05-06 14:07:46
// @param indexCode string
// @param item *EdbInfoMaxAndMinInfo
// @param isIndexUpdateOrAdd bool
// @return err error
func (m *BaseFromBusinessIndex) ModifyIndexMaxAndMinInfo(indexCode string, item *EdbInfoMaxAndMinInfo, isIndexUpdateOrAdd bool) (err error) {
	o := orm.NewOrm()
	sql := ` UPDATE base_from_business_index SET start_date=?,end_date=?,modify_time=NOW() `
	if isIndexUpdateOrAdd {
		sql += `,data_update_time=NOW() `
	}
	sql += ` WHERE index_code=?`
	_, err = o.Raw(sql, item.MinDate, item.MaxDate, indexCode).Exec()
	return
}