package model

import (
	"app.yhyue.com/moapp/jybase/common"
	"app.yhyue.com/moapp/jybase/date"
	"app.yhyue.com/moapp/jybase/encrypt"
	"app.yhyue.com/moapp/jybase/mongodb"
	"fmt"
	"github.com/gogf/gf/v2/util/gconv"
	IC "jyBXSubscribe/rpc/init"
	"jyBXSubscribe/rpc/type/bxsubscribe"
	"strings"
	"time"
)

// PersonSubscribe 个人订阅结构体
type PersonSubscribe struct {
	AInfotype     []string            `json:"a_infotype"`
	ABuyerclass   []string            `json:"a_buyerclass"`
	IProjectmatch int                 `json:"i_projectmatch"`
	OArea         map[string][]string `json:"o_area"`
	AItems        []struct {
		SItem string `json:"s_item"`
		AKey  []struct {
			Key      []string `json:"key"`
			Notkey   []string `json:"notkey"`
			Matchway float64  `json:"matchway"`
		} `json:"a_key"`
	} `json:"a_items"`
	IEntFastimport int `json:"i_ent_fastimport"`
	IApppush       int `json:"i_apppush"`
	IMailpush      int `json:"i_mailpush"`
	IMatchway      int `json:"i_matchway"`
	IRatemode      int `json:"i_ratemode"`
}

// IsEmpty 判断订阅内容是否为空
func (p *PersonSubscribe) IsEmpty() bool {
	if len(p.AInfotype) > 0 || len(p.ABuyerclass) > 0 || len(p.OArea) > 0 {
		return false
	}
	// 遍历订阅词
	for _, item := range p.AItems {
		for _, key := range item.AKey {
			if len(key.Key) > 0 || len(key.Notkey) > 0 {
				return false
			}
		}
	}
	return true
}

// GetStaffSubscribeList 员工订阅总览列表
// query 检索名字/手机号
// eStatus 是否有企业订阅 -1 无企业订阅 1 有企业订阅
// pStatus 是否有个人订阅 -1 无个人订阅 1 有个人订阅
func GetStaffSubscribeList(entId, entUserId int, query string, eStatus, pStatus, pageNum, pageSize int64) (total int64, list []*bxsubscribe.StaffSubscribe) {
	userEnt := EntInfo(entId, entUserId)
	// 非管理员无权限查询
	if !(userEnt.Role_admin_system || userEnt.Role_admin_department) {
		return
	}
	// 当检索是否有个人订阅时，因为无法关联查询，需要提前加载员工是否有个人订阅
	pSubscribeList := getEntPersonOrderList(entId)
	// 加载当前企业所有企业分发数据
	ruleIds := getEntSubscirbeList(entId, userEnt.Dept.Id, userEnt.Role_admin_system)

	allRule := ""
	if len(ruleIds) > 0 {
		allRule = " AND b.rule_id in ('" + strings.Join(ruleIds, "','") + "')"
	} else {
		allRule = " AND b.rule_id is NULL "
	}

	var sql string = ` FROM (
	SELECT
		a.id,
		a.name,
		a.phone,
		b.rule_id,
		a.createtime,
		GROUP_CONCAT( a.product_type ) AS product_type 
	FROM
		(
		SELECT
			u.id,
			u.NAME,
			u.phone,
			'e' AS product_type,
			u.createtime
		FROM
			entniche_info a
			INNER JOIN entniche_user u ON ( a.id = ? AND a.STATUS = 1 AND u.power = 1 AND a.id = u.ent_id ) 
			%s
			UNION
		SELECT
			u.id,
			u.NAME,
			u.phone,
			IF ( instr( a.product_type, 'v' )> 0, 'v', 'm' ) AS product_type ,
			u.createtime
		FROM
			entniche_wait_empower a
			INNER JOIN entniche_power b ON ( a.ent_id = ? AND a.end_time > ? AND b.STATUS = 1 AND a.id = b.wait_empower_id )
			INNER JOIN entniche_user u ON ( b.ent_user_id = u.id ) 
			%s
		) a
		LEFT JOIN entniche_user_rule b ON ( a.id = b.user_id %s)
	GROUP BY
		a.id,
		a.NAME,
		a.phone,
		b.rule_id,
		a.createtime
) as AllData 
WHERE`

	queryArr, valueArr := []string{" 1=1 "}, []interface{}{}
	nowStr := time.Now().Format(date.Date_Full_Layout)
	if userEnt.Role_admin_system { //企业管理员
		sql = fmt.Sprintf(sql, "", "", allRule)
		valueArr = append(valueArr, entId, entId, nowStr)
	} else { //部门管理员
		limit := fmt.Sprintf(" INNER JOIN entniche_department_user d ON ( d.user_id = u.id) WHERE d.dept_id =? ")
		sql = fmt.Sprintf(sql, limit, limit, allRule)
		valueArr = append(valueArr, entId, userEnt.Dept.Id, entId, nowStr, userEnt.Dept.Id)
	}

	// 查询条件过滤
	if query = strings.TrimSpace(query); query != "" {
		queryArr = append(queryArr, ` ( name LIKE ? or phone like ? ) `)
		valueArr = append(valueArr, "%"+query+"%", "%"+query+"%")
	}
	// 企业分发过滤
	if eStatus == 1 && len(ruleIds) == 0 {
		return 0, nil
	} else if eStatus != 0 && len(ruleIds) > 0 {
		if eStatus == 1 { //有个人订阅
			tStr := ``
			for i, v := range ruleIds {
				if i != 0 {
					tStr += `,`
				}
				tStr += fmt.Sprintf(`"%s"`, v)
			}
			queryArr = append(queryArr, fmt.Sprintf(` rule_id in ( %s ) `, tStr))
		} else if eStatus == -1 { //无个人订阅
			queryArr = append(queryArr, ` rule_id is NULL `)
		}
	}
	// 个人订阅过滤
	if pStatus == 1 && len(pSubscribeList) == 0 {
		return 0, nil
	} else if pStatus != 0 && len(pSubscribeList) > 0 {
		tStr := ``
		for i, v := range pSubscribeList {
			if i != 0 {
				tStr += `,`
			}
			tStr += fmt.Sprintf("%d", v)
		}

		if pStatus == 1 { //有个人订阅
			queryArr = append(queryArr, fmt.Sprintf(` id in ( %s ) `, tStr))
		} else if pStatus == -1 { //无个人订阅
			queryArr = append(queryArr, fmt.Sprintf(` id not in ( %s ) `, tStr))
		}
	}

	countSql := fmt.Sprintf("SELECT count(id) %s  %s", sql, strings.Join(queryArr, " AND "))
	total = IC.MainMysql.CountBySql(countSql, valueArr...)
	if total > 0 {
		finalSql := fmt.Sprintf("SELECT * %s  %s ORDER BY createtime DESC  LIMIT %d,%d", sql, strings.Join(queryArr, " AND "), common.If(pageNum >= 0, pageNum, 0).(int64)*pageSize, pageSize)
		finalRes := IC.MainMysql.SelectBySql(finalSql, valueArr...)
		if finalRes != nil && len(*finalRes) > 0 {
			for _, m := range *finalRes {
				eUser := common.Int64All(m["id"])
				hasPersonSubscribe := false
				for _, pid := range pSubscribeList {
					if pid == eUser {
						hasPersonSubscribe = true
						break
					}
				}
				list = append(list, &bxsubscribe.StaffSubscribe{
					Token:   encodeSubscribeMsg(gconv.Int64(entId), gconv.Int64(entUserId), gconv.Int64(m["id"]), common.ObjToString(m["rule_id"]), gconv.String(m["product_type"])),
					Name:    common.ObjToString(m["name"]),
					Phone:   common.ObjToString(m["phone"]),
					EStatus: gconv.Int64(common.If(common.ObjToString(m["rule_id"]) == "", -1, 1)),
					PStatus: gconv.Int64(common.If(hasPersonSubscribe, 1, -1)),
				})
			}
		}
	}
	return
}

// getEntPersonOrderList 查询企业订阅所有设置个人订阅的列表
func getEntPersonOrderList(entId int) (uIds []int64) {
	res, _ := IC.Mgo.Find("entniche_rule", map[string]interface{}{"i_entid": entId, "i_userid": map[string]interface{}{"$exists": 1}, "i_type": map[string]interface{}{"$exists": 1}}, nil, `{"o_entniche":1,"i_userid":1}`, false, -1, -1)
	if res == nil || len(*res) == 0 {
		return
	}
	for _, mData := range *res {
		uId := common.Int64All(mData["i_userid"])
		if uId <= 0 {
			continue
		}
		thisSub := &PersonSubscribe{}
		if gconv.Struct(mData["o_entniche"], thisSub) == nil {
			if !thisSub.IsEmpty() {
				uIds = append(uIds, uId)
			}
		}
	}
	return
}

// getEntSubscirbeList 查询企业分发列表
func getEntSubscirbeList(entId, depId int, isAdmin bool) (rId []string) {
	//查询是否有企业分发
	dept_subscribe := IC.MainMysql.Count("entniche_info", map[string]interface{}{"dept_subscribe": 1, "id": entId}) > 0
	queryMap := map[string]interface{}{
		"1": "1",
	}
	if dept_subscribe && !isAdmin {
		queryMap = map[string]interface{}{
			"i_entid":  entId,
			"i_status": 0, //0未删除 1已删除
			"i_deptid": depId,
		}
	} else if isAdmin {
		queryMap = map[string]interface{}{
			"i_entid":  entId,
			"i_status": 0, //0未删除 1已删除
			"i_deptid": map[string]interface{}{
				"$exists": false,
			},
		}
	}
	res, _ := IC.Mgo.Find("entniche_distribute", queryMap, nil, `{"_id":1,"o_area":1,"a_buyerclass":1,"a_items":1}`, false, -1, -1)
	if len(*res) > 0 {
		for _, v := range *res {
			rId = append(rId, mongodb.BsonIdToSId(v["_id"]))
		}
	}
	return
}

// GetStaffSubscribeDetail 获取企业个人订阅
func GetStaffSubscribeDetail(entId, uid int64, token string) (rData map[string]interface{}, err error) {
	entIdCheck, uidCheck, staffId, ruleId, power, err := decodeSubscribeMsg(token)
	if err != nil {
		return
	}
	if entId != entIdCheck || uid != uidCheck {
		err = fmt.Errorf("权限异常")
		return
	}
	if power == "" {
		err = fmt.Errorf("无订阅内容")
		return
	}
	rData = map[string]interface{}{}
	nameEntNiche, nameVipMember := "", "" //当只存在大会员或商机管理时 展示个人订阅；当都存在时展示产品信息
	valueEntNiche, valueVipMember := map[string]interface{}{}, map[string]interface{}{}

	if strings.Index(power, "e") > -1 {
		//个人订阅商机管理
		if data := getPersonSubscribe(map[string]interface{}{"i_entid": entId, "i_userid": staffId, "i_type": 0}); data != nil && len(data) > 0 {
			nameEntNiche = "个人订阅<br>商机管理"
			valueEntNiche = data
		}
	}
	if strings.Index(power, "m") > -1 || strings.Index(power, "v") > -1 {
		//大会员或超级订阅企业版
		if data := getPersonSubscribe(map[string]interface{}{"i_entid": entId, "i_userid": staffId, "i_type": 1}); data != nil && len(data) > 0 {
			nameVipMember = fmt.Sprintf("个人订阅<br>%s", common.If(strings.Index(power, "v") > -1, "超级订阅", "大会员"))
			valueVipMember = data
		}
	}

	if len(valueEntNiche) > 0 && len(valueVipMember) > 0 {
		rData[nameEntNiche] = valueEntNiche
		rData[nameVipMember] = valueVipMember
	} else if len(valueEntNiche) > 0 {
		rData["个人订阅"] = valueEntNiche
	} else if len(valueVipMember) > 0 {
		rData["个人订阅"] = valueVipMember
	}

	// 企业自动分发
	if ruleId != "" {
		if data := getEntDistribute(ruleId, entId, staffId); data != nil && len(data) > 0 {
			rData["企业自动分发"] = data
		}
	}
	return
}

// getPersonSubscribe 个人订阅
func getPersonSubscribe(query map[string]interface{}) (rData map[string]interface{}) {
	res, _ := IC.Mgo.FindOneByField("entniche_rule", query, `{"o_entniche":1,"i_userid":1}`)
	if res == nil || len(*res) == 0 {
		return
	}
	subDetail, rData := &PersonSubscribe{}, map[string]interface{}{}
	if err := gconv.Struct((*res)["o_entniche"], subDetail); err == nil {
		if subDetail.IsEmpty() {
			return
		}
		wordsList := []map[string]interface{}{}
		for _, set := range subDetail.AItems {
			for _, t := range set.AKey {
				wordsList = append(wordsList, map[string]interface{}{
					"key":    t.Key,
					"match":  t.Matchway,
					"notkey": t.Notkey,
				})
			}
		}

		rData["area"] = subDetail.OArea
		rData["infotype"] = subDetail.AInfotype
		rData["projectmatch"] = subDetail.IProjectmatch
		rData["matchway"] = common.If(subDetail.IMatchway == 0, 1, subDetail.IMatchway) //匹配方式 默认标题匹配 1
		rData["wordsList"] = wordsList
		rData["buyerClass"] = subDetail.ABuyerclass
	}
	return
}

// getEntDistribute 获取企业分发订阅
func getEntDistribute(ruleId string, entId, uid int64) (rData map[string]interface{}) {
	//查询分发内容
	ruleRes, _ := IC.Mgo.FindById("entniche_distribute", ruleId, `{"i_deptid":1,"o_area":1,"a_buyerclass":1,"a_items":1}`)
	if ruleRes == nil || len(*ruleRes) == 0 {
		return
	}
	rData = map[string]interface{}{}
	deptId := common.IntAll((*ruleRes)["i_deptid"])  //部门id
	itemArr := gconv.SliceStr((*ruleRes)["a_items"]) //关键词分类名称

	var area map[string][]string
	_ = gconv.Struct((*ruleRes)["o_area"], &area) //订阅地区

	//查询分发订阅关键词及信息类型
	var wordsRes *map[string]interface{}
	if deptId != 0 {
		wordsRes, _ = IC.Mgo.FindOne("entniche_rule", map[string]interface{}{"i_entid": entId, "i_deptid": deptId, "i_userid": map[string]interface{}{"$exists": 0}})
	} else {
		wordsRes, _ = IC.Mgo.FindOne("entniche_rule", map[string]interface{}{"i_entid": entId, "i_deptid": map[string]interface{}{"$exists": 0}, "i_userid": map[string]interface{}{"$exists": 0}})
	}
	wordsList := []map[string]interface{}{}
	infotype, i_projectmatch, i_matchway := []string{}, 0, 0
	if wordsRes != nil && len(*wordsRes) > 0 {
		thisSub := &PersonSubscribe{}
		if gconv.Struct((*wordsRes)["o_entniche"], thisSub) == nil {
			for _, set := range thisSub.AItems {
				for _, name := range itemArr {
					if set.SItem == name {
						for _, t := range set.AKey {
							wordsList = append(wordsList, map[string]interface{}{
								"key":    t.Key,
								"match":  t.Matchway,
								"notkey": t.Notkey,
							})
						}
					}
				}
			}
			i_matchway = thisSub.IMatchway
			i_projectmatch = thisSub.IProjectmatch
			infotype = thisSub.AInfotype
		}
	}
	rData["buyerClass"] = (*ruleRes)["a_buyerclass"] //采购单位类型
	rData["area"] = area
	rData["infotype"] = infotype
	rData["projectmatch"] = i_projectmatch
	rData["matchway"] = i_matchway
	rData["wordsList"] = wordsList
	return
}

// decodeSubscribeMsg token解密
func decodeSubscribeMsg(token string) (entId, uId, staffId int64, ruleId, power string, err error) {
	values := encrypt.DecodeArticleId2ByCheck(token)
	if len(values) != 5 {
		err = fmt.Errorf("解析异常")
		return
	}
	entId = gconv.Int64(values[0])
	uId = gconv.Int64(values[1])
	staffId = gconv.Int64(values[2])
	ruleId = gconv.String(values[3])
	power = gconv.String(values[4])

	if entId == 0 || uId == 0 || staffId == 0 {
		err = fmt.Errorf("参数异常")
		return
	}
	return
}

// encodeSubscribeMsg token加密
func encodeSubscribeMsg(entId, uId, staffId int64, ruleId, power string) string {
	return encrypt.EncodeArticleId2ByCheck(fmt.Sprintf("%d,%d,%d,%s,%s", entId, uId, staffId, ruleId, strings.Replace(power, ",", "_", -1)))
}
