package pretreated

import (
	//"jy/clear"
	"jy/util"
	qutil "qfw/util"
	"regexp"
	"strconv"
	"strings"
)

type WinnerOrderEntity struct {
}
type WinnerFlag struct {
	index     int //数组索引
	start     int //数组开始索引
	end       int //数组结束索引
	textStart int //文本开始索引
	textEnd   int //文本结束索引
	max       int
	indexs    []int
}

var (
	winnerOrderEntity = &WinnerOrderEntity{}
	numberReg         = regexp.MustCompile("[一二三四五六七八九十0-9]+")
	numberReg2        = regexp.MustCompile("[\\d一二三四五六七八九十.,，]+")
	thisNumberReg     = regexp.MustCompile("第" + numberReg.String())
	winnerReg1        = regexp.MustCompile("(^|[^为])(【?(推荐)?第[一二三四五六七八九十1-9]+(合格|名|包|标段)?】?((候|侯)选)?(备选|成交|中(标|选))人?([(（]成交[）)])?((候|侯)选|排序)?(人(单位)?|供应商|单位|机构)(名称)?为?)($|[^，；;。,])")
	winnerReg2        = regexp.MustCompile("(排名第[一二三四五六七八九十1-9]+|第[一二三四五六七八九十1-9]+(候|侯)选人)")
	//winnerReg2     = regexp.MustCompile("(第[一二三四五六七八九十1-9]+(候|侯)选人)")
	winnerReg3     = regexp.MustCompile("(第[一二三四五六七八九十1-9]+名)")
	winnerReg4     = regexp.MustCompile("((确认|推荐|评审|排(名|序))[为:：]+|(由高到低排序前.名|公示下列内容|(确定|推荐)的?中(标|选)候选人|\n中(标|选)候选.{1,3}\\s*\n|\n(中(标|选)候选.{1,3}[:：\u3000\u2003\u00a0\\s]|成交候选供应商)|(排(名|序)|公(示|告)|具体|推荐|结果(公示)?|中(标|选)候选人.{0,2})如下|[一二三四五六七八九十\\d]+、(中(标|选)候选[^\n:：]{1,8}|.{0,8}(成交|结果)信息|成交[^\n:：]{2,8}))[为:：]?)")
	winnerReg5     = regexp.MustCompile("([^，；;。,、\n]+?)(为?)(第[一二三四五六七八九十1-9]+(成交|中标)?((候|侯)选(人|供应商|单位|机构)|名)|排名第[一二三四五六七八九十1-9]+)([，；;。,、]|\\s+\n)")
	winnerReg6     = regexp.MustCompile("(^(排名)?第[一二三四五六七八九十1-9]+[名中标成交备选候选人单位供应商]*)")
	colonEndReg    = regexp.MustCompile("[:：]$")
	toWarpReg      = regexp.MustCompile("[，。,;；]+")
	findamountReg  = regexp.MustCompile("[，。,;；\u3000\u2003\u00a0\\s]+")
	amountReg      = regexp.MustCompile("^\\d+(\\.\\d+)?((百|千)?元|(百|千)?(万|亿)元?)$")
	companyWarpReg = regexp.MustCompile("(公司)(.+?[:：])")
	findCompanyReg = regexp.MustCompile("[^:：]+公司")
	colonSpaceReg  = regexp.MustCompile("[:：]\\s+")
	findCandidate  = regexp.MustCompile("(^.{5,}(公司|集团|单位|机构|企业|厂|场|院|所|店|中心|市|局|站|城|处|行|部|队|联合(会|体))|工作室)")
	findCandidate2 = regexp.MustCompile("(^.{5,}(公司|集团|单位|机构|企业|厂|场|院|所|店|中心|市|局|站|城|处|行|部|队|联合(会|体)|工作室)$)")
	clearSpace1    = regexp.MustCompile("([（(][\\d一二三四五六七八九十][)）][\\s\u3000\u2003\u00a0\\t]*|<[^>].+?>)")
)

/*
 *查找分包中的中标人排序
 *text文本，flag非否精确查找
 *from 来源
 */
func (wo *WinnerOrderEntity) Find(text string, flag bool, from int) []map[string]interface{} {
	text = winnerReg5.ReplaceAllString(text, "\n$3：$1\n")
	/*
		"_id" : ObjectId("5c2c6f60a5cb26b9b7b62cd8")

		1 .第一中选候选人：
		（1）	单位名称：成都维诺信科技有限公司
		（2）	参选报价：522,00.00元
		（3）	质量：符合比选文件规定的质量标准

	*/
	text = clearSpace1.ReplaceAllString(text, "") //清理（1）	单位名称：成都维诺信科技有限公司-->单位名称：成都维诺信科技有限公司
	if strings.TrimSpace(text) == "" {
		return []map[string]interface{}{}
	}
	blocks := winnerReg4.Split(text, -1)
	if len(blocks) == 0 {
		blocks = append(blocks, text)
	}
	winners := wo.findByReg(text, blocks, winnerReg1, from)
	if len(winners) == 0 {
		winners = wo.findByReg(text, blocks, winnerReg2, from)
	}
	if len(winners) == 0 {
		if flag {
			winners = wo.findByReg(text, blocks, winnerReg3, from)
		} else {
			indexs_4 := winnerReg4.Split(text, -1)
			if len(indexs_4) > 1 {
				for _, v_4 := range indexs_4 {
					indexs_3 := winnerReg3.FindAllStringIndex(v_4, -1)
					if len(indexs_3) < 2 {
						continue
					}
					for _, v_3 := range indexs_3 {
						if strings.Count(v_4[:v_3[1]], "\n") <= 3 {
							winners = wo.findByReg(text, blocks, winnerReg3, from)
							break
						}
					}
				}
			}
		}
	}
	return winners
}

//获取中标人排序文本
func (wo *WinnerOrderEntity) getText(text string, blocks []string, reg_2 *regexp.Regexp, from int) string {
	isWinnerReg1 := reg_2 == winnerReg1
	//确定中标候选人排序在哪个块里面
	rightIndex, prevMax := -1, -1
	var winnerFlag *WinnerFlag
	for b_k, b_v := range blocks {
		indexs := []*WinnerFlag{}
		array := reg_2.FindAllStringSubmatchIndex(b_v, -1)
		for _, v := range array {
			var wrfg *WinnerFlag
			if isWinnerReg1 {
				wrfg = &WinnerFlag{
					index:     wo.toNumber(b_v[v[4]:v[5]], 0),
					textStart: v[4],
					textEnd:   v[5],
				}
			} else {
				wrfg = &WinnerFlag{
					index:     wo.toNumber(b_v[v[2]:v[3]], 0),
					textStart: v[2],
					textEnd:   v[3],
				}
			}
			indexs = append(indexs, wrfg)
		}
		wf := wo.getMax(indexs, from)
		if wf != nil && wf.max >= prevMax {
			prevMax = wf.max
			rightIndex = b_k
			winnerFlag = wf
		}
	}
	//在这个块里面，截取
	if rightIndex == -1 {
		return ""
	}
	text = blocks[rightIndex]
	warpCount := wo.interceptText(winnerFlag.indexs, text)
	if warpCount == 0 {
		warpCount = 1
	}
	textEnd := text[winnerFlag.textEnd:]
	text = text[winnerFlag.textStart:winnerFlag.textEnd]
	warpIndex := regSpliteSegment.FindAllStringIndex(textEnd, -1)
	if len(warpIndex) >= warpCount {
		textEnd = textEnd[:warpIndex[warpCount-1][1]]
	}
	text = text + textEnd
	if isWinnerReg1 {
		text = reg_2.ReplaceAllString(text, "$1\n$2$15")
	} else {
		text = reg_2.ReplaceAllString(text, "\n$1")
	}
	text = regReplWrapSpace.ReplaceAllString(text, "")
	lines := SspacekvEntity.getLines(text)
	text = ""
	for k, v := range lines {
		v = strings.TrimSpace(v)
		v = colonSpaceReg.ReplaceAllString(v, "：")
		if reg_2.MatchString(v) && !regDivision.MatchString(v) {
			if isWinnerReg1 {
				v = reg_2.ReplaceAllString(v, "$1$2：$15")
			} else {
				v = reg_2.ReplaceAllString(v, "$1：")
			}
		}
		//逗号之类符号的分割，查找紧跟在中标候选人之后的中标金额
		//如果后面没有什么标识，只有金额的情况下，把中标金额加到金额前面
		if reg_2.MatchString(v) {
			//两个kv连到一起
			if len(regDivision.FindAllString(v, -1)) > 1 && !findamountReg.MatchString(v) {
				v = companyWarpReg.ReplaceAllString(v, "$1\n$2")
			}
			vs := findamountReg.Split(v, -1)
			if len(vs) > 1 {
				vs_1 := strings.TrimSpace(vs[1])
				if amountReg.MatchString(vs_1) {
					v = strings.Replace(v, vs[1], "中标金额："+vs_1, 1)
				}
			}
		}
		v = toWarpReg.ReplaceAllString(v, "\n")
		text += v
		if (!reg_2.MatchString(v) || !colonEndReg.MatchString(v)) && k < len(lines)-1 {
			text += "\n"
		}
	}
	return text
}

//抽取对应的排序结果
func (wo *WinnerOrderEntity) findByReg(content string, blocks []string, reg_2 *regexp.Regexp, from int) []map[string]interface{} {
	text := wo.getText(content, blocks, reg_2, from)
	winners := []map[string]interface{}{}
	object := map[string]interface{}{}
	count := 0
	kvs := colonkvEntity.getColonSpaceKV(text)
	for _, kv := range kvs {
		k, v := kv.Key, kv.Value
		if regDivision.MatchString(v) {
			v_k := regDivision.Split(v, -1)[0]
			if reg_2.MatchString(v_k) {
				k = v_k
			}
		}
		if reg_2.MatchString(k) { //中标人
			if len(object) > 0 {
				winners = append(winners, object)
				object = map[string]interface{}{}
			}
			//新加 从正文抽取时对v校验
			if from == 1 || from == 3 {
				v = findCandidate.FindString(v)
				if v == "" {
					continue
				}
			}
			val := wo.clear("中标单位", v)
			if val != nil {
				count++
				object["entname"] = val
				object["sort"] = wo.toNumber(k, count)
				object["sortstr"] = thisNumberReg.FindString(k)
				object["type"] = 1
			}
		} else { //中标金额
			kvTags := GetKvTags([]*util.Kv{&util.Kv{Key: k, Value: v}}, "", []string{"中标金额"})
			//找到了中标金额
			if len(kvTags["中标金额"]) > 0 && object["entname"] != nil {
				val := wo.clear("中标金额", kvTags["中标金额"][0].Value)
				if val != nil {
					object["price"] = val
				}
				winners = append(winners, object)
				object = map[string]interface{}{}
			}
		}
	}
	if len(object) > 0 {
		winners = append(winners, object)
	}
	indexs := []*WinnerFlag{}
	for _, winner := range winners {
		indexs = append(indexs, &WinnerFlag{
			index: winner["sort"].(int),
		})
	}
	winnerFlag := wo.getMax(indexs, from)
	if winnerFlag != nil {
		winners = winners[winnerFlag.start : winnerFlag.end+1]
	} else {
		winners = []map[string]interface{}{}
	}
	return winners
}

//清理结果
func (wo *WinnerOrderEntity) clear(typ, v string) interface{} {
	if typ == "中标单位" && regDivision.MatchString(v) {
		v = findCompanyReg.FindString(v)
	}
	v = filterValue.ReplaceAllString(v, "")
	//过滤
	return v //clear.ClearResult(typ, v)
}

//
func (wo *WinnerOrderEntity) toNumber(value string, defaultNum int) int {
	value = numberReg.FindString(value)
	if value == "" {
		return defaultNum
	}
	v := util.ChineseNumberToInt(value)
	if v < 1 {
		v, _ = strconv.Atoi(value)
	}
	if v > 0 {
		return v
	}
	return defaultNum
}

//
func (wo *WinnerOrderEntity) getMax(indexs []*WinnerFlag, from int) *WinnerFlag {
	allMap := map[int]*WinnerFlag{}
	max, start, textStart := -1, -1, -1
	isContinue := false
	flag := false
	is := []int{}
	for k, winnerFlag := range indexs {
		v := winnerFlag.index
		//从1开始，1前面的过滤掉
		if v == 1 {
			flag = true
		}
		if !flag {
			continue
		}
		if v == 1 {
			start = k
			textStart = winnerFlag.textStart
			isContinue = false
		}
		if isContinue {
			continue
		}
		nextIndex := 0
		if k < len(indexs)-1 {
			nextIndex = indexs[k+1].index
		}
		//从1-n是一组，遇到小于n的从新添加分组，分组不是1开头的过滤掉
		is = append(is, winnerFlag.textStart, winnerFlag.textEnd)
		if nextIndex-v != 1 {
			isContinue = true
			if max < k-start {
				max = k - start
				allMap[k-start] = &WinnerFlag{
					textStart: textStart,
					textEnd:   winnerFlag.textEnd,
					start:     start,
					end:       k,
					max:       max,
					indexs:    is,
				}
			}
		}
	}
	if max != -1 {
		if from != 3 && len(allMap[max].indexs) <= 2 {
			return nil
		}
		return allMap[max]
	}
	return nil
}

//如果有两个，看第一个有几个换行，用第一个里面的最后一个换行作为第二个的结束位置
//如果有两个以上，取前两个中换行最多的最后一个换行，作为其他的结束位置
func (wo *WinnerOrderEntity) interceptText(indexs []int, con string) int {
	if len(indexs) == 1 {
		return 0
	}
	count := 0
	for ik, iv := range indexs {
		text := ""
		if ik < len(indexs)-1 {
			text = con[iv:indexs[ik+1]]
		} else {
			text = con[iv:]
		}
		//如果两个
		if len(indexs) == 2 {
			//取第一个有几个换行符
			if ik == 0 {
				count = len(regSpliteSegment.FindAllStringIndex(text, -1))
			}
		} else {
			//多个，取前两个中换行符最多的
			if ik <= 1 {
				thisCount := len(regSpliteSegment.FindAllStringIndex(text, -1))
				if thisCount > count {
					count = thisCount
				}
			}
		}
	}
	return count
}

//排序
func (wo *WinnerOrderEntity) Order(winnerOrder []map[string]interface{}) {
	if winnerOrder == nil || len(winnerOrder) <= 1 {
		return
	}
	for x, _ := range winnerOrder {
		for y := 0; y < len(winnerOrder)-x-1; y++ {
			dt1, xok := winnerOrder[y]["sort"].(int)
			dt2, yok := winnerOrder[y+1]["sort"].(int)
			if xok && yok && dt1 > dt2 {
				temp := winnerOrder[y]
				winnerOrder[y] = winnerOrder[y+1]
				winnerOrder[y+1] = temp
			}
		}
	}
}

//合并
func (wo *WinnerOrderEntity) Merge(winnerOrder, wors []map[string]interface{}) {
	if wors == nil || len(wors) == 0 {
		return
	}
	for _, v := range wors {
		for _, tv := range winnerOrder {
			sort, _ := v["sort"].(int)
			t_sort, _ := tv["sort"].(int)
			if sort == 0 || sort != t_sort {
				continue
			}
			if qutil.ObjToString(tv["entname"]) == "" && qutil.ObjToString(v["entname"]) != "" {
				tv["entname"] = v["entname"]
			}
			t_price, _ := tv["price"].(float64)
			price, _ := v["price"].(float64)
			if t_price == 0 && price != 0 {
				tv["price"] = v["price"]
			}
		}
	}
}
