package entity

import (
	MC "app.yhyue.com/moapp/jybase/common"
	"app.yhyue.com/moapp/jybase/redis"
	"app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
	"encoding/json"
	"fmt"
	IC "jyBXCore/rpc/init"
	"jyBXCore/rpc/service"
	"jyBXCore/rpc/type/bxcore"
	"jyBXCore/rpc/util"
	"log"
	"strconv"
	"strings"
	"time"
)

var (
	SearchCacheKey   = "searchDataCache_%d_%s_%s_%s"
	SearchCacheCount = "searchCountCache_%d_%s_%s_%s"
)

type KeyWordsSearch struct{}

func NewKeyWordsSearch() *KeyWordsSearch {
	return &KeyWordsSearch{}
}

// IsEmptySearch  是否是空搜索，如果是空搜索查缓存数据
func (kws *KeyWordsSearch) IsEmptySearch(in *bxcore.SearchReq) bool {
	//有主关键词 或 选择了行业，都不是空搜索
	if strings.TrimSpace(in.KeyWords) != "" || strings.TrimSpace(in.Industry) != "" || strings.TrimSpace(in.AdditionalWords) != "" {
		return false
	}
	//所有的未登录空搜索 缓存都最多查500条数据
	return true
}

// GetBidSearchListByCache   查询缓存数据
// 未登录用户默认搜索和关键词搜索改成500条和免费用户保持一致--需求调整P260来自产品经理杨蘭20220116
func (kws *KeyWordsSearch) GetBidSearchListByCache(in *bxcore.SearchReq) (list []*bxcore.SearchList, count, total int64) {
	//缓存数据 最大量是5000条  100页数据
	l, c := func(in *bxcore.SearchReq) (list []*bxcore.SearchList, count int64) {
		//缓存数据总量 - 当前平台
		redisCountKey := fmt.Sprintf(SearchCacheCount, in.SearchGroup, MC.If(in.IsPay, "v", "f").(string), MC.If(in.BidField != "", in.BidField, "n").(string), in.Platform)
		count = int64(redis.GetInt(util.RedisNameNew, redisCountKey))
		//缓存数据： SearchGroup-全部；招标信息；超前项目信息；kws.PageNum-当前页 免费用户 or 付费用户
		redisDataKey := fmt.Sprintf(SearchCacheKey, in.SearchGroup, MC.If(in.IsPay, "v", "f").(string), MC.If(in.BidField != "", in.BidField, "n").(string), in.Platform)
		sCache, err := redis.GetNewBytes(util.RedisNameNew, redisDataKey)
		log.Println("-------------------------redisDataKey--------------------------------:", redisDataKey)
		if err == nil {
			if sCache != nil && len(*sCache) > 0 {
				err = json.Unmarshal(*sCache, &list)
				if err == nil {
					return
				} else {
					log.Println("缓存序列化异常")
				}
			}
		}
		//无缓存数据 或 缓存数据查询异常
		//查库>存redis缓存
		//查询缓存数据 参数初始化
		kws.DefaultSearchParamsAuto(in)
		//缓存数据
		count, list = service.GetBidSearchData(in, true)
		if len(list) > 0 {
			redis.Put(util.RedisNameNew, redisCountKey, count, MC.If(IC.C.DefaultSearchCacheTime > 0, IC.C.DefaultSearchCacheTime*60*60, 24*60*60).(int))
			b, err := json.Marshal(list)
			if err == nil {
				redis.PutBytes(util.RedisNameNew, redisDataKey, &b, MC.If(IC.C.DefaultSearchCacheTime > 0, IC.C.DefaultSearchCacheTime*60*60, 24*60*60).(int))
			} else {
				log.Println("默认搜索查询结果保存redis缓存异常")
			}
		} else {
			log.Println("默认搜索 暂无数据")
		}
		return
	}(in)
	if len(l) > 0 {
		total = c
		limitCount := int64(util.SearchPageSize * MC.If(in.IsPay, util.SearchMaxPageNum_PAYED, util.SearchMaxPageNum).(int))
		count = c
		if count > limitCount {
			count = limitCount
		}
		list = l[(in.PageNum-1)*in.PageSize : in.PageNum*in.PageSize]
		//是否收藏
		util.MakeCollection(in.UserId, list)
	}
	return
}

// DefaultSearchParamsAuto 缓存查询条件初始化
func (kws *KeyWordsSearch) DefaultSearchParamsAuto(in *bxcore.SearchReq) {
	in.TopType = ""
	in.City = ""
	in.Industry = ""
	in.FileExists = ""
	in.WinnerTel = ""
	in.BuyerTel = ""
	in.BuyerClass = ""
	in.Price = ""
	in.SelectType = "title"
	in.Province = ""
}

// SaveKeyWordsToHistory 保存历史记录
func (kws *KeyWordsSearch) SaveKeyWordsToHistory(in *bxcore.SearchReq) {
	if in.KeyWords != "" {
		//历史记录
		history := redis.GetStr("other", "s_"+in.UserId)
		keys := util.SearchHistory(history, in.KeyWords, in.AdditionalWords)
		if len(keys) > 0 {
			if b := redis.Put("other", "s_"+in.UserId, strings.Join(keys, ","), -1); !b {
				log.Println("保存搜索记录异常，用户id:", in.UserId)
			}
		}
	}
}

// GetSearchKeyWordsQueryStr 关键词和附加词处理 获取关键词查询条件；是否进行分词查询
func (kws *KeyWordsSearch) GetSearchKeyWordsQueryStr(in *bxcore.SearchReq) (searchWords []string) {
	// in.SearchMode 搜索模式：0：精准搜索；1：模糊搜索
	// 精准搜索：不分词，完全匹配；（中间带空格的关键词组自动分词）
	// 模糊搜索：对用户输入的单个关键词进行分词处理，但必须都存在；
	//主关键词词组
	if in.KeyWords != "" {
		if in.SearchMode == 1 {
			if ikWords := util.HttpEs(in.KeyWords, "ik_smart", IC.DB.Es.Addr); ikWords != "" {
				in.KeyWords = jy.KeywordsProcessing(ikWords, IC.C.JYKeyMark)
			}
		}
		searchWords = append(searchWords, in.KeyWords)
	}
	//多组附加词，每组间,号隔开。每组内如果关键词中间有空格，自动分词
	if in.AdditionalWords != "" {
		if in.SearchMode == 1 {
			var (
				addWords []string
			)
			for _, awv := range strings.Split(in.AdditionalWords, ",") {
				if strings.TrimSpace(awv) != "" {
					if ikWords := util.HttpEs(awv, "ik_smart", IC.DB.Es.Addr); ikWords != "" {
						addWords = append(addWords, jy.KeywordsProcessing(ikWords, IC.C.JYKeyMark))
					}
				}
			}
			if len(addWords) > 0 {
				in.AdditionalWords = strings.Join(addWords, ",")
			}
		}
		searchWords = append(searchWords, strings.Split(in.AdditionalWords, ",")...)
	}
	return
}

// SearchParamsHandle 搜索条件 处理
func (kws *KeyWordsSearch) SearchParamsHandle(in *bxcore.SearchReq) []string {
	baseUserId, _ := strconv.ParseInt(in.NewUserId, 10, 64)
	accountId, _ := strconv.ParseInt(in.AccountId, 10, 64)
	positionType, _ := strconv.ParseInt(in.PositionType, 10, 64)
	positionId, _ := strconv.ParseInt(in.PositionId, 10, 64)
	//判断用户身份
	userInfo := IC.Middleground.PowerCheckCenter.Check(in.AppId, in.MgoUserId, baseUserId, accountId, in.EntId, positionType, positionId)
	//是否是付费用户
	in.IsPay = !userInfo.Free.IsFree
	//默认搜索范围
	if in.SelectType == "" {
		in.SelectType = "title,content"
	}
	queryItems := util.GetQueryItems(in.SelectType, IC.C.BidSearchOldUserLimit, userInfo.Free.Registedate, in.IsPay)
	in.SelectType = strings.Join(queryItems, ",")
	// in.SearchGroup 搜索分组 搜索分组：默认0：全部；1：招标采购公告；2：超前项目
	//	详情页判断是否能使用超前项目  老版超级订阅、大会员、商机管理有权限
	if in.SearchGroup < 0 || in.SearchGroup > 2 {
		in.SearchGroup = 1
	}
	//信息类型
	if in.Subtype == "" && in.TopType == "" {
		//（免费用户和新版超级订阅用户 有搜索权限，但是没有查看权限）免费用户与未登录用户支持 拟建,采购意向搜索
		if in.SearchGroup > 0 && len(IC.C.DefaultTopTypes) >= int(in.SearchGroup) {
			in.Subtype = IC.C.DefaultTopTypes[in.SearchGroup-1]
		}
	}
	// in.SearchMode 搜索模式 搜索模式：0：精准搜索；1：模糊搜索
	// 精准搜索：不分词，完全匹配；（中间带空格的关键词组自动分词）
	// 模糊搜索：对用户输入的单个关键词进行分词处理，但必须都存在；
	if in.SearchMode < 0 || in.SearchMode > 1 {
		in.SearchMode = 0
	}
	// in.WordsMode 搜索关键词模式；默认0：包含所有，1：包含任意
	if in.WordsMode < 0 || in.WordsMode > 1 {
		in.WordsMode = 0
	}
	//查询时间publishTime
	if in.PublishTime == "" {
		//付费用户最新5年；免费用户||未登录用户最新1年
		in.PublishTime = fmt.Sprintf("%d-%d", time.Now().AddDate(-1, 0, 0).Unix(), time.Now().Unix())
		if in.IsPay {
			in.PublishTime = fmt.Sprintf("%d-%d", time.Now().AddDate(-5, 0, 0).Unix(), time.Now().Unix())
		}
	}
	//默认每页数据量
	if in.PageSize <= 0 {
		in.PageSize = 50
	}
	//第一页
	if in.PageNum <= 0 {
		in.PageNum = 1
	}
	count := MC.If(in.IsPay, IC.C.DefaultBidInfo.PayCount, IC.C.DefaultBidInfo.Count).(int)
	if in.PageNum > int64(count)/in.PageSize {
		in.PageNum = -1
		in.PageSize = -1
	}
	//行业格式化
	if in.Industry != "" {
		in.Industry = strings.TrimSpace(in.Industry)
	}
	//免费用户：高级筛选 采购单位类型、采购单位联系方式、中标企业联系方式、排除词、城市
	if userInfo.Free.IsFree {
		in.BuyerClass = ""
		in.BuyerTel = ""
		in.WinnerTel = ""
		in.ExclusionWords = ""
		in.City = ""
		in.ExclusionWords = ""
	}
	//判断是否有关键词
	if in.KeyWords != "" {
		//关键词处理
		in.KeyWords = strings.TrimSpace(in.KeyWords)
		in.InterceptKeyWords, in.InterceptOtherWords, in.KeyWords = util.InterceptSearchKW(in.KeyWords, MC.IntAllDef(IC.C.KeywordsLimit, 35), true) // len(in.Industry) == 0
	}
	//附加词 每组附加词不能超过15个字符
	if in.AdditionalWords != "" {
		var additionalWords []string
		for _, ak := range strings.Split(in.AdditionalWords, ",") {
			if len([]rune(ak)) > 15 {
				additionalWords = append(additionalWords, string([]rune(ak)[:15]))
			} else {
				additionalWords = append(additionalWords, ak)
			}
		}
		in.AdditionalWords = strings.Join(additionalWords, ",") //分组不变
	}
	//更新关键词搜索历史记录
	go kws.SaveKeyWordsToHistory(in)
	//排除词  每组排除词不能超过15个字符
	if in.ExclusionWords != "" {
		var exclusionWords []string
		for _, ak := range strings.Split(in.ExclusionWords, ",") {
			if len([]rune(ak)) > 15 {
				exclusionWords = append(exclusionWords, string([]rune(ak)[:15]))
			} else {
				exclusionWords = append(exclusionWords, ak)
			}
		}
		in.ExclusionWords = strings.Join(exclusionWords, IC.C.JYKeyMark) //util.MatchSpace.ReplaceAllString(in.ExclusionWords, IC.C.JYKeyMark)
	}
	return kws.GetSearchKeyWordsQueryStr(in) //格式化关键词
}

// GetBidSearchList 非空搜索 查询
func (kws *KeyWordsSearch) GetBidSearchList(in *bxcore.SearchReq) (count, total int64, list []*bxcore.SearchList) {
	//排除异常in.PageNum参数
	count, list = service.GetBidSearchData(in, false)
	util.MakeCollection(in.UserId, list)
	total = count //返回数据总量提示信息
	limitCount := MC.If(in.IsPay, int64(util.SearchPageSize*util.SearchMaxPageNum_PAYED), int64(util.SearchPageSize*util.SearchMaxPageNum)).(int64)
	if count > limitCount {
		count = limitCount //付费用户count 最多5000条，100页数据，每页50条；免费用户count 最多500条，10页数据，每页50条。
	}
	return
}
