package service

import (
	MC "app.yhyue.com/moapp/jybase/common"
	"app.yhyue.com/moapp/jybase/encrypt"
	elastic "app.yhyue.com/moapp/jybase/es"
	"bp.jydev.jianyu360.cn/BaseService/powerCheckCenter/rpc/pb"
	userPb "bp.jydev.jianyu360.cn/BaseService/userCenter/rpc/pb"
	"context"
	"fmt"
	IC "jyBXCore/rpc/init"
	"jyBXCore/rpc/model/es"
	"jyBXCore/rpc/type/bxcore"
	"jyBXCore/rpc/util"
	"log"
	"strings"
	"time"
)

const (
	entQuery      = `{"query":{"bool":{"must":[%s],"must_not":[%s]}},"_source":["_id","company_name","company_status","legal_person","capital","company_address","company_shortname","company_phone","establish_date"],"sort":[{"capital":{"order":"desc"}}]}`
	entQueryCount = `{"query":{"bool":{"must":[%s],"must_not":[%s]}}}`
	index, itype  = "qyxy", "qyxy"
	query         = `{%s "query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer_name": ""}}]}}}`
	BuyerIndex    = "buyer" // 采购单位index
	BuyerType     = "buyer"
)

// GetBidSearchData  默认查询缓存数据 只查标题
// 登录用户默认搜索500条数据，付费用户字段和免费用户字段不同，未登录用户查询5000条。
// 标信息搜索 isCache:是否是获取缓存信息
func GetBidSearchData(in *bxcore.SearchReq, isCache bool) (count int64, list []*bxcore.SearchList) {
	var start = int((in.PageNum - 1) * in.PageSize)
	if start >= 0 {
		t := time.Now()
		fields := MC.If(in.IsPay, es.BidSearchFieldOfVip, es.BidSearchFieldBase).(string)
		//in.BidField（医疗）领域化字段
		if in.BidField != "" {
			fields = es.BidSearchDomainField
		}
		//IC.C.FileSignBool列表是否显示附件开关
		if IC.C.FileSignBool {
			fields = fields + es.BidSearchFieldFile
		}
		biddingSearch := es.SearchByES{
			Index:      MC.If(in.UserId == "", es.INDEXNoLogin, es.INDEX).(string),
			IType:      MC.If(in.UserId == "", es.TYPENoLogin, es.TYPE).(string),
			Query:      es.GetSearchQuery(in, es.GetBidSearchQuery(in)),
			FindFields: MC.If(isCache, "title", "detail").(string),
			Order:      es.BidSearchSort,
			Fields:     fields,
			Start:      MC.If(isCache, 0, start).(int),
			Limit:      MC.If(isCache, MC.If(in.IsPay, IC.C.DefaultBidInfo.PayCount, IC.C.DefaultBidInfo.Count).(int), int(in.PageSize)).(int),
			Count:      MC.If(strings.Contains(in.SelectType, "detail"), 115, 0).(int),       //高亮正文数量
			HighLight:  MC.If(strings.Contains(in.SelectType, "detail"), true, false).(bool), //是否高亮正文
		}
		var repl *[]map[string]interface{}
		if in.UserId != "" {
			count, repl = biddingSearch.GetAllByNgramWithCount(true)
		} else {
			if IC.C.NoLoginSearch.Switch {
				if flag := IC.ReqLimitInit.Limit(context.Background()); flag == 1 {
					defer IC.ReqLimitInit.Release()
				} else {
					if flag == -2 {
						log.Println("等待队列已满")
					} else if flag == -1 {
						log.Println("等待超时")
					}
					return 0, nil
				}
			}
			count, repl = biddingSearch.GetAllByNgramWithCount(false)
		}
		if repl != nil && *repl != nil && len(*repl) > 0 {
			//格式化查询结果
			list = util.SearchListFormat(in.UserId, in.Industry, repl, strings.Contains(in.SelectType, "detail"))
		} else {
			log.Println("查询数据异常")
		}
		log.Println(in.KeyWords, "关键词 -1- 查询耗时：", time.Since(t).Seconds())
	}
	return
}
func EntSearch(searchCode string) ([]*bxcore.Search, int64) {
	data := make([]*bxcore.Search, 0, 0)
	count := int64(0)
	musts := make([]string, 0, 0)
	musts = append(musts, `{"range":{"company_type_int":{"to":"22"}}}`)
	thisQuery := []string{}
	//查询指定内容
	thisQuery = append(thisQuery, fmt.Sprintf(`{"match_phrase":{"name":"%s"}}`, searchCode))
	musts = append(musts, fmt.Sprintf(`{"bool":{"should":[%s],"minimum_should_match": 1}}`, strings.Join(thisQuery, ",")))
	sql := fmt.Sprintf(entQuery, strings.Join(musts, ","), "")
	sql = sql[:len(sql)-1] + fmt.Sprintf(`,"from":%d,"size":%d}`, 0, 5)
	log.Println("企业搜索sql:", sql)
	count, list := elastic.GetWithCount(index, itype, "", sql)
	if list != nil {
		for _, value := range *list {
			data = append(data, &bxcore.Search{
				Title: MC.InterfaceToStr(value["company_name"]),
				Url:   encrypt.EncodeArticleId2ByCheck(MC.ObjToString(value["_id"])),
			})
		}
	}
	return data, count
}
func ProcureSearch(searchCode string) ([]*bxcore.Search, int64) {
	data := []*bxcore.Search{}
	count := int64(0)
	//数据查询处理
	entNameQuery := fmt.Sprintf(`{"multi_match": {"query": "%s","type": "phrase", "fields": ["name"]}}`, searchCode)
	qstr := fmt.Sprintf(query, fmt.Sprintf(`"from":%d,"size": %d,`, 0, 5), entNameQuery)
	log.Println("采购单位搜索sql:", qstr)
	count, rs := elastic.GetWithCount(BuyerIndex, BuyerType, "", qstr)
	//rs := elastic.Get(BuyerIndex, BuyerType, qstr) // 采购单位列表
	if rs == nil || len(*rs) == 0 {
		return data, count
	}
	for i := 0; i < len(*rs); i++ {
		data = append(data, &bxcore.Search{
			Title: MC.ObjToString((*rs)[i]["name"]),
		})
	}
	return data, count
}

// 菜单搜索
func MenuSearch(in *bxcore.PolymerizeSearchReq) []*bxcore.MenuList {
	data := []*bxcore.MenuList{}
	workData := IC.Middleground.UserCenter.WorkDesktopMenuInfo(userPb.WorkDesktopMenuInfoReq{
		UserId:       in.UserId,
		AppId:        in.AppId,
		Platform:     "PC",
		NewUserId:    MC.InterfaceToStr(in.NewUserId),
		EntId:        MC.InterfaceToStr(in.EntId),
		EntUserId:    MC.InterfaceToStr(in.EntUserId),
		AccountId:    MC.InterfaceToStr(in.AccountId),
		PositionType: MC.InterfaceToStr(in.PositionType),
		PositionId:   MC.InterfaceToStr(in.PositionId),
		EntAccountId: MC.InterfaceToStr(in.EntAccountId),
	})
	if workData != nil && len(workData.Data.MenuList) > 0 {
		for _, value1 := range workData.Data.MenuList {
			for _, value2 := range value1.Child {
				for _, value3 := range value2.Child {
					if strings.Contains(value3.Name, in.SearchCode) {
						tipInfo := &bxcore.TipInfo{}
						if value3.TipInfo != nil {
							tipInfo = &bxcore.TipInfo{
								Title:        value3.TipInfo.Title,
								Content:      value3.TipInfo.Content,
								ConfirmUrl:   value3.TipInfo.ConfirmUrl,
								ConfirmText:  value3.TipInfo.ConfirmText,
								IsShowCancel: value3.TipInfo.IsShowCancel,
								AppType:      value3.TipInfo.AppType,
								OpenType:     value3.TipInfo.OpenType,
							}
						}
						data = append(data, &bxcore.MenuList{
							Name:     value3.Name,
							Icon:     value3.Icon,
							Url:      value3.Url,
							Usable:   value3.Usable,
							AppType:  value3.AppType,
							OpenType: value3.OpenType,
							TipInfo:  tipInfo,
							Match:    value3.Match,
							Path:     fmt.Sprintf("%s>%s>%s", value1.Name, value2.Name, value3.Name),
						})
					}
				}
			}
		}
	}
	return data
}
func SubscribeSearch(searchCode string, powerCheck *pb.CheckResp) []*bxcore.Search {
	data := []*bxcore.Search{}
	in := &bxcore.SearchReq{
		PageNum:     int64(1),
		PageSize:    int64(10),
		IsPay:       false,
		SelectType:  "title",
		KeyWords:    searchCode,
		PublishTime: fmt.Sprintf("%v_%v", time.Now().AddDate(-1, 0, 0).Unix(), time.Now().Unix()),
	}
	isLimit := int64(0)
	isLimit = util.IsLimited(in.LimitFlag, in.UserId, powerCheck.Vip.Status > 0 || powerCheck.Member.Status > 0, in.IsNew)
	if isLimit == 1 { //没有被限制
		defer util.Limit()
	}
	list := []*bxcore.SearchList{}
	if isLimit == 1 {
		//付费用户搜索优化--默认搜索5年数据，数据量太多，接口反应太慢，前两页数据 时间范围根据配置缩小查询以达到快速查询的目的。
		t1 := time.Now()
		_, list = GetBidSearchData(in, false)
		log.Println("1查询耗时：", time.Since(t1))
	}
	if list != nil && len(list) > 0 {
		for _, value := range list {
			data = append(data, &bxcore.Search{
				Title:    value.Title,
				Url:      value.Id,
				DataTime: value.PublishTime,
			})
		}
	}
	return data
}
