package edb_data

import (
	"errors"
	"fmt"
	"hongze/hongze_yb/global"
	"hongze/hongze_yb/utils"
	"strconv"
	"time"
)

// 指标数据->存储表
func GetEdbDataTableName(source int) (tableName string) {
	switch source {
	case utils.DATA_SOURCE_THS:
		tableName = "edb_data_ths"
	case utils.DATA_SOURCE_WIND:
		tableName = "edb_data_wind"
	case utils.DATA_SOURCE_PB:
		tableName = "edb_data_pb"
	case utils.DATA_SOURCE_CALCULATE:
		tableName = "edb_data_calculate"
	case utils.DATA_SOURCE_CALCULATE_LJZZY:
		tableName = "edb_data_calculate_ljzzy"
	case utils.DATA_SOURCE_CALCULATE_TBZ:
		tableName = "edb_data_calculate_tbz"
	case utils.DATA_SOURCE_CALCULATE_TCZ:
		tableName = "edb_data_calculate_tcz"
	case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS:
		tableName = "edb_data_calculate_nszydpjjs"
	case utils.DATA_SOURCE_MANUAL:
		tableName = "edb_data_manual"
	case utils.DATA_SOURCE_LZ:
		tableName = "edb_data_lz"
	case utils.DATA_SOURCE_YS:
		tableName = "edb_data_ys"
	case utils.DATA_SOURCE_CALCULATE_HBZ:
		tableName = "edb_data_calculate_hbz"
	case utils.DATA_SOURCE_CALCULATE_HCZ:
		tableName = "edb_data_calculate_hcz"
	case utils.DATA_SOURCE_CALCULATE_BP:
		tableName = "edb_data_calculate_bp"
	case utils.DATA_SOURCE_GL:
		tableName = "edb_data_gl"
	case utils.DATA_SOURCE_ZZ:
		tableName = "edb_data_zz"
	case utils.DATA_SOURCE_DL:
		tableName = "edb_data_dl"
	case utils.DATA_SOURCE_SH:
		tableName = "edb_data_sh"
	case utils.DATA_SOURCE_CFFEX:
		tableName = "edb_data_cffex"
	case utils.DATA_SOURCE_SHFE:
		tableName = "edb_data_ine"
	case utils.DATA_SOURCE_GIE:
		tableName = "edb_data_gie"
	case utils.DATA_SOURCE_CALCULATE_ZJPJ:
		tableName = "edb_data_calculate_zjpj"
	case utils.DATA_SOURCE_CALCULATE_TIME_SHIFT:
		tableName = "edb_data_calculate_time_shift"
	case utils.DATA_SOURCE_CALCULATE_LJZTBPJ:
		tableName = "edb_data_calculate_ljztbpj"
	case utils.DATA_SOURCE_LT:
		tableName = "edb_data_lt"
	default:
		tableName = ""
	}
	return
}

type EdbDataList struct {
	EdbDataId     int     `description:" 指标数据ID"`
	EdbInfoId     int     `description:"指标ID"`
	DataTime      string  `json:"-" description:"数据日期"`
	DataTimestamp int64   `description:"数据日期"`
	Value         float64 `description:"数据值"`
}

type EdbDataItems struct {
	Items []*EdbDataList
	Year  int
}

type EdbDataResult struct {
	List []*EdbDataItems
}

type QuarterData struct {
	Year     int
	DataList []*EdbDataList
}

// GetEdbDataList 获取指标数据
func GetEdbDataList(source, endInfoId int, startDate, endDate string) (list []*EdbDataList, err error) {
	tableName := GetEdbDataTableName(source)
	if tableName == "" {
		err = errors.New("无效的渠道：" + strconv.Itoa(source))
		list = make([]*EdbDataList, 0)
		return list, err
	}
	var pars []interface{}
	sql := `SELECT edb_data_id,edb_info_id,data_time,value,data_timestamp FROM %s WHERE edb_info_id = ? `
	if startDate != "" {
		sql += ` AND data_time >= ? `
		pars = append(pars, startDate)
	}
	if endDate != "" {
		sql += ` AND data_time <= ? `
		pars = append(pars, endDate)
	}
	sql += ` ORDER BY data_time ASC `
	sql = fmt.Sprintf(sql, tableName)
	err = global.MYSQL["data"].Raw(sql, endInfoId, pars).Scan(&list).Error

	return
}


func GetEdbDataThsByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_ths WHERE edb_code = ? AND data_time = ? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error

	return
}

func GetEdbDataWindByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_wind WHERE edb_code=? AND data_time=? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error

	return
}

func GetEdbDataPbByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_pb WHERE edb_code=? AND data_time>=? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error

	return
}

type ManualEdbdata struct {
	TradeCode  string    `orm:"column(TRADE_CODE);pk" description:"指标编码"`
	Dt         string    `orm:"column(DT)" description:"日期"`
	Close      string    `orm:"column(CLOSE)" description:"值"`
	ModifyTime time.Time `orm:"column(modify_time)" description:"修改时间"`
}

func GetEdbdataManualByTradeCode(condition string, pars []interface{}) (item []*ManualEdbdata, err error) {
	sql := ` SELECT  * FROM edbdata WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += ` ORDER BY DT DESC `
	err = global.MYSQL["edb"].Raw(sql, pars).Scan(&item).Error

	return
}

type EdbDataBase struct {
	EdbDataId     int `orm:"column(edb_data_id);pk"`
	EdbInfoId     int
	EdbCode       string
	DataTime      string
	Value         string
	Status        int
	CreateTime    time.Time
	ModifyTime    time.Time
	DataTimestamp int64
}

type lzSurveyData struct {
	DataTime   string `orm:"column(data_time)" description:"日期"`
	InputValue string `orm:"column(input_value)" description:"值"`
}

func GetLzSurveyDataByTradeCode(condition string, pars []interface{}) (item []*lzSurveyData, err error) {
	sql := ` SELECT  a.* FROM longzhong_survey_data AS a
				INNER JOIN longzhong_survey_product AS b ON a.survey_product_id=b.survey_product_id
				WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += ` ORDER BY a.data_time DESC `
	err = global.MYSQL["edb"].Raw(sql, pars).Scan(&item).Error

	return
}

func GetEdbDataLzByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_lz WHERE edb_code=? AND data_time=? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error

	return
}

type EdbDataPb struct {
	EdbDataId     int `orm:"column(edb_data_id);pk"`
	EdbInfoId     int
	EdbCode       string
	DataTime      string
	Value         float64
	Status        int
	CreateTime    time.Time
	ModifyTime    time.Time
	Ticker        string
	Field         string
	DataTimestamp int64
}

type BaseFromSmm struct {
	BaseFromSmmId int `orm:"column(base_from_smm_id);pk"`
	Aid           int
	Name          string
	Interface     string
	ApiUpdate     int
	ApiUpdateType string
	ApiType       int
	ApiTypeAll    string
	Type1         string `orm:"column(type_1)"`
	Type2         string `orm:"column(type_2)"`
	Type3         string `orm:"column(type_3)"`
	ApiStartTime  string
	ApiUpdateTime string
	StartTime     string
	FinishTime    string
	AuthModule    string
	AuthLang      string
	ApiLabel      string
	Enable        string
	EditPerson    string
	EditTime      string
	AuthDur       int
	AuthDurType   string
}

type BaseFromSmmIndex struct {
	BaseFromSmmIndexId int `orm:"column(base_from_smm_index_id);pk"`
	Interface          string
	Name               string
	IndexCode          string
	IndexName          string
	Type1              string `orm:"column(type_1)"`
	Type2              string `orm:"column(type_2)"`
	Type3              string `orm:"column(type_3)"`
	Frequency          string
	Unit               string
	ApiStartTime       string
	ApiUpdateTime      string
	StartTime          string
	FinishTime         string
	CreateTime         time.Time
	ModifyTime         time.Time
}

type BaseFromSmmData struct {
	SmmDataId          int `orm:"column(smm_data_id);pk"`
	BaseFromSmmIndexId int
	IndexCode          string
	DataTime           string
	Value              string
	CreateTime         time.Time
	ModifyTime         time.Time
	DataTimestamp      int64
}

func GetBaseFromSmmBySmmCode(smmCode string) (item *BaseFromSmm, err error) {
	sql := `SELECT * FROM base_from_smm WHERE interface = ?`
	err = global.MYSQL["data"].Raw(sql, smmCode).Scan(&item).Error

	return
}

func GetBaseFromSmmIndexBySmmCode(smmCode string) (list []*BaseFromSmmIndex, err error) {
	sql := ` SELECT * FROM base_from_smm_index WHERE interface = ? `
	err = global.MYSQL["data"].Raw(sql, smmCode).Scan(&list).Error

	return
}

func GetBaseFromSmmDataAllByIndexCode(indexCode string) (list []*BaseFromSmmData, err error) {
	sql := `SELECT * FROM base_from_smm_data WHERE index_code=? `
	err = global.MYSQL["data"].Raw(sql, indexCode).Scan(&list).Error

	return
}

func GetBaseFromSmmMaxOrMinDate(indexCode string) (min_date, max_date string, err error) {
	sql := ` SELECT MIN(data_time) AS min_date FROM base_from_smm_data WHERE index_code=? `
	err = global.MYSQL["data"].Raw(sql, indexCode).Scan(&min_date).Error
	sql = ` SELECT MAX(data_time) AS max_date FROM base_from_smm_data WHERE index_code=? `
	err = global.MYSQL["data"].Raw(sql, indexCode).Scan(&max_date).Error

	return
}

type YsResult struct {
	Code int64 `json:"Code"`
	Data struct {
		CompanyList []interface{} `json:"CompanyList"`
		Content     [][]string    `json:"Content"`
		Field       []struct {
			ColIndex   int64  `json:"ColIndex"`
			ColumnType string `json:"ColumnType"`
			Info       string `json:"Info"`
			IsDate     string `json:"IsDate"`
			Name       string `json:"Name"`
			Unit       string `json:"Unit"`
			DBColName  string `json:"db_col_name"`
		} `json:"Field"`
		CountPage   int64  `json:"count_page"`
		CurrentPage int64  `json:"current_page"`
		Frequency   string `json:"frequency"`
		Mindate     string `json:"mindate"`
		PageNum     int64  `json:"page_num"`
		Status      int64  `json:"status"`
		TotalNum    int64  `json:"total_num"`
	} `json:"Data"`
	Msg string `json:"Msg"`
}

type BaseFromSmmDataSimple struct {
	SmmDataId          int `orm:"column(smm_data_id);pk"`
	BaseFromSmmIndexId int
	IndexCode          string
	DataTime           string
	Value              string
}

type BaseFromDlDataSimple struct {
	Id        int `orm:"column(base_from_trade_dalian_index_id);pk"`
	DealCode  string
	BuyCode   string
	SoldCode  string
	DataTime  string
	DealValue string
	BuyValue  string
	SoldValue string
}

func GetDlDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromDlDataSimple, err error) {
	sql := ` SELECT * FROM base_from_trade_dalian_index WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += ` ORDER BY data_time DESC `
	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error

	return
}

func GetEdbDataDlByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_dl WHERE edb_code=? AND data_time=? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error

	return
}

type GlData struct {
	InputValue string `orm:"column(DATA_VALUE)" description:"日期"`
	DataTime   string `orm:"column(DATA_DATE)" description:"值"`
}

func GetGlDataByTradeCode(condition string, pars []interface{}) (item []*GlData, err error) {
	condition += " AND IS_DELETE=0 "
	sql := ` SELECT * FROM mb_index_main_data WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += ` ORDER BY PUBLISH_TIME DESC `
	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error

	return
}

func GetEdbDataGlByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_gl WHERE edb_code=? AND data_time=? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error

	return
}

type EdbDataFromLt struct {
	Close map[int64]interface{} `json:"CLOSE"`
}

type BaseFromZzDataSimple struct {
	Id        int `orm:"column(base_from_trade_zhengzhou_index_id);pk"`
	DealCode  string
	BuyCode   string
	SoldCode  string
	DataTime  string
	DealValue string
	BuyValue  string
	SoldValue string
}

func GetZzDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromZzDataSimple, err error) {
	sql := ` SELECT * FROM base_from_trade_zhengzhou_index WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += ` ORDER BY data_time DESC `
	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error

	return
}

func GetEdbDataZzByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_zz WHERE edb_code=? AND data_time=? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error
	return
}

type BaseFromShDataSimple struct {
	Id        int `orm:"column(base_from_trade_shanghai_index_id);pk"`
	DealCode  string
	BuyCode   string
	SoldCode  string
	DataTime  string
	DealValue string
	BuyValue  string
	SoldValue string
}

func GetShDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromShDataSimple, err error) {
	sql := ` SELECT * FROM base_from_trade_shanghai_index WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += ` ORDER BY data_time DESC `
	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error

	return
}

func GetEdbDataShByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_sh WHERE edb_code=? AND data_time=? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error

	return
}

type BaseFromCffexDataSimple struct {
	Id        int `orm:"column(base_from_trade_cffex_index_id);pk"`
	DealCode  string
	BuyCode   string
	SoldCode  string
	DataTime  string
	DealValue string
	BuyValue  string
	SoldValue string
}

func GetCffexDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromCffexDataSimple, err error) {
	sql := ` SELECT * FROM base_from_trade_cffex_index WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += ` ORDER BY data_time DESC `
	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error

	return
}

func GetEdbDataCffexByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_cffex WHERE edb_code=? AND data_time=? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error

	return
}

type BaseFromShfeDataSimple struct {
	Id        int `orm:"column(base_from_trade_ine_index_id);pk"`
	DealCode  string
	BuyCode   string
	SoldCode  string
	DataTime  string
	DealValue string
	BuyValue  string
	SoldValue string
}

func GetShfeDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromShfeDataSimple, err error) {
	sql := ` SELECT * FROM base_from_trade_ine_index WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += ` ORDER BY data_time DESC `
	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error

	return
}

func GetEdbDataShfeByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_ine WHERE edb_code=? AND data_time=? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error

	return
}

type BaseFromTradeEicIndex struct {
	BaseFromEicIndexId     int `orm:"column(base_from_eic_index_id);pk"`
	Country                string
	Type                   string
	EicCode                string
	ShortName              string
	Name                   string
	Status                 string
	GasDayStartedOn        string
	GasInStorage           string
	GasInStorageCode       string
	Full                   string
	FullCode               string
	Trend                  string
	TrendCode              string
	Injection              string
	InjectionCode          string
	Withdrawal             string
	WithdrawalCode         string
	WorkingGasVolume       string
	WorkingGasVolumeCode   string
	InjectionCapacity      string
	InjectionCapacityCode  string
	WithdrawalCapacity     string
	WithdrawalCapacityCode string
	Info                   string
	CreateTime             time.Time
	ModifyTime             time.Time
}

func GetGieDataByTradeCode(condition string, pars []interface{}) (item []*BaseFromTradeEicIndex, err error) {
	sql := ` SELECT * FROM base_from_trade_eic_index WHERE 1=1 `
	if condition != "" {
		sql += condition
	}
	sql += ` ORDER BY gas_day_started_on DESC `
	err = global.MYSQL["data"].Raw(sql, pars).Scan(&item).Error

	return
}

func GetEdbDataGieByCodeAndDate(edbCode string, startDate string) (count int, err error) {
	sql := ` SELECT COUNT(1) AS count FROM edb_data_gie WHERE edb_code=? AND data_time=? `
	err = global.MYSQL["data"].Raw(sql, edbCode, startDate).Scan(&count).Error

	return
}

type EdbInfoMaxAndMinInfo struct {
	MinDate     string  `description:"最小日期"`
	MaxDate     string  `description:"最大日期"`
	MinValue    float64 `description:"最小值"`
	MaxValue    float64 `description:"最大值"`
	LatestValue float64 `description:"最新值"`
}

func GetEdbInfoMaxAndMinInfo(source int, edbCode string) (item *EdbInfoMaxAndMinInfo, err error) {
	sql := ``
	tableName := GetEdbDataTableName(source)
	sql = ` SELECT MIN(data_time) AS min_date,MAX(data_time) AS max_date,MIN(value) AS min_value,MAX(value) AS max_value FROM %s WHERE edb_code=? `
	sql = fmt.Sprintf(sql, tableName)
	err = global.MYSQL["data"].Raw(sql, edbCode).Scan(&item).Error

	var latest_value float64
	sql = ` SELECT value AS latest_value FROM %s WHERE edb_code=? ORDER BY data_time DESC LIMIT 1 `
	sql = fmt.Sprintf(sql, tableName)
	err = global.MYSQL["data"].Raw(sql, edbCode).Scan(&latest_value).Error
	item.LatestValue = latest_value
	return
}