package community

import (
	"errors"
	"fmt"
	"hongze/hongze_yb/global"
	"hongze/hongze_yb/models/request"
	"hongze/hongze_yb/models/response"
	"hongze/hongze_yb/models/tables/admin"
	"hongze/hongze_yb/models/tables/company"
	"hongze/hongze_yb/models/tables/company_product"
	"hongze/hongze_yb/models/tables/research_group"
	"hongze/hongze_yb/models/tables/research_group_relation"
	"hongze/hongze_yb/models/tables/research_variety_tag_relation"
	"hongze/hongze_yb/models/tables/variety_classify"
	"hongze/hongze_yb/models/tables/variety_tag"
	"hongze/hongze_yb/models/tables/wx_user"
	"hongze/hongze_yb/models/tables/yb_community_audio_listen_log"
	"hongze/hongze_yb/models/tables/yb_community_question"
	"hongze/hongze_yb/models/tables/yb_community_question_audio"
	"hongze/hongze_yb/models/tables/yb_community_question_process"
	"hongze/hongze_yb/services/alarm_msg"
	"hongze/hongze_yb/services/company_approval_message"
	"hongze/hongze_yb/services/user"
	"hongze/hongze_yb/services/wechat"
	"hongze/hongze_yb/utils"
	"strconv"
	"strings"
	"time"
)

// GetQuestionList 获取问答列表
func GetQuestionList(pageIndex, pageSize, onlyMine, varietyTagId, replyStatus, groupId int, userInfo user.UserInfo) (resp []*response.CommunityQuestionItem, err error) {
	condition := " is_deleted = 0"
	var pars []interface{}
	// 用户身份
	isResearcher, _, e := user.GetResearcherByUserInfo(userInfo)
	if e != nil {
		err = errors.New("获取用户身份失败 Err:" + e.Error())
		return
	}
	if onlyMine == 1 {
		if isResearcher { //如果是研究员
			if replyStatus == 4 { //分配给研究员未回答的问题
				condition += " and replier_user_id=? and reply_status = 2"
				pars = append(pars, userInfo.UserID)
			} else if replyStatus == 2 { //研究员提问的问题未分配或者未回答的问题
				condition += " and user_id=? and reply_status >0 and reply_status <3"
				pars = append(pars, userInfo.UserID)
			} else if replyStatus == 3 { //分配给研究员的已回答和研究员提问的被回答的问题
				condition += " and (replier_user_id=? or user_id=?) and reply_status =3"
				pars = append(pars, userInfo.UserID, userInfo.UserID)
			} else if replyStatus == 0 { //分配给研究员或者研究员提问的所以问题
				condition += " and (replier_user_id=? or user_id=?)"
				pars = append(pars, userInfo.UserID, userInfo.UserID)
			} else if replyStatus == 5 {
				// 已终止状态
				condition += " and replier_user_id=? and reply_status = 4"
				pars = append(pars, userInfo.UserID)
			}
		} else {
			condition += " and user_id=?"
			pars = append(pars, userInfo.UserID)
			if replyStatus == 2 { // 普通用户未回答为待分配和未回答
				condition += " and reply_status >0 and reply_status <3"
			} else if replyStatus == 3 {
				condition += " and reply_status = 3"
			}
		}
	} else {
		if replyStatus == 3 {
			condition += " and reply_status = 3"
		}
	}

	if varietyTagId > 0 {
		condition += " and variety_tag_id =?"
		pars = append(pars, varietyTagId)
	}
	if groupId > 0 {
		condition += " and research_group_second_id =?"
		pars = append(pars, groupId)
	}
	// 问题列表
	questionList, e := yb_community_question.GetPageListByCondition(condition, pars, pageIndex, pageSize)
	if e != nil {
		err = errors.New("获取问题列表失败 Err:" + e.Error())
		return
	}
	listLen := len(questionList)
	if listLen == 0 {
		return
	}
	idArr := make([]int, 0)
	for i := 0; i < listLen; i++ {
		idArr = append(idArr, questionList[i].CommunityQuestionID)
	}
	// 音频列表
	audioList, e := yb_community_question_audio.GetListByQuestrionIds(idArr)
	if e != nil {
		err = errors.New("获取音频列表失败 Err:" + e.Error())
		return
	}
	// 用户权限
	//authOk, permissionInfo, _, e := company.CheckBaseFiccPermission(userInfo.CompanyID, int(userInfo.UserID))
	//if e != nil {
	//	err = errors.New("获取用户权限失败 Err:" + e.Error())
	//	return
	//}

	userId := int(userInfo.UserID)
	resp = make([]*response.CommunityQuestionItem, 0)
	for _, v := range questionList {
		audios := make([]*response.CommunityQuestionAudioItem, 0)
		for _, a := range audioList {
			if a.CommunityQuestionID == v.CommunityQuestionID {
				audios = append(audios, &response.CommunityQuestionAudioItem{
					CommunityQuestionAudioID: a.CommunityQuestionAudioID,
					CommunityQuestionID:      a.CommunityQuestionID,
					AudioURL:                 a.AudioURL,
					AudioPlaySeconds:         a.AudioPlaySeconds,
					AudioSize:                a.AudioSize,
					Sort:                     a.Sort,
				})
			}
		}
		replierRank := fmt.Sprintf("弘则%s研究员", v.ResearchGroupFirstName)
		avatar := v.ReplierAvatar
		if avatar == "" {
			avatar = utils.HZ_DEFAULT_AVATAR
		}
		item := &response.CommunityQuestionItem{
			CommunityQuestionID:     v.CommunityQuestionID,
			UserId:                  v.UserID,
			QuestionContent:         v.QuestionContent,
			ReplierRealName:         v.ReplierRealName,
			ReplierRank:             replierRank,
			ReplierAvatar:           avatar,
			VarietyTagId:            v.VarietyTagID,
			VarietyTagName:          v.VarietyTagName,
			ResearchGroupSecondId:   v.ResearchGroupSecondID,
			ResearchGroupSecondName: v.ResearchGroupSecondName,
			IsRead:                  v.IsRead,
			ReplierUserID:           v.ReplierUserID,
			ReplierIsRead:           v.ReplierIsRead,
			ReplyStatus:             v.ReplyStatus,
			CreateTime:              v.CreateTime.Format(utils.FormatDateTime),
			ReplyTime:               v.ReplyTime.Format(utils.FormatDateTime),
			//AuthOk:                  authOk,
			//PermissionInfo:          permissionInfo,
			AudioList:  audios,
			StopReason: v.StopReason,
		}
		if item.IsRead == 0 && item.UserId == userId {
			item.IsTop = 1
		}
		resp = append(resp, item)
	}
	return
}

// GetQuestionDetail 获取问答详情
func GetQuestionDetail(questionId int, userInfo user.UserInfo) (item *response.CommunityQuestionItem, errMsg string, err error) {
	detail, e := yb_community_question.GetItemById(questionId)
	errMsg = "获取失败"
	if e != nil {
		if e == utils.ErrNoRow {
			errMsg = "问题已被删除"
		}
		err = errors.New("获取问题详情失败 Err:" + e.Error())
		return
	}
	audioList, e := yb_community_question_audio.GetListByQuestionId(questionId)
	if e != nil {
		err = errors.New("获取问题音频失败 Err:" + e.Error())
		return
	}
	audios := make([]*response.CommunityQuestionAudioItem, 0)
	for _, a := range audioList {
		audios = append(audios, &response.CommunityQuestionAudioItem{
			CommunityQuestionAudioID: a.CommunityQuestionAudioID,
			CommunityQuestionID:      a.CommunityQuestionID,
			AudioURL:                 a.AudioURL,
			AudioPlaySeconds:         a.AudioPlaySeconds,
			AudioSize:                a.AudioSize,
			Sort:                     a.Sort,
		})
	}
	replierRank := fmt.Sprintf("弘则%s研究员", detail.ResearchGroupFirstName)
	// 用户权限
	//authOk, permissionInfo, _, e := company.CheckBaseFiccPermission(userInfo.CompanyID, int(userInfo.UserID))
	//if e != nil {
	//	err = errors.New("获取用户权限失败 Err:" + e.Error())
	//	return
	//}
	avatar := detail.ReplierAvatar
	if avatar == "" {
		avatar = utils.HZ_DEFAULT_AVATAR
	}
	item = &response.CommunityQuestionItem{
		CommunityQuestionID:     detail.CommunityQuestionID,
		UserId:                  detail.UserID,
		QuestionContent:         detail.QuestionContent,
		ReplierRealName:         detail.ReplierRealName,
		ReplierRank:             replierRank,
		ReplierAvatar:           detail.ReplierAvatar,
		ReplierUserID:           detail.ReplierUserID,
		VarietyTagId:            detail.VarietyTagID,
		VarietyTagName:          detail.VarietyTagName,
		ResearchGroupSecondId:   detail.ResearchGroupSecondID,
		ResearchGroupSecondName: detail.ResearchGroupSecondName,
		IsRead:                  detail.IsRead,
		ReplierIsRead:           detail.ReplierIsRead,
		ReplyStatus:             detail.ReplyStatus,
		CreateTime:              detail.CreateTime.Format(utils.FormatDateTime),
		ReplyTime:               detail.ReplyTime.Format(utils.FormatDateTime),
		//AuthOk:                  authOk,
		//PermissionInfo:          permissionInfo,
		AudioList: audios,
	}
	errMsg = "获取成功"
	return
}

// CreateQuestion 新增问答
func CreateQuestion(userId, varietyClassifyId, varietyTagId int, mobile, realName, content string) (err error) {
	// 获取分类
	classifyItem, e := variety_classify.GetVarietyClassifyById(varietyClassifyId)
	if e != nil {
		err = errors.New("获取问答标签分类失败 Err:" + e.Error())
		return
	}

	// 获取标签
	tagItem, e := variety_tag.GetVarietyTagById(varietyTagId)
	if e != nil {
		err = errors.New("获取问答标签失败 Err:" + e.Error())
		return
	}

	// 获取标签对应的研究方向分组-研究员信息
	researcher, e := GetFirstResearcherByVarietyTagId(tagItem.VarietyTagID)
	if e != nil {
		err = errors.New("获取标签对应研究员信息失败 Err:" + e.Error())
		return
	}

	nowTime := time.Now().Local()
	item := &yb_community_question.YbCommunityQuestion{
		UserID:                  userId,
		Mobile:                  mobile,
		RealName:                realName,
		QuestionContent:         content,
		ReplyStatus:             2,
		IsRead:                  1,
		ReplierIsRead:           0,
		MsgSendStatus:           1,
		ReplierUserID:           researcher.UserId,
		ReplierAdminID:          researcher.AdminId,
		ReplierRealName:         researcher.AdminName,
		ResearchGroupFirstID:    classifyItem.VarietyClassifyID,
		ResearchGroupFirstName:  classifyItem.ClassifyName,
		ResearchGroupSecondID:   tagItem.VarietyTagID,
		ResearchGroupSecondName: tagItem.TagName,
		VarietyTagID:            tagItem.VarietyTagID,
		VarietyTagName:          tagItem.TagName,
		CreateTime:              nowTime,
	}
	if e := item.Create(); e != nil {
		err = errors.New("新增问题失败 Err:" + e.Error())
		return
	}

	// 新增问答流程
	go func() {
		pro := new(yb_community_question_process.YbCommunityQuestionProcess)
		pro.CommunityQuestionID = item.CommunityQuestionID
		pro.ReplierUserID = researcher.UserId
		pro.ReplierAdminID = researcher.AdminId
		pro.ReplierAdminName = researcher.AdminName
		pro.VarietyClassifyID = classifyItem.VarietyClassifyID
		pro.VarietyTagID = tagItem.VarietyTagID
		pro.Remark = fmt.Sprintf("自动分配问题给研究员%s", researcher.AdminName)
		pro.ProcessType = yb_community_question_process.ProcessTypeDistribute
		pro.CreateTime = nowTime
		if e = pro.Create(); e != nil {
			return
		}
	}()

	// 推送待回复模板消息给研究员
	go func() {
		_ = wechat.SendQuestionToResearcher(item.CommunityQuestionID, researcher.OpenId, item.QuestionContent, "")
	}()

	// 暂不推送消息给管理员了(其实就是沛总=_=!)
	//go messageToAdmin(userId, item)
	return
}

// ReplyUserQuestion 回复问题
func ReplyUserQuestion(replierId, questionId int, audios []*request.ReplyReqAudioList) (errMsg string, err error) {
	item, e := yb_community_question.GetItemById(questionId)
	if e != nil {
		errMsg = "问答信息有误"
		err = errors.New("获取提问信息失败 Err:" + e.Error())
		return
	}
	if item.ReplyStatus < 2 {
		errMsg = "回复状态有误"
		err = errors.New("回复状态有误")
		return
	}
	if item.ReplyStatus == 3 {
		errMsg = "请勿重复提交"
		err = errors.New("问题已回复,请勿重复提交")
		return
	}
	if item.ReplierUserID != replierId {
		errMsg = "回复人不匹配"
		err = errors.New(fmt.Sprintf("回复人与分配人不匹配, 当前回复人ID: %d, 分配的回复人ID: %d", replierId, item.ReplierUserID))
		return
	}
	// 问题
	updateCols := make([]string, 0)
	updateCols = append(updateCols, "reply_status", "reply_time", "modify_time", "msg_send_status", "is_read")
	nowTime := time.Now().Local()
	item.ReplyStatus = yb_community_question.ReplyStatusDone
	item.ReplyTime = nowTime
	item.ModifyTime = nowTime
	item.MsgSendStatus = 2
	item.IsRead = 0
	// 音频
	audioList := make([]*yb_community_question_audio.YbCommunityQuestionAudio, 0)
	for _, v := range audios {
		audioList = append(audioList, &yb_community_question_audio.YbCommunityQuestionAudio{
			CommunityQuestionID: questionId,
			AudioURL:            v.AudioUrl,
			AudioPlaySeconds:    v.AudioPlaySeconds,
			AudioSize:           v.AudioSize,
			Sort:                v.Sort,
			CreateTime:          nowTime,
		})
	}
	if e := yb_community_question.UpdateQuestionAndAudioList(item, updateCols, audioList); e != nil {
		err = errors.New("UpdateQuestionAndAudioList Err:" + e.Error())
		return
	}
	// 推送回复消息给用户
	go wechat.SendQuestionReplyWxMsg(item.CommunityQuestionID, item.UserID, item.QuestionContent)
	return
}

// ReadQuestionReply 回复已读
func ReadQuestionReply(questionIds string, userInfo user.UserInfo) (err error) {
	if questionIds == "" {
		return
	}
	questionIdArr := make([]int, 0)
	questionIdStrArr := strings.Split(questionIds, ",")
	for _, v := range questionIdStrArr {
		i, _ := strconv.Atoi(v)
		questionIdArr = append(questionIdArr, i)
	}
	if len(questionIdArr) == 0 {
		return
	}
	isResearcher, _, e := user.GetResearcherByUserInfo(userInfo)
	if e != nil {
		err = errors.New("获取用户身份失败 Err:" + e.Error())
		return
	}
	if isResearcher {
		// 设置分配给研究员的问答已读
		e = yb_community_question.UpdateReplierRead(int(userInfo.UserID), questionIdArr)
		if e != nil {
			err = errors.New("更新问答已读失败 Err:" + e.Error())
			return
		}
		// 设置研究员提问的问答已读
		e = yb_community_question.UpdateUserRead(int(userInfo.UserID), questionIdArr)
	} else {
		// 设置普通用户的问答已读
		e = yb_community_question.UpdateUserRead(int(userInfo.UserID), questionIdArr)
	}
	if e != nil {
		err = errors.New("更新问答已读失败 Err:" + e.Error())
	}
	return
}

// GetQuestionListTotal 获取问答列表数量统计
func GetQuestionListTotal(userInfo user.UserInfo) (resp *response.CommunityQuestionListTotal, err error) {
	isResearcher, _, e := user.GetResearcherByUserInfo(userInfo)
	if e != nil {
		err = errors.New("获取用户身份失败 Err:" + e.Error())
		return
	}
	condition := " is_deleted = 0"
	var pars []interface{}
	if isResearcher {
		condition += " and (replier_user_id=? or user_id=?)"
		pars = append(pars, userInfo.UserID, userInfo.UserID)
	} else {
		condition += " and user_id=?"
		pars = append(pars, userInfo.UserID)
	}
	countList, e := yb_community_question.GetQuestionListCount(condition, pars)
	if e != nil {
		err = errors.New("获取回复人问题统计失败 Err:" + e.Error())
		return
	}
	resp = new(response.CommunityQuestionListTotal)
	var distribute, wait, replied, stop, total int
	for _, v := range countList {
		total += v.Total
		if isResearcher {
			if v.UserId == userInfo.UserID {
				if v.ReplyStatus == 1 || v.ReplyStatus == 2 { //研究员提问的待分配的问题
					wait += v.Total
				}
			}
			if v.ReplierUserId == userInfo.UserID && v.ReplyStatus == 2 { //分配给研究员的未回答的问题
				distribute += v.Total
			}
			if v.ReplyStatus == 3 {
				replied += v.Total
			}
			if v.ReplyStatus == yb_community_question.ReplyStatusStop {
				stop += v.Total
			}
		} else {
			if v.ReplyStatus == 1 || v.ReplyStatus == 2 { //未分配和未回答的数量
				wait += v.Total
			} else if v.ReplyStatus == 3 { //已回答的数量
				replied += v.Total
			}
		}

	}
	if isResearcher {
		resp.Distribute = distribute
	}
	resp.Wait = wait
	resp.Replied = replied
	resp.Total = total
	resp.Stop = stop

	return
}

// GetMyQuestionUnread 获取我的未读数
func GetMyQuestionUnread(userInfo user.UserInfo) (total int, err error) {
	isResearcher, _, e := user.GetResearcherByUserInfo(userInfo)
	if e != nil {
		err = errors.New("获取用户身份失败 Err:" + e.Error())
		return
	}
	condition := " is_deleted = 0"
	var pars []interface{}
	if isResearcher {
		condition += " and ((replier_user_id=? and replier_is_read=0) or (user_id=? and is_read=0))"
		pars = append(pars, userInfo.UserID, userInfo.UserID)
	} else {
		condition += " and user_id=? and is_read=0"
		pars = append(pars, userInfo.UserID)
	}
	num, e := yb_community_question.GetUnreadNum(condition, pars)
	if e != nil {
		err = errors.New("获取我的未读数失败 Err:" + e.Error())
		return
	}
	total = int(num)
	return
}

// GetResearchGroupTree 获取研究方向分组
func GetResearchGroupTree() (respList []*response.ResearchGroupItem, err error) {
	respList = make([]*response.ResearchGroupItem, 0)
	list, e := research_group.GetResearchGroupList()
	if e != nil {
		err = errors.New("获取研究方向分组失败, Err:" + e.Error())
		return
	}
	listLen := len(list)
	if listLen == 0 {
		return
	}
	// 分类
	firstList := make([]*response.ResearchGroupItem, 0)
	secondList := make([]*response.ResearchGroupItem, 0)
	for i := 0; i < listLen; i++ {
		item := new(response.ResearchGroupItem)
		item.ResearchGroupId = list[i].ResearchGroupID
		item.ResearchGroupName = list[i].ResearchGroupName
		item.ParentId = list[i].ParentID
		item.ChartPermissionId = list[i].ChartPermissionID
		item.Sort = list[i].Sort
		if list[i].ParentID == 0 {
			firstList = append(firstList, item)
		} else {
			secondList = append(secondList, item)
		}
	}
	if len(firstList) == 0 {
		return
	}
	// 匹配成员
	relationList, e := research_group_relation.GetResearchGroupRelationList()
	if e != nil {
		err = errors.New("获取研究方向关系失败, Err:" + e.Error())
		return
	}
	for _, v := range secondList {
		members := make([]*response.ResearchGroupMember, 0)
		for _, r := range relationList {
			if v.ResearchGroupId == r.ResearchGroupId {
				members = append(members, &response.ResearchGroupMember{
					AdminId:   r.AdminId,
					AdminName: r.AdminName,
				})
			}
		}
		v.Members = members
	}
	// 匹配子分类
	for _, p := range firstList {
		children := make([]*response.ResearchGroupItem, 0)
		for _, child := range secondList {
			if p.ResearchGroupId == child.ParentId {
				children = append(children, child)
			}
		}
		p.Children = children
	}
	respList = firstList
	return
}

// AddAudioListenLog 添加用户点击音频日志
func AddAudioListenLog(userInfo user.UserInfo, audioId int, sourceAgent int) (newId int, err error) {
	//1. 查询音频是否存在
	audio, err := yb_community_question_audio.GetByAudioId(audioId)
	if err != nil && err != utils.ErrNoRow {
		err = errors.New("查询音频信息失败 Err:" + err.Error())
		return
	}
	if err == utils.ErrNoRow {
		err = errors.New("音频不存在")
		return
	}
	if audio == nil {
		err = errors.New("音频不存在")
		return
	}
	companyInfo, e := company_product.GetByCompany2ProductId(userInfo.CompanyID, 1)
	if e != nil && e != utils.ErrNoRow {
		err = errors.New("获取客户信息失败")
		return
	}
	companyName := "潜在客户"
	companyStatus := "潜在"
	sellerId := 0
	if companyInfo != nil && companyInfo.CompanyID > 0 {
		companyName = companyInfo.CompanyName
		companyStatus = companyInfo.Status
		sellerId = companyInfo.SellerID
	}
	//3. 添加点击日志
	item := &yb_community_audio_listen_log.YbCommunityAudioListenLog{
		CommunityQuestionAudioID: audio.CommunityQuestionAudioID,
		CommunityQuestionID:      audio.CommunityQuestionID,
		UserID:                   int(userInfo.UserID),
		RealName:                 userInfo.RealName,
		CompanyID:                int(userInfo.CompanyID),
		CompanyName:              companyName,
		CompanyStatus:            companyStatus,
		SellerID:                 sellerId,
		SourceAgent:              sourceAgent,
	}
	if err = item.Create(); err != nil {
		err = errors.New("新增点击日志失败 Err:" + err.Error())
		return
	}
	newId = item.Id
	return
}

// messageToAdmin 添加站内消息
func messageToAdmin(userId int, ybCommunityQuestion *yb_community_question.YbCommunityQuestion) {
	var err error
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("新增社区问答完成后,发送消息给管理员失败"+time.Now().Format("2006-01-02 15:04:05")+";Err:"+err.Error(), 3)
		}
	}()

	//因为产品说只要给沛总发送信息,那么没办法咯,只去获取沛总的信息 2022-07-19 11:29:16
	vWangInfo, err := admin.GetVWangInfo()
	if err != nil {
		return
	}
	//站内消息
	go systemMessageToAdmin(*vWangInfo, userId, ybCommunityQuestion)
	//微信模板消息
	go wxMessageToAdmin(*vWangInfo, ybCommunityQuestion)

	return
}

// systemMessageToAdmin 系统消息消息通知管理员
func systemMessageToAdmin(adminInfo admin.Admin, userId int, ybCommunityQuestion *yb_community_question.YbCommunityQuestion) {
	var err error
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("新增社区问答完成后,站内评论信息发送给管理员失败"+time.Now().Format("2006-01-02 15:04:05")+";Err:"+err.Error(), 3)
		}
	}()
	// 接收人的admin_id
	receiveUserId := int(adminInfo.AdminID)

	//获取评论人信息
	wxUser, err := wx_user.GetByUserId(userId)
	if err != nil {
		return
	}
	var msgType, sourceType, approvalStatus int8
	msgType = company_approval_message.CompanyApprovalMessageMessageTypeByApply
	sourceType = company_approval_message.CompanyApprovalMessageSourceTypeByQuestion
	approvalStatus = company_approval_message.CompanyApprovalMessageApprovalStatusByPending

	companyInfo, err := company.GetByCompanyId(wxUser.CompanyID)
	if err != nil {
		return
	}

	productId := 1
	companyProductInfo, err := company_product.GetByCompany2ProductId(wxUser.CompanyID, int64(productId))
	if err != nil {
		return
	}

	companyName := companyInfo.CompanyName
	remark := `您有新的问答待分配`
	content := `您有新的问答待分配`

	messageInfo := company_approval_message.MessageInfo{
		CompanyName:          companyInfo.CompanyName,
		ProductId:            productId,
		CompanyProductStatus: companyProductInfo.Status,
		Title:                ybCommunityQuestion.QuestionContent,
		Content:              ybCommunityQuestion.QuestionContent,
		UserId:               wxUser.UserID,
		UserName:             ybCommunityQuestion.RealName,
		CreateTime:           ybCommunityQuestion.CreateTime,
	}
	//客户添加消息
	err = company_approval_message.AddCompanyApprovalMessage(utils.AdminId, receiveUserId, int(wxUser.CompanyID), ybCommunityQuestion.CommunityQuestionID, msgType, sourceType, approvalStatus, companyName, remark, content, messageInfo)
	return
}

// wxMessageToAdmin 微信模板消息通知管理员
func wxMessageToAdmin(adminInfo admin.Admin, ybCommunityQuestion *yb_community_question.YbCommunityQuestion) {
	var err error
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("新增社区问答完成后,微信模板消息发送给管理员失败"+time.Now().Format("2006-01-02 15:04:05")+";Err:"+err.Error(), 3)
		}
	}()

	if global.CONFIG.Serve.RunMode == "debug" {
		adminInfo.Mobile = `18221983795`
	}

	err = wechat.SendQuestionToAdmin(ybCommunityQuestion.CommunityQuestionID, int(adminInfo.AdminID), adminInfo.OpenId, ybCommunityQuestion.QuestionContent)
	return
}

// GetFirstResearcherByVarietyTagId 通过品种标签ID获取首位研究员admin信息及wx_user信息
func GetFirstResearcherByVarietyTagId(tagId int) (researcher *admin.ResearcherAdminAndUser, err error) {
	researcher = new(admin.ResearcherAdminAndUser)

	// 获取标签研究员关系组
	relationList, e := research_variety_tag_relation.GetResearchVarietyTagRelationList()
	if e != nil {
		err = errors.New("获取研究员分组失败, Err: " + e.Error())
		return
	}
	if len(relationList) == 0 {
		err = errors.New("获取研究员分组有误")
		return
	}

	// 从当前组取出有效的研究员信息
	for i := range relationList {
		if relationList[i].VarietyTagId == tagId {
			item, e := admin.GetResearcherAdminAndWxUserByAdminId(relationList[i].AdminId)
			if e != nil && e != utils.ErrNoRow {
				err = errors.New("获取研究员成员信息失败, Err: " + e.Error())
				return
			}
			if item != nil && item.UserId > 0 && item.AdminId > 0 && item.OpenId != "" {
				researcher = item
				break
			}
		}
	}
	// 未在当前组找到有效的研究员信息, 去其他组找
	if researcher.UserId == 0 || researcher.AdminId == 0 || researcher.OpenId == "" {
		for i := range relationList {
			if relationList[i].VarietyTagId != tagId {
				item, e := admin.GetResearcherAdminAndWxUserByAdminId(relationList[i].AdminId)
				if e != nil && e != utils.ErrNoRow {
					err = errors.New("获取其他组研究员成员信息失败, Err: " + e.Error())
					return
				}
				if item != nil && item.UserId > 0 && item.AdminId > 0 && item.OpenId != "" {
					researcher = item
					break
				}
			}
		}
	}
	// 无有效研究员
	if researcher.UserId == 0 || researcher.AdminId == 0 || researcher.OpenId == "" {
		err = errors.New("无有效研究员可分配")
	}
	return
}

// TransferQuestion 转移问答
func TransferQuestion(questionId, userId, userAdminId, varietyClassifyId, varietyTagId, adminId int, userAdminName string) (errMsg string, err error) {
	errMsg = "操作失败"
	item, e := yb_community_question.GetItemById(questionId)
	if e != nil {
		err = errors.New("获取提问信息失败 Err:" + e.Error())
		return
	}
	if item.ReplyStatus != yb_community_question.ReplyStatusWait {
		errMsg = "当前状态不可转移"
		err = errors.New("回复状态有误")
		return
	}
	if item.ReplierUserID != userId {
		errMsg = "无权操作"
		err = errors.New(fmt.Sprintf("回复人与分配人不匹配, 当前回复人ID: %d, 分配的回复人ID: %d", userId, item.ReplierUserID))
		return
	}

	// 获取分类
	classifyItem, e := variety_classify.GetVarietyClassifyById(varietyClassifyId)
	if e != nil {
		err = errors.New("获取问答标签分类失败 Err:" + e.Error())
		return
	}

	// 获取标签
	tagItem, e := variety_tag.GetVarietyTagById(varietyTagId)
	if e != nil {
		err = errors.New("获取问答标签失败 Err:" + e.Error())
		return
	}

	// 获取研究员信息失败
	researcher, e := admin.GetResearcherAdminAndWxUserByAdminId(adminId)
	if e != nil {
		errMsg = "该研究员未关注公众号或无法正确接收模板消息"
		err = errors.New("获取研究员信息失败 Err:" + e.Error())
		return
	}

	// 更新问答
	nowTime := time.Now().Local()
	updateCols := []string{
		"ReplierIsRead", "ReplierUserID", "ReplierAdminID", "ReplierRealName", "ResearchGroupFirstID", "ResearchGroupFirstName",
		"ResearchGroupSecondID", "ResearchGroupSecondName", "VarietyTagID", "VarietyTagName", "ModifyTime",
	}
	item.ReplierIsRead = 0
	item.ReplierUserID = researcher.UserId
	item.ReplierAdminID = researcher.AdminId
	item.ReplierRealName = researcher.AdminName
	item.ResearchGroupFirstID = classifyItem.VarietyClassifyID
	item.ResearchGroupFirstName = classifyItem.ClassifyName
	item.ResearchGroupSecondID = tagItem.VarietyTagID
	item.ResearchGroupSecondName = tagItem.TagName
	item.VarietyTagID = tagItem.VarietyTagID
	item.VarietyTagName = tagItem.TagName
	item.ModifyTime = nowTime
	if e = item.Update(updateCols); e != nil {
		err = errors.New("更新问答失败 Err:" + e.Error())
		return
	}

	// 新增问答流程
	go func() {
		pro := new(yb_community_question_process.YbCommunityQuestionProcess)
		pro.CommunityQuestionID = item.CommunityQuestionID
		pro.TransferUserID = userId
		pro.TransferAdminID = userAdminId
		pro.TransferAdminName = userAdminName
		pro.ReplierUserID = researcher.UserId
		pro.ReplierAdminID = researcher.AdminId
		pro.ReplierAdminName = researcher.AdminName
		pro.VarietyClassifyID = classifyItem.VarietyClassifyID
		pro.VarietyTagID = tagItem.VarietyTagID
		pro.Remark = fmt.Sprintf("转至%s", researcher.AdminName)
		pro.ProcessType = yb_community_question_process.ProcessTypeTransfer
		pro.CreateTime = nowTime
		if e = pro.Create(); e != nil {
			return
		}
	}()

	// 推送转移模板消息给研究员
	go func() {
		remark := fmt.Sprintf("【%s】移交了新的问答给您, 请点击详情尽快处理", userAdminName)
		_ = wechat.SendQuestionToResearcher(item.CommunityQuestionID, researcher.OpenId, item.QuestionContent, remark)
	}()
	return
}

// StopQuestion 终止问答
func StopQuestion(questionId, userId int, reason string) (errMsg string, err error) {
	errMsg = "操作失败"
	item, e := yb_community_question.GetItemById(questionId)
	if e != nil {
		err = errors.New("获取提问信息失败 Err:" + e.Error())
		return
	}
	if item.ReplyStatus != yb_community_question.ReplyStatusWait {
		errMsg = "当前状态不可终止"
		err = errors.New("回复状态有误")
		return
	}
	if item.ReplierUserID != userId {
		errMsg = "无权操作"
		err = errors.New(fmt.Sprintf("回复人与分配人不匹配, 当前回复人ID: %d, 分配的回复人ID: %d", userId, item.ReplierUserID))
		return
	}

	// 更新问答
	nowTime := time.Now().Local()
	updateCols := []string{
		"ReplyStatus", "StopReason", "ModifyTime",
	}
	item.ReplyStatus = yb_community_question.ReplyStatusStop
	item.StopReason = reason
	item.ModifyTime = nowTime
	if e = item.Update(updateCols); e != nil {
		err = errors.New("更新问答失败 Err:" + e.Error())
		return
	}
	return
}