package util

import (
	"fmt"
	"jyBXBase/rpc/bxbase"
	IC "jyBXBase/rpc/init"
	"log"
	"strconv"
	"strings"
	"time"

	"app.yhyue.com/moapp/jybase/common"
	"app.yhyue.com/moapp/jybase/encrypt"
	elastic "app.yhyue.com/moapp/jybase/es"
	"app.yhyue.com/moapp/jybase/mongodb"
	"app.yhyue.com/moapp/jybase/mysql"
	"app.yhyue.com/moapp/jybase/redis"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

const (
	query                     = `{"query":{"terms":{"_id":["%s"]}},"_source":["_id","subtype","s_winner","buyertel","winnertel","buyerclass"],"from":0,"size":%d}`
	mongodb_fields            = `{"_id":1,"area":1,"publishtime":1,"s_subscopeclass":1,"subtype":1,"title":1,"toptype":1,"type":1, "buyerclass":1,"budget":1,"bidamount":1,"winnertel":1,"s_winner":1,"buyertel":1,"attach_text":1}`
	querys                    = `{"query":{"terms":{"_id":["%s"]}},"_source":["_id","title","detail","area","city","publishtime","projectname","buyer","buyerclass","s_winner","bidamount","subtype","toptype","projectcode","buyertel","budget","bidopentime","agency","projectscope","winnerperson","winnertel"],"from":0,"size":%d}}`
	SearchGroupBidding        = 1 // 搜索分组：1：招标采购公告；2：超前项目
	SearchGroupLeadingProject = 2 // 搜索分组：1：招标采购公告；2：超前项目
	TopTypesBidding           = "招标预告,招标公告,招标结果,招标信用信息"
	TopTypesLeadingProject    = "拟建,采购意向"
)

//是否是付费用户 -bool: true:是 fasle:不是
func Power(userid string) (bool, map[string]interface{}) {
	isVip, isMember, isEnt := false, false, false
	vipstatus := 0
	phone := ""
	var registedate int64
	data := IC.Compatible.Select(userid, `"i_member_status":1,"i_vip_status":1,"s_m_phone":1,"s_phone":1,"o_vipjy":1,"l_registedate":1`)
	if data != nil && len(*data) > 0 {
		i_vip_status := common.IntAll((*data)["i_vip_status"])
		if i_vip_status > 1 {
			vipstatus = 1
			isVip = true
		}
		ovipjy, _ := (*data)["o_vipjy"].(map[string]interface{})
		if ovipjy["o_buyset"] != nil {
			o_buyset := ovipjy["o_buyset"].(map[string]interface{})
			if o_buyset["upgrade"] != nil && isVip {
				vipstatus = 2
			}
		}
		if i_member_status := common.IntAllDef((*data)["i_member_status"], 0); i_member_status > 0 {
			isMember = true
		}
		if s_phone, _ := (*data)["s_phone"].(string); s_phone != "" {
			phone = s_phone
		} else if s_m_phone, _ := (*data)["s_m_phone"].(string); s_m_phone != "" {
			phone = s_m_phone
		}
		if phone != "" {
			//已购买企业未过期
			if entInfo := *IC.MainMysql.SelectBySql(`SELECT status FROM entniche_info WHERE id  IN (SELECT ent_id FROM entniche_user where phone = ? and power =1)`, phone); len(entInfo) > 0 {
				for _, v := range entInfo {
					if common.IntAll(v["status"]) == 1 {
						isEnt = true
						break
					}
				}
			}
		}
		registedate, _ = (*data)["l_registedate"].(int64)
	}
	return isVip || isEnt || isMember, map[string]interface{}{
		"vip":         vipstatus,
		"member":      isMember,
		"entniche":    isEnt,
		"registedate": registedate,
	}
}

//招标信息是否被收藏
func IsCollByBids(bids, userid string) []string {
	res := []string{}
	collBidMap := map[string]bool{}
	isCollkey := fmt.Sprintf("isColl_%s", userid)
	collStatus := redis.GetInt("other", isCollkey)
	if collStatus == 0 {
		if count := int(IC.MainMysql.CountBySql(fmt.Sprintf(`select count(1) 
		from %s where userid = ?`, "bdcollection"), userid)); count > 100 {
			collStatus = 2
		} else if count == 0 {
			collStatus = 0
		} else {
			collStatus = 1
		}
		redis.Put("other", isCollkey, collStatus, 259200)
	}
	if collStatus == 1 { //100条内 取redis
		list := GetCollRedis(userid, collStatus)
		for _, v := range list {
			collBidMap[v] = true
		}
	} else if collStatus == 2 { //大于100条 取mysql
		if labArr := *IC.MainMysql.SelectBySql(fmt.Sprintf("select bid from %s where  userid = ?", "bdcollection"), userid); len(labArr) > 0 {
			for _, v := range labArr {
				bid_id := common.ObjToString(v["bid"])
				collBidMap[bid_id] = true
			}
		}
	} else { //0条
		return res
	}

	if bids == "" {
		for k, _ := range collBidMap {
			res = append(res, k)
		}
	} else {
		for _, v := range strings.Split(bids, ",") {
			//招标信息解密
			bid := DecodeId(v)
			if collBidMap[bid] {
				// url.QueryEscape(v)
				res = append(res, v)
			}
		}
	}
	return res
}

/*
    isColl int:	收藏条数的状态 (是否超过100条 超过:2 没超过:1)
return
	[]string:收藏的id
*/
func GetCollRedis(userid string, isColl int) []string {
	redisCollKey := fmt.Sprintf("coll_%s", userid) //列表
	redisArr := []string{}
	if isColl == 1 {
		redisArr, _ = redis.Get("other", redisCollKey).([]string)
		if len(redisArr) == 0 {
			data := IC.MainMysql.SelectBySql(fmt.Sprintf(`select bid from %s where userid ='%s'`, "bdcollection", userid))
			if data != nil && len(*data) > 0 {
				for _, v := range *data {
					redisArr = append(redisArr, common.ObjToString(v["bid"]))
				}
				redis.Put("other", redisCollKey, redisArr, 259200)
			}
		}
	}
	return redisArr
}

//招标信息 bid&userid 唯一
type BidInfo struct {
	Bid        string `json:"bid"`        //招标信息id 加密后
	Buyerclass string `json:"buyerclass"` //采购单位类型
	Buyerinfo  bool   `json:"buyerinfo"`  //是否有采购单位联系方式
	Winnerinfo bool   `json:"winnerinfo"` //是否有中标企业联系方式
	Userid     string `json:"userid"`     //用户id
	Createdate string `json:"createdate"` //收藏时间
	Labelid    string `json:"labelid"`    //标签ids
}

func FormatColl(bidinfo []string) []BidInfo {
	es_ids := []string{}
	infos := map[string]interface{}{}
	for _, v := range bidinfo {
		es_ids = append(es_ids, DecodeId(v))
	}
	if len(es_ids) > 0 {
		list := elastic.Get("bidding", "bidding", fmt.Sprintf(query, strings.Join(es_ids, `","`), len(es_ids)))
		if list != nil {
			for _, v := range *list {
				_id := common.ObjToString(v["_id"])
				//中标电话 需要查企业库 和三级页保持一致
				winnertel := common.ObjToString(v["winnertel"])
				if winnertel == "" && isbid(v["subtype"]) {
					v["winnertel"] = getwinnertel(v["s_winner"])
				}
				infos[_id] = v
			}
		}
	}
	var bids []BidInfo
	if len(infos) > 0 {
		for _, v := range bidinfo {
			var bid BidInfo
			id := DecodeId(v)
			bid.Bid = v
			if infos[id] != nil {
				infoMap, _ := (infos[id]).(map[string]interface{})
				if common.ObjToString(infoMap["winnertel"]) != "" {
					bid.Winnerinfo = true
				}
				if common.ObjToString(infoMap["buyertel"]) != "" {
					bid.Buyerinfo = true
				}
				if common.ObjToString(infoMap["buyerclass"]) != "" {
					bid.Buyerclass = common.ObjToString(infoMap["buyerclass"])
				}
			}
			bids = append(bids, bid)
		}
	}
	return bids
}

func isbid(typ interface{}) bool {
	if typ != nil {
		subtype := common.ObjToString(typ)
		if subtype == "中标" || subtype == "合同" || subtype == "成交" {
			return true
		}
	}
	return false
}

func getwinnertel(company interface{}) string {
	if company != nil {
		data, _ := IC.MgoEnt.FindOneByField("winner_enterprise", map[string]interface{}{
			"company_name": common.ObjToString(company),
		}, map[string]interface{}{"company_phone": 1})
		if (*data)["company_phone"] != nil {
			return common.ObjToString((*data)["company_phone"])
		}
	}
	return ""
}

//修改redis中的收藏条数;
/*	typ:"d"删除  typ:"a"添加
	list:需要添加或删除的bid_id
*/
func UpdateCollListRedis(typ, userid string, list []string) bool {
	bl := false
	if len(list) == 0 {
		return true
	}
	Blist := []string{}
	m := map[string]bool{}
	redisCollKey := fmt.Sprintf("coll_%s", userid)
	collTime := 3600 * 2
	if 7200 > 0 {
		collTime = 7200
	}
	redisIsCollKey := fmt.Sprintf("isColl_%s", userid) //是否超过100条 超过:2 没超过:1
	isCollTime := 3600 * 24 * 3
	if 259200 > 0 {
		isCollTime = 259200
	}
	collStatus := redis.GetInt("other", redisIsCollKey)
	redisArr := GetCollRedis(userid, collStatus)
	if len(redisArr) > 0 {
		for _, v := range redisArr {
			m[v] = true
		}
	}
	if typ == "a" {
		for _, v := range list {
			if m[v] {
				continue //去重
			}
			Blist = append(Blist, v)
		}
	} else if typ == "d" {
		for _, v := range list {
			delete(m, v)
		}
		if len(m) > 0 {
			for k, _ := range m {
				Blist = append(Blist, k)
			}
		}
	}
	arr := append(redisArr, Blist...)
	status := 1
	if len(arr) > 100 {
		status = 2
		arr = []string{}
	} else if len(arr) == 0 {
		status = 0
	}
	bl = redis.Put("other", redisCollKey, arr, collTime) &&
		redis.Put("other", redisIsCollKey, status, isCollTime)
	return bl

}

var PushMapping = &pushMapping{}

type pushMapping struct {
	Area          map[string]int
	City          map[string]int
	Toptype       map[string]int
	Subtype       map[string]int
	Buyerclass    map[string]int
	Subscopeclass map[string]int
}

func (p *pushMapping) Init(MainMysql *mysql.Mysql) {
	infotype := MainMysql.SelectBySql("select id,type,name from infotype")
	p.Toptype = map[string]int{}
	p.Subtype = map[string]int{}
	p.Buyerclass = map[string]int{}
	p.Subscopeclass = map[string]int{}
	for _, v := range *infotype {
		id := common.IntAll(v["id"])
		tp := common.IntAll(v["type"])
		name := common.ObjToString(v["name"])
		if tp == 1 {
			p.Toptype[name] = id
		} else if tp == 2 {
			p.Subtype[name] = id
		} else if tp == 3 {
			p.Buyerclass[name] = id
		} else if tp == 4 {
			p.Subscopeclass[name] = id
		}
	}
	if len(p.Toptype) == 0 {
		log.Fatalln("PushMapping Toptype Init Error")
	}
	if len(p.Subtype) == 0 {
		log.Fatalln("PushMapping Subtype Init Error")
	}
	if len(p.Buyerclass) == 0 {
		log.Fatalln("PushMapping Buyerclass Init Error")
	}
	if len(p.Subscopeclass) == 0 {
		log.Fatalln("PushMapping Subscopeclass Init Error")
	}
	//
	p.Area = map[string]int{}
	p.City = map[string]int{}
	province := MainMysql.SelectBySql("select id,level,name from province")
	for _, v := range *province {
		id := common.IntAll(v["id"])
		level := common.IntAll(v["level"])
		name := common.ObjToString(v["name"])
		if level == 1 {
			p.Area[name] = id
		} else if level == 2 {
			p.City[name] = id
		}
	}
	if len(p.Area) == 0 {
		log.Fatalln("PushMapping Area Init Error")
	}
	if len(p.City) == 0 {
		log.Fatalln("PushMapping City Init Error")
	}
}

type InfoList struct {
	Id              string      `json:"_id"`
	Title           string      `json:"title"`
	Area            string      `json:"area"`
	Buyerclass      string      `json:"buyerclass"`
	Type            string      `json:"type"`
	S_subscopeclass string      `json:"s_subscopeclass"`
	Publishtime     int64       `json:"publishtime"`
	Budget          interface{} `json:"budget"`
	Bidamount       interface{} `json:"bidamount"`
	Buyer           string      `json:"buyer"`
	S_winner        string      `json:"s_winner"`
	Bidopentime     int64       `json:"bidopentime"`
	FileExists      bool        `json:"fileExists"`
}

//根据id取内容
func GetInfoById(Mgo_bidding mongodb.MongodbSim, bidding, bidding_back string, idlist []map[string]interface{}) []*InfoList {
	array := make([]*InfoList, len(idlist))
	if len(idlist) == 0 {
		return array
	}
	m := map[string]bool{}
	ids := []string{}
	for _, v := range idlist {
		if m[common.ObjToString(v["bid"])] {
			continue
		}
		m[common.ObjToString(v["bid"])] = true
		ids = append(ids, common.ObjToString(v["bid"]))
	}
	infos := map[string]map[string]interface{}{}
	//redis
	es_ids := []string{}
	for _, v := range ids {
		info_i := redis.Get("pushcache_1", fmt.Sprintf("info_%s", v))
		if info_i != nil {
			info_m, _ := info_i.(map[string]interface{})
			info_m["_id"] = v
			infos[v] = info_m
		} else {
			es_ids = append(es_ids, v)
		}
	}
	//	log.Println(es_ids)
	//elasticsearch
	if len(es_ids) > 0 {
		list := elastic.Get("bidding", "bidding", fmt.Sprintf(querys, strings.Join(es_ids, `","`), len(es_ids)))
		if list != nil {
			for _, v := range *list {
				_id := common.ObjToString(v["_id"])
				v["attachment_count"] = common.If(v["filetext"] != nil, 1, 0).(int)
				infos[_id] = v
			}
		}
	}
	//mongodb bidding
	mgo_ids := []primitive.ObjectID{}
	for _, v := range es_ids {
		if infos[v] == nil {
			_id, _ := primitive.ObjectIDFromHex(v)
			mgo_ids = append(mgo_ids, _id)
		}
	}
	if len(mgo_ids) > 0 {
		list, ok := Mgo_bidding.Find(bidding, map[string]interface{}{"_id": map[string]interface{}{"$in": mgo_ids}}, nil, mongodb_fields, false, -1, -1)
		if ok && *list != nil {
			for _, v := range *list {
				_id := mongodb.BsonIdToSId(v["_id"])
				v["_id"] = _id
				v["attachment_count"] = common.If(v["attach_text"] != nil, 1, 0).(int)
				infos[_id] = v
			}
		}
	}
	//mongodb bidding_back
	mgo_back_ids := []primitive.ObjectID{}
	for _, v := range mgo_ids {
		if infos[mongodb.BsonIdToSId(v)] == nil {
			mgo_back_ids = append(mgo_back_ids, v)
		}
	}
	if len(mgo_back_ids) > 0 {
		list, ok := Mgo_bidding.Find(bidding_back, map[string]interface{}{"_id": map[string]interface{}{"$in": mgo_back_ids}}, nil, mongodb_fields, false, -1, -1)
		if ok && *list != nil {
			for _, v := range *list {
				_id := mongodb.BsonIdToSId(v["_id"])
				v["_id"] = _id
				v["attachment_count"] = common.If(v["attach_text"] != nil, 1, 0).(int)
				infos[_id] = v
			}
		}
	}
	//
	for k, v := range idlist {
		info := infos[common.ObjToString(v["bid"])]
		if info == nil {
			info = map[string]interface{}{}
		}
		array[k] = InfoFormat(common.ObjToString(v["bid"]), &info)
	}
	return array
}

//列表单条信息格式化
func InfoFormat(p string, info *map[string]interface{}) *InfoList {
	area := common.ObjToString((*info)["area"])
	if area == "A" {
		area = "全国"
	}
	industry := common.ObjToString((*info)["s_subscopeclass"])
	scs := strings.Split(industry, ",")
	if len(scs) > 0 {
		industry = scs[0]
		if industry != "" {
			iss := strings.Split(industry, "_")
			if len(iss) > 0 {
				industry = iss[0]
			}
		}
	}
	infotype := common.ObjToString((*info)["subtype"])
	if infotype == "" {
		infotype = common.ObjToString((*info)["toptype"])
	}
	if infotype == "" {
		infotype = common.ObjToString((*info)["type"])
		if infotype == "tender" {
			infotype = "招标"
		} else if infotype == "bid" {
			infotype = "中标"
		}
	}
	_id := p
	if _id == "" {
		_id = common.ObjToString((*info)["_id"])
	}
	return &InfoList{
		Id:              encrypt.EncodeArticleId2ByCheck(_id),
		Title:           common.ObjToString((*info)["title"]),
		Area:            area,
		Buyerclass:      common.ObjToString((*info)["buyerclass"]),
		Type:            infotype,
		S_subscopeclass: industry,
		Publishtime:     common.Int64All((*info)["publishtime"]),
		Budget:          (*info)["budget"],
		Bidamount:       (*info)["bidamount"],
		Buyer:           common.ObjToString((*info)["buyer"]),
		S_winner:        common.ObjToString((*info)["s_winner"]),
		Bidopentime:     common.Int64All((*info)["bidopentime"]),
		FileExists:      common.IntAll((*info)["attachment_count"]) > 0,
	}
}

//搜藏列表
func CollListSql(c *bxbase.ListReq, isPay bool, userid string) string {
	sql := fmt.Sprintf(`select bid from %s where userid ='%s'`, "bdcollection", userid)
	limit := 10
	//个人标签
	if c.Label != "" {
		i := 0
		sql += ` and `
		if labelArr := strings.Split(c.Label, ","); len(labelArr) > 0 {
			sql += `(`
			for _, v := range labelArr {
				i++
				labid := encrypt.SE.DecodeString(v)
				if i == len(labelArr) {
					sql += fmt.Sprintf(`FIND_IN_SET(%s,labelid)`, labid)
				} else {
					sql += fmt.Sprintf(`FIND_IN_SET(%s,labelid) or `, labid)
				}
			}
			sql += `)`
		}
	}
	now := time.Now()
	start, end := "", ""
	//收藏时间
	if c.SelectTime == "lately-7" { //最近7天
		start = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-7, 0, 0, 0, 0, time.Local).Format(Date_Full_Layout))
	} else if c.SelectTime == "lately-30" { //最近30天
		start = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-30, 0, 0, 0, 0, time.Local).Format(Date_Full_Layout))
	} else if c.SelectTime == "thisyear" { //去年
		start = fmt.Sprint(time.Date(now.Year()-1, 1, 1, 0, 0, 0, 0, time.Local).Format(Date_Full_Layout))
		end = fmt.Sprint(time.Date(now.Year()-1, 12, 31, 23, 59, 59, 0, time.Local).Format(Date_Full_Layout))
	} else if len(strings.Split(c.SelectTime, "_")) == 2 {
		if c.SelectTime != "0_0" {
			starttime := strings.Split(c.SelectTime, "_")[0]
			startstamp, _ := strconv.Atoi(starttime)
			start = time.Unix(int64(startstamp), 0).Format(Date_Full_Layout)
			endtime := strings.Split(c.SelectTime, "_")[1]
			et, _ := strconv.ParseInt(endtime, 0, 64)
			etTime := time.Unix(et, 0)
			end = fmt.Sprint(time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local).Format(Date_Full_Layout))
		}
	}
	if start != "" && end != "" {
		sql += ` and createdate >= '` + start + `' and createdate < '` + end + `'`
	} else if start != "" && end == "" {
		sql += ` and createdate >= '` + start + `'`
	} else if start == "" && end != "" {
		sql += ` and createdate < '` + end + `'`
	}
	if isPay {

		//采购单位 用,分隔开
		if c.Buyerclass != "" {
			i := 0
			sql += ` and buyerclass in (`
			if buyClassArr := strings.Split(c.Buyerclass, ","); len(buyClassArr) > 0 {
				for _, v := range buyClassArr {
					i++
					buyerclassid := fmt.Sprint(PushMapping.Buyerclass[v])
					if i == len(buyClassArr) {
						sql += buyerclassid + `)`
					} else {
						sql += buyerclassid + ","
					}
				}
			}
		}
		//是否存在采购单位电话
		if c.BuyerPhone == 1 {
			sql += ` and buyerinfo = 1`
		} else if c.BuyerPhone == -1 {
			sql += ` and buyerinfo = 0`
		}
		//是否存在中标单位电话
		if c.WinnerPhone == 1 {
			sql += ` and winnerinfo = 1`
		} else if c.WinnerPhone == -1 {
			sql += ` and winnerinfo = 0`
		}
		limit = 5000
	}
	sql += fmt.Sprintf(` order by createdate desc limit %v`, limit)
	return sql
}
