package services

import (
	"encoding/json"
	"eta/eta_crawler/models"
	"eta/eta_crawler/services/alarm_msg"
	"eta/eta_crawler/utils"
	"fmt"
	"github.com/mozillazg/go-pinyin"
	"github.com/rdlucklib/rdluck_tools/http"
	"strings"
	"time"
)

type JSONData struct {
	OCursor    []OCursor   `json:"o_cursor"`
	OCode      interface{} `json:"o_code"`
	OMsg       string      `json:"o_msg"`
	ReportDate string      `json:"report_date"`
	UpdateDate string      `json:"update_date"`
}
type OCursor struct {
	Instrumentid     string      `json:"INSTRUMENTID"`
	Participantid3   string      `json:"PARTICIPANTID3"`
	Participantid2   string      `json:"PARTICIPANTID2"`
	Participantid1   string      `json:"PARTICIPANTID1"`
	Participantabbr3 string      `json:"PARTICIPANTABBR3"`
	Participantabbr2 string      `json:"PARTICIPANTABBR2"`
	Rank             int         `json:"RANK"`
	Participantabbr1 string      `json:"PARTICIPANTABBR1"`
	BuyIn            interface{} `json:"CJ2"`
	Deal             interface{} `json:"CJ1"`
	Change1          interface{} `json:"CJ1_CHG"`
	Change3          interface{} `json:"CJ3_CHG"`
	Productname      string      `json:"Productname"`
	Productsortno    interface{} `json:"PRODUCTSORTNO"`
	SoldOut          interface{} `json:"CJ3"`
	Change2          interface{} `json:"CJ2_CHG"`
}

var ineIndexCode string
var ineIndexCodeMap = make(map[string]string)

func IneIndexCodeGenerator(shortName, indexName, Instrumentid, suffix string) string {
	if shortName == "" {
		return ""
	}
	strResult := ""
	if shortName != "top20" {
		//取公司全拼
		a := pinyin.NewArgs()
		rows := pinyin.LazyPinyin(shortName, a)
		for i := 0; i < len(rows); i++ {
			strResult += rows[i]
		}
	} else {
		strResult = "top20"
	}
	ineIndexCode, _ := ineIndexCodeMap[indexName]
	if ineIndexCode == "" {
		ineIndexCode = strResult + Instrumentid + suffix
		ineIndexCode = strings.Replace(ineIndexCode, " ", "", -1)
		ineIndexCodeMap[indexName] = ineIndexCode
		err := models.AddBaseFromTradeMapping(indexName, ineIndexCode, "INE")
		if err != nil {
			fmt.Println("add Code err:", err)
		}
	}
	return strings.Replace(ineIndexCode, " ", "", -1)
}

// SyncRankingFromIne 上海能源交易中心持单排名
func SyncRankingFromIne() {
	var err error
	defer func() {
		if err != nil {
			msg := "失败提醒" + "SyncRankingFromIne ErrMsg:" + err.Error()
			go alarm_msg.SendAlarmMsg(msg, 3)
		}
	}()
	n := utils.GetRandInt(10, 120)
	time.Sleep(time.Duration(n) * time.Second)
	allCode, err := models.GetIndexCodeFromMapping("Ine")
	if err != nil {
		fmt.Println("select Code err:", err)
	}
	for _, item := range allCode {
		ineIndexCodeMap[item.IndexName] = item.IndexCode
	}
	//获取新的指标信息
	for i := 10; i >= 0; i-- {
		var message JSONData
		var item = new(models.BaseFromTradeIneIndex)
		zzUrl := "http://www.ine.com.cn/data/dailydata/kx/pm%s.dat"
		date := time.Now().AddDate(0, 0, -i)
		dateStr := date.Format(utils.FormatDateUnSpace)
		zzUrl = fmt.Sprintf(zzUrl, dateStr)
		fmt.Println(zzUrl)
		body, err := http.Get(zzUrl)
		if err != nil {
			fmt.Println("err:", err)
		}
		if body == nil {
			return
		}
		err = json.Unmarshal(body, &message)
		if err != nil {
			fmt.Println("Unmarshal Err:", err)
			continue
		}
		var position = message.OCursor
		var tradeDate = message.ReportDate
		existIndexMap := make(map[string]*models.BaseFromTradeIneIndex)

		//获取所有指标信息
		allIndex, err := models.GetBaseFromTradeIneIndexAll(dateStr)
		if err != nil {
			fmt.Println("select err:", err)
		}
		for _, v := range allIndex {
			indexKey := v.DealName + v.BuyName + v.SoldName
			existIndexMap[indexKey] = v
		}
		var itemVerifyCode int
		//处理指标
		for _, p := range position {
			if p.Rank > 0 && p.Rank < 40 && p.Participantabbr1 != "" {
				//成交量
				item.Rank = p.Rank
				item.DealShortName = p.Participantabbr1
				item.BuyShortName = p.Participantabbr2
				item.SoldShortName = p.Participantabbr3
				item.DealName = strings.Replace(fmt.Sprintf("%s", p.Participantabbr1+"_"+p.Instrumentid+"_成交量(手)"), " ", "", -1)
				item.BuyName = strings.Replace(fmt.Sprintf("%s", p.Participantabbr2+"_"+p.Instrumentid+"_持买单量(手)"), " ", "", -1)
				item.SoldName = strings.Replace(fmt.Sprintf("%s", p.Participantabbr3+"_"+p.Instrumentid+"_持卖单量(手)"), " ", "", -1)
				item.DealCode = IneIndexCodeGenerator(item.DealShortName, item.DealName, p.Instrumentid, "deal")
				item.BuyCode = IneIndexCodeGenerator(item.BuyShortName, item.BuyName, p.Instrumentid, "buy")
				item.SoldCode = IneIndexCodeGenerator(item.SoldShortName, item.SoldName, p.Instrumentid, "sold")
				item.ClassifyName = strings.Replace(p.Productname, " ", "", -1)
				item.ClassifyType = strings.Replace(p.Instrumentid, " ", "", -1)
				item.Frequency = "日度"
				item.CreateTime = time.Now()
				item.ModifyTime = time.Now()
				item.DataTime = tradeDate

				if deal, ok := p.Deal.(float64); ok {
					item.DealValue = int(deal)
				}
				if change1, ok := p.Change1.(float64); ok {
					item.DealChange = int(change1)
				}
				if buyIn, ok := p.BuyIn.(float64); ok {
					item.BuyValue = int(buyIn)
				}
				if change2, ok := p.Change2.(float64); ok {
					item.BuyChange = int(change2)
				}
				if soldOut, ok := p.SoldOut.(float64); ok {
					item.SoldValue = int(soldOut)
				}
				if change3, ok := p.Change3.(float64); ok {
					item.SoldChange = int(change3)
				}

				itemVerifyCode = item.BuyValue + item.DealValue + item.SoldValue
				if existIndex, ok := existIndexMap[item.DealName+item.BuyName+item.SoldName]; !ok {
					newID, err := models.AddBaseFromTradeIneIndex(item)
					if err != nil {
						fmt.Println("insert error:", err)
					}
					fmt.Println("insert new indexID:", newID)
				} else if existIndex != nil && itemVerifyCode != (existIndex.DealValue+existIndex.BuyValue+existIndex.SoldValue) {
					//更新
					err := models.ModifyBaseFromTradeIneIndex(item.DealValue, item.BuyValue, item.SoldValue, existIndex.BaseFromTradeIneIndexId)
					if err != nil {
						fmt.Println("data update err:", err)
					}
				}
			} else if p.Rank == 999 {
				//Top 20
				item.Rank = p.Rank
				item.DealShortName = p.Participantabbr1
				item.BuyShortName = p.Participantabbr2
				item.SoldShortName = p.Participantabbr3
				item.DealName = strings.Replace(fmt.Sprintf("%s", "top20_"+p.Instrumentid+"_成交量(手)"), " ", "", -1)
				item.BuyName = strings.Replace(fmt.Sprintf("%s", "top20_"+p.Instrumentid+"_持买单量(手)"), " ", "", -1)
				item.SoldName = strings.Replace(fmt.Sprintf("%s", "top20_"+p.Instrumentid+"_持卖单量(手)"), " ", "", -1)
				item.DealCode = IneIndexCodeGenerator("top20", item.DealName, p.Instrumentid, "deal")
				item.BuyCode = IneIndexCodeGenerator("top20", item.BuyName, p.Instrumentid, "buy")
				item.SoldCode = IneIndexCodeGenerator("top20", item.SoldName, p.Instrumentid, "sold")
				item.ClassifyName = strings.Replace(p.Productname, " ", "", -1)
				item.ClassifyType = strings.Replace(p.Instrumentid, " ", "", -1)
				item.Frequency = "日度"
				item.CreateTime = time.Now()
				item.ModifyTime = time.Now()
				item.DataTime = tradeDate

				if deal, ok := p.Deal.(float64); ok {
					item.DealValue = int(deal)
				}
				if change1, ok := p.Change1.(float64); ok {
					item.DealChange = int(change1)
				}
				if buyIn, ok := p.BuyIn.(float64); ok {
					item.BuyValue = int(buyIn)
				}
				if change2, ok := p.Change2.(float64); ok {
					item.BuyChange = int(change2)
				}
				if soldOut, ok := p.SoldOut.(float64); ok {
					item.SoldValue = int(soldOut)
				}
				if change3, ok := p.Change3.(float64); ok {
					item.SoldChange = int(change3)
				}

				itemVerifyCode = item.BuyValue + item.DealValue + item.SoldValue
				if existIndex, ok := existIndexMap[item.DealName+item.BuyName+item.SoldName]; !ok {
					newID, err := models.AddBaseFromTradeIneIndex(item)
					if err != nil {
						fmt.Println("insert error:", err)
					}
					fmt.Println("insert new indexID:", newID)
				} else if existIndex != nil && itemVerifyCode != (existIndex.DealValue+existIndex.BuyValue+existIndex.SoldValue) {
					//更新
					err := models.ModifyBaseFromTradeIneIndex(item.DealValue, item.BuyValue, item.SoldValue, existIndex.BaseFromTradeIneIndexId)
					if err != nil {
						fmt.Println("data update err:", err)
					}
				}
			}
		}
	}
	fmt.Println("end")
}