package models

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

var thsds = "thsds"

// 新增同花顺指标数据
func AddEdbDataFromThsDs(stockCode,edbCode string, item EdbDataFromThs) (err error) {
	o := orm.NewOrm()

	edbCodeList := strings.Split(edbCode, ",")
	indexCodeMap := make(map[string]string)
	if len(item.Tables) > 0 {
		var isAdd bool
		addSql := ` INSERT INTO edb_data_ths_ds(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
		for k, table := range item.Tables {
			dataLen := len(table.Value)
			for i := 0; i < dataLen; i++ {
				eDate := table.Time[i]
				var sValue float64
				if len(table.Value) != 0 {
					sValue = table.Value[i]
				}
				code := edbCodeList[k]
				dataTime, err := time.ParseInLocation(utils.FormatDate, eDate, time.Local)
				if err != nil {
					return err
				}
				timestamp := dataTime.UnixNano() / 1e6
				timeStr := fmt.Sprintf("%d", timestamp)
				indexCode := thsds+stockCode+code
				indexCodeMap[indexCode] = indexCode
				addSql += GetAddSql("0", indexCode, eDate, timeStr, utils.SubFloatToString(sValue, 20))
				isAdd = true
			}
		}
		if isAdd {
			for _, v := range indexCodeMap {
				var count int
				sql := ` SELECT COUNT(1) FROM edb_data_ths_ds WHERE edb_code=? `
				err = o.Raw(sql, v).QueryRow(&count)
				if err != nil {
					return err
				}
				if count > 0 {
					sql = ` DELETE FROM edb_data_ths_ds WHERE edb_code=? `
					_, err = o.Raw(sql, v).Exec()
					if err != nil {
						return err
					}
				}
			}

			addSql = strings.TrimRight(addSql, ",")
			_, err = o.Raw(addSql).Exec()
			if err != nil {
				return
			}
		}
	}
	return
}

// 刷新同花顺指标数据
func RefreshEdbDataFromThsDs(edbInfoId int, edbCode, startDate string, item EdbDataFromThs) (err error) {
	o := orm.NewOrm()
	source := utils.DATA_SOURCE_THS
	subSource := utils.DATA_SUB_SOURCE_DATE

	// 真实数据的最大日期  ， 插入规则配置的日期
	var realDataMaxDate, edbDataInsertConfigDate time.Time
	var edbDataInsertConfig *EdbDataInsertConfig
	var isFindConfigDateRealData bool //是否找到配置日期的实际数据的值
	{
		edbDataInsertConfig, err = GetEdbDataInsertConfigByEdbId(edbInfoId)
		if err != nil && err.Error() != utils.ErrNoRow() {
			return
		}
		if edbDataInsertConfig != nil {
			edbDataInsertConfigDate = edbDataInsertConfig.Date
		}
	}

	if len(item.Tables) > 0 {
		var condition string
		var pars []interface{}

		condition += " AND edb_info_id=? "
		pars = append(pars, edbInfoId)
		if startDate != "" {
			condition += " AND data_time>=? "
			pars = append(pars, startDate)
		}

		existList, err := GetEdbDataByCondition(source, subSource, condition, pars)
		if err != nil {
			return err
		}

		existMap := make(map[string]*EdbInfoSearchData)
		for _, v := range existList {
			existMap[v.DataTime] = v
		}

		table := item.Tables[0]
		dataLen := len(table.Time)
		addSql := ` INSERT INTO edb_data_ths_ds(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
		var isAdd bool
		addMap := make(map[string]string)
		edbInfoIdStr := strconv.Itoa(edbInfoId)
		for i := 0; i < dataLen; i++ {
			eDate := table.Time[i]
			sValue := table.Value[i]
			sValueStr := utils.SubFloatToString(sValue, 30)

			dataTime, err := time.ParseInLocation(utils.FormatDate, eDate, time.Local)
			if err != nil {
				return err
			}
			if findItem, ok := existMap[eDate]; !ok {
				if _, addOk := addMap[eDate]; !addOk {
					timestamp := dataTime.UnixNano() / 1e6
					timeStr := fmt.Sprintf("%d", timestamp)
					addSql += GetAddSql(edbInfoIdStr, edbCode, eDate, timeStr, sValueStr)
					isAdd = true
					addMap[eDate] = sValueStr
				}
			} else {
				if findItem != nil && utils.SubFloatToString(findItem.Value, 30) != utils.SubFloatToString(sValue, 30) {
					err = ModifyEdbDataById(source, subSource, findItem.EdbDataId, sValueStr)
					if err != nil {
						return err
					}
				}
			}

			// 下面代码主要目的是处理掉手动插入的数据判断
			{
				if realDataMaxDate.IsZero() || dataTime.After(realDataMaxDate) {
					realDataMaxDate = dataTime
				}
				if edbDataInsertConfigDate.IsZero() || dataTime.Equal(edbDataInsertConfigDate) {
					isFindConfigDateRealData = true
				}
			}
		}

		// 处理手工数据补充的配置
		HandleConfigInsertEdbData(realDataMaxDate, edbDataInsertConfig, edbInfoId, source, subSource, existMap, isFindConfigDateRealData)

		if isAdd {
			addSql = strings.TrimRight(addSql, ",")
			_, err = o.Raw(addSql).Exec()
			if err != nil {
				return err
			}
		}
	}
	return
}
