package extract

import (
	"fmt"
	"jy/clear"
	"jy/util"
	"log"
	util2 "qfw/util"
	"regexp"
	"strings"
	"unicode/utf8"
)

//清理html
var htmlclrear = regexp.MustCompile("</?[^>]+>")

//清理括号结尾
var endOfParenthesesClrear = regexp.MustCompile(`[\\(\\[（【\\{]+[\\u4e00-\\u9fa5\s]*[\\)）\\]】\\}]+$`)

//清理标点符合结尾
var endOfPunctuationClrear = regexp.MustCompile("[,，.。?？;；]+$")

//清理关键字
var keysClrear = regexp.MustCompile("(详见|公告|X|内文|某单位|某部|文件|\\*|暂无|？|\\?)")

//jsondata清理
func clearJd(jd *map[string]interface{}, e *ExtractTask, spiderCode string, isclearnMoney string) {
	for k, v := range *jd {
		if k == "buyer" || k == "winner" || k == "agency" || k == "projectcode" || k == "projectname" {
			vstring := util2.ObjToString(v)
			if vstring == "" {
				delete(*jd, k)
				continue
			}
			//函数清理
			lockclear.Lock()
			cfn := e.ClearFn[k]
			lockclear.Unlock()
			if len(cfn) > 0 {
				data := clear.DoClearFn(cfn, []interface{}{vstring, ""}, spiderCode, isclearnMoney)
				lockclear.Lock()
				if clear.AsyField[k] != nil || clear.SymField[k] != nil || clear.MesField[k] != nil {
					vstring = clear.OtherClean(k, util2.ObjToString(data[0]))
				}
				lockclear.Unlock()
			}
			vstring = htmlclrear.ReplaceAllString(vstring, "")
			vstring = endOfParenthesesClrear.ReplaceAllString(vstring, "")
			vstring = endOfPunctuationClrear.ReplaceAllString(vstring, "")
			if utf8.RuneCountInString(vstring) < 5 {
				delete(*jd, k)
				continue
			}
			if utf8.RuneCountInString(vstring) > 35 {
				delete(*jd, k)
				continue
			} else {
				(*jd)[k] = vstring
			}
		} else if k == "Detail" {
			delete(*jd, k)
		}
	}
}

func JsonDataMergeProcessing(j *util.Job, e *ExtractTask) map[string][]*util.ExtField {
	jdextweight := util2.IntAll((*j.Jsondata)["extweight"])
	if jdextweight == 0 {
		return j.Result
	}
	tmps := make(map[string][]*util.ExtField)
	for _, v := range util.JsonData {
		//jsondata没有值跳过
		if j.Jsondata == nil || (*j.Jsondata)[v] == nil || (*j.Jsondata)[v] == "" {
			continue
		}
		tmp := make([]*util.ExtField, 0)
		//jsondata有值，res没有值，取jsondata值
		if j.Result[v] == nil || len(j.Result[v]) == 0 {
			if v == "budget" || v == "bidamount" {
				lockclear.Lock()
				cfn := e.ClearFn[v]
				lockclear.Unlock()
				if len(cfn) == 0 {
					continue
				}
				newNum := clear.DoClearFn(cfn, []interface{}{(*j.Jsondata)[v], ""}, j.SpiderCode, j.IsClearnMoney)
				//if util2.IntAll(newNum[0]) != 0 {
				extFields := make([]*util.ExtField, 0)
				extFields = append(extFields, &util.ExtField{Code: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), Field: v, ExtFrom: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), SourceValue: (*j.Jsondata)[v], Value: newNum[0], Score: 0.1, IsTrue: newNum[len(newNum)-1].(bool)})
				j.Result[v] = extFields
				//AddExtLog("extract", j.SourceMid, nil, newNum[0], &RegLuaInfo{ "JsonData_"+v, "", v, "", false, nil, nil}, e.TaskInfo) //抽取日志
				//AddExtLog("clear", j.SourceMid, (*j.Jsondata)[v], newNum[0], &RegLuaInfo{ "JsonData_"+v, "", v, "", false, nil, nil}, e.TaskInfo) //抽取日志
				//}
				continue
			} else if v == "bidopentime" {
				lockclear.Lock()
				cfn := e.ClearFn[v]
				lockclear.Unlock()
				if len(cfn) == 0 {
					continue
				}
				extFields := make([]*util.ExtField, 0)
				if bt, ok := (*j.Jsondata)[v].(float64); ok && bt > 0 {
					extFields = append(extFields, &util.ExtField{Code: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), Field: v, ExtFrom: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), SourceValue: (*j.Jsondata)[v], Value: bt, Score: 0.1})
				} else {
					newNum := clear.DoClearFn(cfn, []interface{}{(*j.Jsondata)[v], ""}, j.SpiderCode, j.IsClearnMoney)
					extFields = append(extFields, &util.ExtField{Code: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), Field: v, ExtFrom: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), SourceValue: (*j.Jsondata)[v], Value: newNum[0], Score: 0.1})
				}
				j.Result[v] = extFields
				continue
			}
			vv := strings.TrimSpace(util2.ObjToString((*j.Jsondata)[v]))
			if vv == "" || strings.Contains(vv, "详见公告") {
				continue
			}
			lockscore.Lock()
			scoreRule := SoreConfig[v]
			lockscore.Unlock()
			tmpExtField := &util.ExtField{Code: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), Field: v, ExtFrom: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), SourceValue: (*j.Jsondata)[v], Value: vv, Score: 0.1}
			//1.长度打分
			valueLen := utf8.RuneCountInString(fmt.Sprint(tmpExtField.Value))
			if valueLen < 1 {
				tmpExtField.Score = -5
				continue
			}
			if valueLen > 100 {
				tmpExtField.Score = -99
			}
			if lengths, ok := scoreRule["length"].([]interface{}); ok {
				for _, tmp := range lengths {
					if length, ok := tmp.(map[string]interface{}); ok {
						if ranges, ok := length["range"].([]interface{}); ok {
							gt := util2.IntAll(ranges[0])
							lte := util2.IntAll(ranges[1])
							if lte < 0 { //∞
								lte = 999999
							}
							score := util2.Float64All(ranges[2])
							if valueLen > gt && valueLen <= lte {
								tmpExtField.Score += score
								break
							}
						}
					}
				}
			}
			//2.负面词打分
			if positions, ok := scoreRule["negativewords"].([]interface{}); ok {
				for _, position := range positions {
					if p, ok := position.(map[string]interface{}); ok {
						util2.Try(func() {
							if p["regexp"] != nil {
								reg := p["regexp"].(*regexp.Regexp)
								if reg.MatchString(util2.ObjToString(tmpExtField.Value)) {
									tmpExtField.Score += util2.Float64All(p["score"])
								}
							}
						}, func(err interface{}) {
							log.Println(err)
						})
					}
				}
			}
			//3.正面词打分
			if positions, ok := scoreRule["positivewords"].([]interface{}); ok {
				for _, position := range positions {
					if p, ok := position.(map[string]interface{}); ok {
						util2.Try(func() {
							if p["regexp"] != nil {
								reg := p["regexp"].(*regexp.Regexp)
								if reg.MatchString(util2.ObjToString(tmpExtField.Value)) {
									tmpExtField.Score += util2.Float64All(p["score"])
								}
							}
						}, func(err interface{}) {
							log.Println(err)
						})
					}
				}
			}
			if tmpExtField.Score > 0 {
				extFields := make([]*util.ExtField, 0)
				extFields = append(extFields, tmpExtField)
				j.Result[v] = extFields
			}
			//AddExtLog("extract", j.SourceMid, nil, (*j.Jsondata)[v], &RegLuaInfo{  "JsonData_"+v, "", v, "", false, nil, nil}, e.TaskInfo) //抽取日志
			//AddExtLog("clear", j.SourceMid, (*j.Jsondata)[v], (*j.Jsondata)[v], &RegLuaInfo{  "JsonData_"+v, "", v, "", false, nil, nil}, e.TaskInfo) //抽取日志
			continue
		} else {
			if jdextweight == 0 {
				continue
			}
			oneScore := j.Result[v][0].Score
			if oneScore < 0 {
				oneScore = 0
			}else {
				oneScore -= 0.5
			}
			if v == "budget" || v == "bidamount" {
				lockclear.Lock()
				cfn := e.ClearFn[v]
				lockclear.Unlock()
				if len(cfn) == 0 {
					continue
				}
				newNum := clear.DoClearFn(cfn, []interface{}{(*j.Jsondata)[v], ""}, j.SpiderCode, j.IsClearnMoney)
				if newNum[len(newNum)-1].(bool) {
					//if util2.IntAll(newNum[0]) != 0 {
					extFields := make([]*util.ExtField, 0)
					if jdextweight > 1 {
						if oneScore < 0 {
							oneScore = 0.1
						}else {
							oneScore -= 0.5
						}
						extFields = append(extFields, &util.ExtField{Code: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), Field: v, ExtFrom: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), SourceValue: (*j.Jsondata)[v], Value: newNum[0], Score: oneScore + 1, IsTrue: newNum[len(newNum)-1].(bool)})
					} else {
						if oneScore < 0 {
							oneScore = 0.1
						}else {
							oneScore -= 0.5
						}
						extFields = append(extFields, &util.ExtField{Code: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), Field: v, ExtFrom: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), SourceValue: (*j.Jsondata)[v], Value: newNum[0], Score: oneScore, IsTrue: newNum[len(newNum)-1].(bool)})
					}
					j.Result[v] = append(j.Result[v], extFields...)
				}
				continue
			}

			if strings.Trim(util2.ObjToString(j.Result[v][0].Value), " ") != strings.Trim(util2.ObjToString((*j.Jsondata)[v]), " ") {
				jdtmp := &util.ExtField{j.Result[v][0].BlockTag,
					j.Result[v][0].Field, j.Result[v][0].Code, j.Result[v][0].RuleText,
					j.Result[v][0].Type, j.Result[v][0].MatchType, j.Result[v][0].ExtFrom,
					j.Result[v][0].SourceValue, j.Result[v][0].Value, j.Result[v][0].Score,
					j.Result[v][0].ScoreItem, j.Result[v][0].Weight, j.Result[v][0].ValRepeat,
					j.Result[v][0].IsTrue}
				tmp = append(tmp, jdtmp)
				if jdextweight == 2 {
					oneScore += 2
				}
				tmp = append(tmp, &util.ExtField{Code: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), Field: v, ExtFrom: "JsonData_" + v + "_" + fmt.Sprint(jdextweight), SourceValue: (*j.Jsondata)[v], Value: strings.Trim(util2.ObjToString((*j.Jsondata)[v]), " "), Score: oneScore, ScoreItem: []*util.ScoreItem{&util.ScoreItem{
					Des:       "jsondata初始化,取抽取分第一个",
					Code:      "init_jsondata",
					RuleText:  "init_jsondata",
					ScoreFrom: "j.Result[0]",
					Value:     strings.TrimSpace(util2.ObjToString((*j.Jsondata)[v])),
					Score:     oneScore,
				}}})
				tmps[v] = tmp
			}
		}
	}
	if jdextweight < 2 {
		for k, v := range tmps {
			lockscore.Lock()
			scoreRule := SoreConfig[k]
			lockscore.Unlock()
			if k == "projectname" || k == "projectcode" || k == "buyer" || k == "winner" || k == "agency" || k == "buyerperson" || k == "buyertel" {
				for i, tmpsvalue := range v {
					//1.长度打分
					valueLen := utf8.RuneCountInString(fmt.Sprint(tmpsvalue.Value))
					if valueLen < 1 {
						v[i].Score = -5
						continue
					}
					if valueLen > 100 {
						v[i].Score = -99
					}
					if lengths, ok := scoreRule["length"].([]interface{}); ok {
						for _, tmp := range lengths {
							if length, ok := tmp.(map[string]interface{}); ok {
								if ranges, ok := length["range"].([]interface{}); ok {
									gt := util2.IntAll(ranges[0])
									lte := util2.IntAll(ranges[1])
									if lte < 0 { //∞
										lte = 999999
									}
									score := util2.Float64All(ranges[2])
									if valueLen > gt && valueLen <= lte {
										v[i].Score += score
										v[i].ScoreItem = append(v[i].ScoreItem, &util.ScoreItem{Des: "JsonData长度打分", Code: fmt.Sprint(gt, "<", valueLen, "<=", lte), ScoreFrom: "fieldscore.json.length", Value: tmpsvalue.Value, Score: score})
										break
									}
								}
							}
						}
					}
					//2.负面词打分
					if positions, ok := scoreRule["negativewords"].([]interface{}); ok {
						for _, position := range positions {
							if p, ok := position.(map[string]interface{}); ok {
								util2.Try(func() {
									if p["regexp"] != nil {
										reg := p["regexp"].(*regexp.Regexp)
										if reg.MatchString(util2.ObjToString(tmpsvalue.Value)) {
											v[i].Score += util2.Float64All(p["score"])
											v[i].ScoreItem = append(v[i].ScoreItem, &util.ScoreItem{Des: "JsonData负面词打分" + fmt.Sprint(p["describe"]), Code: "negativewords", RuleText: reg.String(), ScoreFrom: "fieldscore.json.negativewords", Value: tmpsvalue.Value, Score: util2.Float64All(p["score"])})
										}
									}
								}, func(err interface{}) {
									log.Println(err)
								})
							}
						}
					}
					//3.正面词打分
					if positions, ok := scoreRule["positivewords"].([]interface{}); ok {
						for _, position := range positions {
							if p, ok := position.(map[string]interface{}); ok {
								util2.Try(func() {
									if p["regexp"] != nil {
										reg := p["regexp"].(*regexp.Regexp)
										if reg.MatchString(util2.ObjToString(tmpsvalue.Value)) {
											v[i].Score += util2.Float64All(p["score"])
											v[i].ScoreItem = append(v[i].ScoreItem, &util.ScoreItem{Des: "Jsondata正面词打分" + fmt.Sprint(p["describe"]), Code: "positivewords", RuleText: reg.String(), ScoreFrom: "fieldscore.json.positivewords", Value: tmpsvalue.Value, Score: util2.Float64All(p["score"])})
										}
									}
								}, func(err interface{}) {
									log.Println(err)
								})
							}
						}
					}
				}
			}
		}
	}

	for k, v := range tmps { //新打分的结果集放入到result中,v为数组只有2个值
		if v[0].Score == v[1].Score { //分数相等优先取打分的值
			if v[0].ExtFrom == "JsonData_"+k+"_"+fmt.Sprint(jdextweight) {
				j.Result[k] = append(j.Result[k], v[1])
			} else {
				j.Result[k] = append(j.Result[k], v[0])
			}
			continue
		}
		j.Result[k] = append(j.Result[k], v...) //分数不相等就放入result排序
	}

	//结果排序
	for _, val := range j.Result {
		util.Sort(val)
	}

	return j.Result
}
