package trade_analysis

import (
	"eta/eta_api/models/data_manage/trade_analysis"
	"eta/eta_api/utils"
	"fmt"
	"sort"
	"strings"
	"time"
)

func GetClassifyName() (list trade_analysis.TradeClassifyNameListSort, err error, errMsg string) {
	//定义交易所
	exchanges := map[string]string{
		"zhengzhou": "郑商所",
		"dalian":    "大商所",
		"shanghai":  "上期所",
		"cffex":     "中金所",
		"ine":       "上期能源",
	}
	exchangesSortMap := map[string]int{
		"zhengzhou": 1,
		"dalian":    2,
		"shanghai":  3,
		"cffex":     4,
		"ine":       5,
	}
	//查询所有交易所下的分类
	classifyExchangeList, tmpErr := trade_analysis.GetAllBaseFromTradeClassify()
	if tmpErr != nil {
		err = tmpErr
		errMsg = "查询交易所最新更新时间失败"
		return
	}

	// 每个交易所的分类信息
	classifyExchangeMap := make(map[string][]trade_analysis.TradeClassifyName)
	// 每个交易所的最新更新时间
	timeLastMap := make(map[string]time.Time)
	for _, v := range classifyExchangeList {
		tmpExchange := v.Exchange

		// 分类
		tmpList, ok := classifyExchangeMap[tmpExchange]
		if !ok {
			tmpList = make([]trade_analysis.TradeClassifyName, 0)
		}
		tmpList = append(tmpList, trade_analysis.TradeClassifyName{
			ClassifyName: v.ClassifyName,
			ClassifyType: v.ClassifyType,
			LatestDate:   v.LatestDate.Format(utils.FormatDate),
		})
		classifyExchangeMap[v.Exchange] = tmpList

		// 时间
		if tmpLastTime, ok2 := timeLastMap[tmpExchange]; !ok2 {
			timeLastMap[tmpExchange] = v.ModifyTime
		} else {
			if v.ModifyTime.After(tmpLastTime) {
				timeLastMap[tmpExchange] = v.ModifyTime
			}
		}
	}

	i := 0
	currDate := time.Now().Format(utils.FormatDate)
	for k, v := range exchanges {
		tmp := trade_analysis.TradeClassifyNameList{
			Exchange: v,
			Items:    nil,
			Sort:     exchangesSortMap[k],
			CurrDate: currDate,
		}
		nameList, ok := classifyExchangeMap[k]
		if !ok {
			err = fmt.Errorf("查询交易所分类信息失败")
			errMsg = "查询交易所分类信息失败"
			return
		}

		// 查询交易所最新更新时间失败
		if timeLast, ok := timeLastMap[k]; ok {
			tmp.DataTime = timeLast.Format(utils.FormatDateTime)
		} else {
			err = fmt.Errorf("查询交易所最新更新时间失败")
			errMsg = "查询交易所最新更新时间失败"
			return
		}

		classifyMap := make(map[string][]trade_analysis.TradeClassifyNameListItemItem)
		if len(nameList) > 0 {
			if k == "zhengzhou" {
				for _, item := range nameList {
					classifyName := getZhengzhouClassifyName(item.ClassifyName)
					tmpItemItem := trade_analysis.TradeClassifyNameListItemItem{
						ClassifyType: item.ClassifyName,
					}
					classifyMap[classifyName] = append(classifyMap[classifyName], tmpItemItem)
				}
			} else {
				for _, item := range nameList {
					tmpItemItem := trade_analysis.TradeClassifyNameListItemItem{
						ClassifyType: item.ClassifyType,
					}
					classifyMap[item.ClassifyName] = append(classifyMap[item.ClassifyName], tmpItemItem)
				}
			}
			for n, l := range classifyMap {
				sort.Sort(trade_analysis.TradeClassifyNameListItemItemSort(l))
				tmpItems := trade_analysis.TradeClassifyNameListItem{
					ClassifyName: n,
					Items:        l,
				}
				tmp.Items = append(tmp.Items, tmpItems)
				tmp.Num++
			}
		}
		sort.Sort(trade_analysis.TradeClassifyNameListItemSort(tmp.Items))
		list = append(list, tmp)
		i++
	}
	if len(list) > 0 {
		sort.Sort(list)
	}
	return
}

func getZhengzhouClassifyName(code string) (name string) {
	if strings.HasPrefix(code, "PTA") {
		name = "PTA"
		return
	}
	if strings.HasPrefix(code, "TA") {
		name = "PTA"
		return
	}
	if strings.HasPrefix(code, "ZC") {
		name = "动力煤"
		return
	}
	if strings.HasPrefix(code, "WH") {
		name = "强麦"
		return
	}
	if strings.HasPrefix(code, "UR") {
		name = "尿素"
		return
	}
	if strings.HasPrefix(code, "SR") {
		name = "白糖"
		return
	}
	if strings.HasPrefix(code, "SM") {
		name = "锰硅"
		return
	}
	if strings.HasPrefix(code, "SF") {
		name = "硅铁"
		return
	}
	if strings.HasPrefix(code, "SA") {
		name = "纯碱"
		return
	}
	if strings.HasPrefix(code, "RS") {
		name = "油菜籽"
		return
	}
	if strings.HasPrefix(code, "RM") {
		name = "菜籽粕"
		return
	}
	if strings.HasPrefix(code, "RI") {
		name = "早籼稻"
		return
	}
	if strings.HasPrefix(code, "PM") {
		name = "普麦"
		return
	}
	if strings.HasPrefix(code, "PK") {
		name = "花生"
		return
	}
	if strings.HasPrefix(code, "PF") {
		name = "涤纶短纤"
		return
	}
	if strings.HasPrefix(code, "OI") {
		name = "菜油"
		return
	}
	if strings.HasPrefix(code, "MA") {
		name = "甲醇"
		return
	}
	if strings.HasPrefix(code, "LR") {
		name = "晚籼稻"
		return
	}
	if strings.HasPrefix(code, "JR") {
		name = "粳稻"
		return
	}
	if strings.HasPrefix(code, "FG") {
		name = "玻璃"
		return
	}
	if strings.HasPrefix(code, "CY") {
		name = "棉纱"
		return
	}
	if strings.HasPrefix(code, "CJ") {
		name = "红枣"
		return
	}
	if strings.HasPrefix(code, "CF") {
		name = "棉花"
		return
	}
	if strings.HasPrefix(code, "AP") {
		name = "苹果"
		return
	}
	if strings.HasPrefix(code, "PX") {
		name = "PX"
		return
	}
	if strings.HasPrefix(code, "SH") {
		name = "烧碱"
		return
	}
	return
}

func GetPositionTopDetail(req trade_analysis.GetPositionTopReq) (ret trade_analysis.GetPositionTopResp, err error, errMsg string) {
	//定义交易所
	exchanges := map[string]string{
		"郑商所":  "zhengzhou",
		"大商所":  "dalian",
		"上期所":  "shanghai",
		"中金所":  "cffex",
		"上期能源": "ine",
	}
	exchange, ok := exchanges[req.Exchange]
	if !ok {
		errMsg = "请输入正确的交易所名称"
		err = fmt.Errorf(errMsg)
		return
	}
	dataTimeStr := req.DataTime
	var lastDataTime, dataTime time.Time

	//查询最新的时间
	lastItem, tmpErr := trade_analysis.GetTradeTopLastDataTime(exchange, req.ClassifyName, req.ClassifyType)
	if tmpErr != nil {
		errMsg = "查询最新的榜单信息失败"
		err = tmpErr
		return
	}
	lastDataTime = lastItem.LatestDate

	// 如果没有传入日期,那么就用最晚的的日期
	if dataTimeStr == "" {
		dataTime = lastDataTime
	} else {
		dataTime, err = time.ParseInLocation(utils.FormatDate, dataTimeStr, time.Local)
		if err != nil {
			errMsg = "请输入正确的时间格式"
			return
		}
	}
	dataTimeStr = dataTime.Format(utils.FormatDate)

	ret.DataTime = dataTimeStr
	ret.LastDataTime = lastDataTime.Format(utils.FormatDate)

	//遇到周末则跳过当天
	weekStr := dataTime.Weekday().String()
	if weekStr == "Sunday" || weekStr == "Saturday" {
		/*errMsg = "日期不正确"
		err = fmt.Errorf(errMsg)*/
		return
	}
	classifyName := req.ClassifyName
	classifyType := req.ClassifyType
	if exchange == "zhengzhou" {
		classifyName = classifyType
		var typeItem *trade_analysis.TradeClassifyName
		typeItem, err = trade_analysis.GetClassifyTypeByClassifyName(exchange, classifyName)
		if err != nil {
			if err.Error() == utils.ErrNoRow() {
				errMsg = "该合约不存在"
				return
			}
			errMsg = "查询类型信息出错"
			return
		}
		classifyType = typeItem.ClassifyType

	}
	//查询当日榜单列表
	dataList, tmpErr := trade_analysis.GetTradePositionTop(exchange, classifyName, classifyType, dataTimeStr)
	if tmpErr != nil {
		errMsg = "查询榜单列表失败"
		err = tmpErr
		return
	}
	if len(dataList) <= 0 {
		return
	}
	totalMap := make(map[int]int)
	totalChangeMap := make(map[int]int)
	totalTmpMap := make(map[int]int)
	totalChangeTmpMap := make(map[int]int)

	detailList := make(map[int][]trade_analysis.GetPositionTopListItem)
	//统计汇总数据
	for _, v := range dataList {
		if t, ok1 := totalMap[v.DealType]; ok1 {
			totalMap[v.DealType] = t + v.DealValue
		} else {
			totalMap[v.DealType] = v.DealValue
		}
		if t, ok1 := totalChangeMap[v.DealType]; ok1 {
			totalChangeMap[v.DealType] = t + v.DealChange
		} else {
			totalChangeMap[v.DealType] = v.DealChange
		}
	}
	_, okTmp1 := totalMap[1]
	_, okTmp2 := totalMap[2]
	_, okTmp3 := totalMap[3]
	_, okTmp4 := totalMap[4]

	if !okTmp1 || !okTmp2 || (!okTmp3 && !okTmp4) {
		errMsg = "榜单数据缺失"
		err = fmt.Errorf(errMsg)
		return
	}

	for k, v := range dataList {
		k++
		if t, ok1 := totalTmpMap[v.DealType]; ok1 {
			totalTmpMap[v.DealType] = t + v.DealValue
		} else {
			totalTmpMap[v.DealType] = v.DealValue
		}
		if t, ok1 := totalChangeTmpMap[v.DealType]; ok1 {
			totalChangeTmpMap[v.DealType] = t + v.DealChange
		} else {
			totalChangeTmpMap[v.DealType] = v.DealChange
		}

		tmp := trade_analysis.GetPositionTopListItem{
			DealShortName:   v.DealShortName,
			DealValue:       v.DealValue,
			DealChange:      v.DealChange,
			Rank:            v.Rank,
			BeforeAllValue:  totalTmpMap[v.DealType],
			BeforeAllChange: totalChangeTmpMap[v.DealType],
		}
		//统计占比
		rate := fmt.Sprintf("%.2f", float64(tmp.DealValue)/float64(totalMap[v.DealType]))               // 保留2位小数
		beforeAllRate := fmt.Sprintf("%.2f", float64(tmp.BeforeAllValue)/float64(totalMap[v.DealType])) // 保留2位小数
		tmp.Rate = rate
		tmp.BeforeAllRate = beforeAllRate
		if tmp.DealShortName == "-" {
			continue
		}
		detailList[v.DealType] = append(detailList[v.DealType], tmp)
	}
	ret.BuyList.TotalDealValue = totalMap[1]
	ret.BuyList.TotalDealChange = totalChangeMap[1]
	ret.BuyList.List = detailList[1]

	ret.SoldList.TotalDealValue = totalMap[2]
	ret.SoldList.TotalDealChange = totalChangeMap[2]
	ret.SoldList.List = detailList[2]

	ret.CleanBuyList.TotalDealValue = totalMap[3]
	ret.CleanBuyList.TotalDealChange = totalChangeMap[3]
	ret.CleanBuyList.List = detailList[3]

	ret.CleanSoldList.TotalDealValue = totalMap[4]
	ret.CleanSoldList.TotalDealChange = totalChangeMap[4]
	ret.CleanSoldList.List = detailList[4]

	return
}