package eas

import (
	json "encoding/json"
	"fmt"

	"gitlab.alibaba-inc.com/pai_biz_arch/pairec/algorithm/eas/easyrec"
	"gitlab.alibaba-inc.com/pai_biz_arch/pairec/algorithm/response"
)

type EasyrecResponse struct {
	RawFeatures      string
	GenerateFeatures string
	ContextFeatures  string
	multiValModule   bool
	score            float64
	scoreArr         map[string]float64
}

func (r *EasyrecResponse) GetScore() float64 {
	return r.score
}

func (r *EasyrecResponse) GetScoreMap() map[string]float64 {
	return r.scoreArr
}

func (r *EasyrecResponse) GetModuleType() bool {
	return r.multiValModule
}

func easyrecMutValResponseFunc(data interface{}) (ret []response.AlgoResponse, err error) {
	resp, ok := data.(*easyrec.PBResponse)
	if !ok {
		err = fmt.Errorf("invalid data type, %v", data)
		return
	}
	outputs := resp.GetOutputs()
	var response []map[string]float64
	for _, itemId := range resp.ItemIds {
		if result, ok := resp.Results[itemId]; ok {
			scores := make(map[string]float64)
			if len(outputs) == len(result.Scores) {
				for k, score := range result.Scores {
					scores[outputs[k]] = score
				}
			} else {
				err = fmt.Errorf("outputs size is not equal scores")
				return
			}

			response = append(response, scores)
		} else {
			scores := make(map[string]float64)
			for _, out := range outputs {
				scores[out] = float64(0)
			}
			response = append(response, scores)
		}
	}

	for _, v := range response {
		ret = append(ret, &EasyrecResponse{scoreArr: v, multiValModule: true})
	}

	return
}

func easyrecMutValResponseFuncDebug(data interface{}) (ret []response.AlgoResponse, err error) {
	resp, ok := data.(*easyrec.PBResponse)
	if !ok {
		err = fmt.Errorf("invalid data type, %v", data)
		return
	}
	outputs := resp.GetOutputs()
	var response []map[string]float64
	var (
		itemFeatures     []string
		generateFeatures []string
		contextFeatures  []string
	)
	for _, itemId := range resp.ItemIds {
		// if result, ok := resp.Results[itemId]; ok {
		// scores := make(map[string]float64)
		// if len(outputs) == len(result.Scores) {
		// for k, score := range result.Scores {
		// scores[outputs[k]] = score
		// }
		// } else {
		// err = fmt.Errorf("outputs size is not equal scores")
		// return
		// }
		//
		// response = append(response, scores)
		// } else {
		// scores := make(map[string]float64)
		// for _, out := range outputs {
		// scores[out] = float64(0)
		// }
		// response = append(response, scores)
		// }
		scores := make(map[string]float64)
		for _, out := range outputs {
			scores[out] = float64(0)
		}
		response = append(response, scores)

		if f, ok := resp.RawFeatures[itemId]; ok {
			itemFeatures = append(itemFeatures, f)
		} else {
			itemFeatures = append(itemFeatures, "")
		}

		if g, ok := resp.GenerateFeatures[itemId]; ok {
			generateFeatures = append(generateFeatures, g)
		} else {
			generateFeatures = append(generateFeatures, "")
		}
		if c, ok := resp.ContextFeatures[itemId]; ok {
			features := c.Features
			j, _ := json.Marshal(features)
			contextFeatures = append(contextFeatures, string(j))
		} else {
			contextFeatures = append(contextFeatures, "")
		}
	}

	for i, v := range response {
		ret = append(ret, &EasyrecResponse{scoreArr: v, multiValModule: true, RawFeatures: itemFeatures[i], GenerateFeatures: generateFeatures[i], ContextFeatures: contextFeatures[i]})
	}

	return
}

func easyrecResponseFunc(data interface{}) (ret []response.AlgoResponse, err error) {
	resp, ok := data.(*easyrec.PBResponse)
	if !ok {
		err = fmt.Errorf("invalid data type, %v", data)
		return
	}

	for _, itemId := range resp.ItemIds {
		if results, ok := resp.Results[itemId]; ok {
			ret = append(ret, &EasyrecResponse{score: results.Scores[0]})
		} else {
			ret = append(ret, &EasyrecResponse{score: float64(0)})
		}
	}

	return
}
func easyrecResponseFuncDebug(data interface{}) (ret []response.AlgoResponse, err error) {
	resp, ok := data.(*easyrec.PBResponse)
	if !ok {
		err = fmt.Errorf("invalid data type, %v", data)
		return
	}

	for _, itemId := range resp.ItemIds {
		itemFeatures := ""
		generateFeatures := ""
		contextFeatures := ""
		if f, ok := resp.RawFeatures[itemId]; ok {
			itemFeatures = f
		}

		if g, ok := resp.GenerateFeatures[itemId]; ok {
			generateFeatures = g
		}

		if c, ok := resp.ContextFeatures[itemId]; ok {
			features := c.Features
			j, _ := json.Marshal(features)
			contextFeatures = string(j)
		}

		if results, ok := resp.Results[itemId]; ok {
			ret = append(ret, &EasyrecResponse{score: results.Scores[0], RawFeatures: itemFeatures, GenerateFeatures: generateFeatures, ContextFeatures: contextFeatures})
		} else {
			ret = append(ret, &EasyrecResponse{score: float64(0), RawFeatures: itemFeatures, GenerateFeatures: generateFeatures, ContextFeatures: contextFeatures})
		}
	}

	return
}
