package yb_community_question

import (
	"errors"
	"fmt"
	"hongze/hongze_yb/global"
	"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/rddp/chart_permission"
	"hongze/hongze_yb/models/tables/wx_user"
	"hongze/hongze_yb/models/tables/yb_comment_anonymous_user"
	"hongze/hongze_yb/models/tables/yb_community_question"
	"hongze/hongze_yb/models/tables/yb_community_question_comment"
	"hongze/hongze_yb/models/tables/yb_community_video"
	"hongze/hongze_yb/models/tables/yb_road_video"
	"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/services/wx_app"
	"hongze/hongze_yb/utils"
	"strconv"
	"strings"
	"time"
)

// Comment 发布留言
func Comment(user user.UserInfo, communityQuestionID uint32, content string, sourceAgent, isShowName, source int8, qaAvatarUrl, copyYb string) (ybCommunityQuestionComment *yb_community_question_comment.YbCommunityQuestionComment, err error, errMsg string) {
	errMsg = "发布留言失败"
	defer func() {
		if err != nil {
			global.LOG.Critical(fmt.Sprintf("yb_community_question Comment: userId=%d, err:%s， errMsg:%s", user.UserID, err.Error(), errMsg))
		}
	}()
	//校验请求入参
	if isShowName != 0 && isShowName != 1 {
		errMsg = "匿名设置出错"
		err = errors.New(errMsg)
		return
	}
	if content == "" {
		errMsg = "请输入留言内容"
		err = errors.New(errMsg)
		return
	}
	if sourceAgent == 0 {
		errMsg = "请输入留言来源"
		err = errors.New(errMsg)
		return
	}
	if communityQuestionID <= 0 {
		errMsg = "请输入问答ID"
		err = errors.New(errMsg)
		return
	}
	if source <= 0 {
		errMsg = "来源有误"
		err = errors.New(errMsg)
		return
	}

	// 敏感词过滤
	if user.RecordInfo.OpenID != "" && (user.RecordInfo.CreatePlatform == utils.USER_RECORD_PLATFORM_YB || user.RecordInfo.CreatePlatform == utils.USER_RECORD_PLATFORM_COPY_YB) { //只有小程序的用户才能走敏感词过滤接口
		checkResult, tErr := wx_app.MsgSecCheck(user.RecordInfo.OpenID, content, copyYb)
		/*if tErr != nil {
			errMsg = "敏感词过滤失败" + tErr.Error()
			err = errors.New("敏感词过滤失败")
			return
		}*/
		if tErr == nil {
			if checkResult.Result != nil {
				if checkResult.Result.Suggest != "pass" {
					errMsg = "含有违禁词，不允许发布：" + checkResult.Result.Suggest + ".命中标签：" + strconv.Itoa(checkResult.Result.Label)
					err = errors.New("含有违禁词，不允许发布。")
					return
				}
			}
		}
	}

	userName := "匿名用户" + strconv.Itoa(int(3333+user.UserID))
	if user.RealName != `` {
		userName = user.RealName
	}
	//新增留言
	now := time.Now()
	ybCommunityQuestionComment = &yb_community_question_comment.YbCommunityQuestionComment{
		//CommunityQuestionCommentID: 0,
		CommunityQuestionID: communityQuestionID,
		UserID:              user.UserID,
		RealName:            userName,
		Content:             content,
		//ReplyCommentID:             0,
		//IsTop:                      0,
		//IsHot:                      0,
		//HotTopTime:                 time.Time{},
		Type:        1,
		Enabled:     1,
		IsShowName:  isShowName,
		SourceAgent: sourceAgent,
		//TopTime:                    time.Time{},
		//HotTime:                    time.Time{},
		ModifyTime:  now,
		CreateTime:  now,
		QaAvatarUrl: qaAvatarUrl,
		Source:      source,
	}
	err = ybCommunityQuestionComment.Create()
	if err != nil {
		errMsg = "新增留言失败"
		return
	}

	// 用户评论完后发送消息给管理员
	go messageToAdmin(user, ybCommunityQuestionComment)
	return
}

// Delete 删除留言
func Delete(user user.UserInfo, communityQuestionCommentID uint64) (err error, errMsg string) {
	errMsg = `删除留言失败`
	defer func() {
		if err != nil {
			global.LOG.Critical(fmt.Sprintf("comment Delete: userId=%d, err:%s， errMsg:%s", user.UserID, err.Error(), errMsg))
		}
	}()
	if communityQuestionCommentID <= 0 {
		errMsg = `请输入留言ID`
		err = errors.New(errMsg)
		return
	}
	//校验请求入参
	communityQuestionCommentInfo, err := yb_community_question_comment.GetByCommunityQuestionCommentId(communityQuestionCommentID)
	if err != nil {
		errMsg = `查询留言出错`
		return
	}
	if communityQuestionCommentInfo.CommunityQuestionCommentID <= 0 {
		errMsg = `留言不存在`
		err = errors.New(errMsg)
		return
	}
	if communityQuestionCommentInfo.UserID != user.UserID {
		errMsg = `不允许删除他人的留言`
		err = errors.New(errMsg)
		return
	}
	if communityQuestionCommentInfo.Type != 1 {
		errMsg = `不允许删除回复`
		err = errors.New(errMsg)
		return
	}
	if communityQuestionCommentInfo.Enabled == 0 {
		return
	}
	err = yb_community_question_comment.Delete(user.UserID, communityQuestionCommentInfo.CommunityQuestionCommentID)
	if err != nil {
		errMsg = `删除留言出错`
		return
	}

	go afterDelete(communityQuestionCommentInfo)
	return
}

// MyList 我的留言列表
func MyList(userId uint64, communityQuestionID, source int, page, pageSize int) (list []*response.RespCommunityQuestionCommentItem, hotTotal, myTotal int64, err error, errMsg string) {
	list, hotTotal, myTotal, err, errMsg = List(userId, communityQuestionID, source, false, page, pageSize)
	if err != nil {
		return
	}
	return
}

// List 查询精选留言列表或我的留言列表
func List(userId uint64, communityQuestionID, source int, hotFlag bool, page, pageSize int) (list []*response.RespCommunityQuestionCommentItem, hotTotal, myTotal int64, err error, errMsg string) {
	defer func() {
		if err != nil {
			global.LOG.Critical(fmt.Sprintf("comment List: userId=%d, err:%s， errMsg:%s", userId, err.Error(), errMsg))
		}
	}()
	list = make([]*response.RespCommunityQuestionCommentItem, 0)

	if communityQuestionID <= 0 {
		err = errors.New("请输入问答ID")
		return
	}

	//精选留言数
	hotTotal, err = yb_community_question_comment.GetHotListTotalByCommunityQuestionID(communityQuestionID, source)
	if err != nil {
		errMsg = `查询精选留言总数出错`
		return
	}

	// 我的留言数
	myTotal, err = yb_community_question_comment.GetListTotalByUserIdCommunityQuestionID(userId, communityQuestionID, source)
	if err != nil {
		errMsg = `查询我的留言总数出错`
		return
	}

	var commentList []*yb_community_question_comment.YbCommunityQuestionComment
	//查询精选留言
	if hotFlag {
		commentList, err = yb_community_question_comment.GetHotListByCommunityQuestionID(communityQuestionID, (page-1)*pageSize, pageSize, source)
		if err != nil {
			errMsg = `查询精选留言列表出错`
			return
		}

	} else {
		//查询个人留言
		commentList, err = yb_community_question_comment.GetListByUserIdCommunityQuestionID(userId, communityQuestionID, source)
		if err != nil {
			errMsg = `查询我的留言列表出错`
			return
		}
	}

	var commentIds []uint64
	var userIds []uint64
	for _, v := range commentList {
		commentIds = append(commentIds, v.CommunityQuestionCommentID)
		userIds = append(userIds, v.UserID)
	}

	// 查询所有的回复列表
	//{
	//	replyListMap := make(map[uint64][]*response.ReplyItem)
	//	if len(commentIds) > 0 {
	//		replyList, tErr := yb_community_question_comment.GetReplyListByReplyCommentId(commentIds)
	//		if tErr != nil {
	//			errMsg = tErr.Error()
	//			err = errors.New("查询回复出错")
	//			return
	//		}
	//		for _, v := range replyList {
	//			t := new(response.ReplyItem)
	//			t.CommentId = v.CommunityQuestionCommentID
	//			t.Content = v.Content
	//			t.AdminId = v.AdminID
	//			t.CreateTime = v.CreateTime
	//			t.ReplyCommentId = v.ReplyCommentId
	//			t.AdminName = "弘则研究"
	//			t.AdminImgUrl = utils.DEFAULT_HONGZE_SYS_LOGO
	//			replyListMap[v.ReplyCommentId] = append(replyListMap[v.ReplyCommentId], t)
	//		}
	//	}
	//}

	// 查询精选留言相关的用户
	var userOthers []*wx_user.WxUser
	if len(userIds) > 0 {
		userOthers, err = wx_user.GetByUserIds(userIds)
		if err != nil {
			errMsg = err.Error()
			err = errors.New("查询精选留言用户出错")
			return
		}
	}
	usersMap := make(map[uint64]*wx_user.WxUser)
	for _, v := range userOthers {
		usersMap[v.UserID] = v
	}
	for _, v := range commentList {
		tmp := &response.RespCommunityQuestionCommentItem{
			CommunityQuestionCommentID: v.CommunityQuestionCommentID,
			UserId:                     v.UserID,
			Content:                    v.Content,
			IsTop:                      v.IsTop,
			IsHot:                      v.IsHot,
			HotTopTime:                 v.HotTopTime,
			IsShowName:                 v.IsShowName,
			UserName:                   "匿名用户" + strconv.Itoa(int(3333+v.UserID)),
			UserImgUrl:                 utils.DEFAULT_HONGZE_USER_LOGO,
			CreateTime:                 v.CreateTime,
			ReplyList:                  nil,
			QaAvatarUrl:                v.QaAvatarUrl,
		}
		if info, ok := usersMap[v.UserID]; ok && v.IsShowName == 1 {
			tmp.UserName = info.NickName
			tmp.UserImgUrl = info.Headimgurl
		}
		//if existList, ok := replyListMap[v.CommentId]; ok {
		//	tmp.ReplyList = existList
		//}
		list = append(list, tmp)
	}
	return
}

// GetNeedCommentAnonymousUserTips 获取是否 弹出让去设置头像 的提示框
func GetNeedCommentAnonymousUserTips(userId uint64) (ok bool, err error) {
	ybCommentAnonymousUser, err := yb_comment_anonymous_user.GetByUserId(userId)
	if err != nil {
		return
	}
	//如果能找到，那么认为是有设置过匿名评论，那么不需要需要弹框提示
	if ybCommentAnonymousUser.UserID > 0 {
		ok = true
	}
	return
}

// SetYbCommentAnonymousUserTips 设置不再提示 弹出让去设置头像 的提示框
func SetYbCommentAnonymousUserTips(userId uint64) (err error) {
	ybCommentAnonymousUser, err := yb_comment_anonymous_user.GetByUserId(userId)
	if err != nil {
		return
	}
	//如果找不到，那么认为是第一次评论，那么需要弹框提示
	if ybCommentAnonymousUser.UserID <= 0 {
		//ybCommentAnonymousUser = &yb_comment_anonymous_user.YbCommentAnonymousUser{
		//	UserID:     userId,
		//	CreateTime: time.Now(),
		//}
		//err = ybCommentAnonymousUser.Create()
		err = yb_comment_anonymous_user.CreateBySql(userId, time.Now())
	}
	return
}

// HandleCommentByCommunityQuestionItemList 问答 评论 数据
func HandleCommentByCommunityQuestionItemList(userId uint64, questionList []*response.CommunityQuestionItem) (err error) {
	listLen := len(questionList)
	if listLen == 0 {
		return
	}
	idArr := make([]uint32, 0)

	// 问题ID-精选评论列表
	questionIdCommentsMap := make(map[uint32][]*response.CommunityQuestionCommentListItem, 0)

	for i := 0; i < listLen; i++ {
		idArr = append(idArr, uint32(questionList[i].CommunityQuestionID))
		questionIdCommentsMap[uint32(questionList[i].CommunityQuestionID)] = make([]*response.CommunityQuestionCommentListItem, 0)
	}

	// 精选评论数据
	hotList, err := yb_community_question_comment.GetHotListByCommunityQuestionIds(idArr, yb_community_question_comment.SourceQuestion)
	if err != nil {
		return
	}
	for _, v := range hotList {
		questionIdCommentsMap[v.CommunityQuestionID] = append(questionIdCommentsMap[v.CommunityQuestionID], &response.CommunityQuestionCommentListItem{
			QaAvatarUrl: v.QaAvatarUrl,
			Comment:     v.Content,
		})
	}

	for _, v := range questionList {
		comments := questionIdCommentsMap[uint32(v.CommunityQuestionID)]
		v.CommentTotal = len(comments)
		v.CommentList = comments
	}

	return
}

// messageToAdmin 添加站内消息
func messageToAdmin(wxUser user.UserInfo, communityQuestionComment *yb_community_question_comment.YbCommunityQuestionComment) {
	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, wxUser, communityQuestionComment)
	//微信模板消息(2022-0823评论后不再通知管理员)
	//go wxMessageToAdmin(*vWangInfo, communityQuestionComment)

	return
}

// systemMessageToAdmin 系统消息消息通知管理员
func systemMessageToAdmin(adminInfo admin.Admin, wxUser user.UserInfo, communityQuestionComment *yb_community_question_comment.YbCommunityQuestionComment) {
	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)

	var msgType, sourceType, approvalStatus int8
	var remark, content, msgContent, extra, messageSource string
	msgType = company_approval_message.CompanyApprovalMessageMessageTypeByApply

	// 消息来源: 6-问答社区; 7-视频社区; 8-线上路演;
	switch communityQuestionComment.Source {
	case 1:
		sourceType = company_approval_message.CompanyApprovalMessageSourceTypeByQuestionComment
		remark = `您有新的问答评论待查阅`
		content = `您有新的问答评论待查阅`
		messageSource = `问答社区`

		// 获取评论对应的问答/视频信息
		communityQuestion, e := yb_community_question.GetItemById(int(communityQuestionComment.CommunityQuestionID))
		if e != nil {
			err = errors.New("获取评论对应的问答失败,err：" + e.Error())
			return
		}
		msgContent = communityQuestion.QuestionContent
	case 2:
		sourceType = company_approval_message.CompanyApprovalMessageSourceTypeByVideoComment
		remark = `您有新的视频评论待查阅`
		content = `您有新的视频评论待查阅`
		messageSource = `视频社区`

		communityVideo, e := yb_community_video.GetItemById(int(communityQuestionComment.CommunityQuestionID))
		if e != nil {
			err = errors.New("获取评论对应的视频失败,err：" + e.Error())
			return
		}
		msgContent = communityVideo.Title
		extra = communityVideo.VarietyTagName
	case 3:
		sourceType = company_approval_message.CompanyApprovalMessageSourceTypeByRoadVideoComment
		remark = `您有新的线上路演评论待查阅`
		content = `您有新的线上路演评论待查阅`
		messageSource = `线上路演`

		communityVideo, e := yb_road_video.GetItemById(int(communityQuestionComment.CommunityQuestionID))
		if e != nil {
			err = errors.New("获取评论对应的路演视频失败,err：" + e.Error())
			return
		}
		msgContent = communityVideo.Title
		// 路演视频品种
		if communityVideo.ChartPermissionIds != "" {
			cpIds := utils.JoinStr2IntArr(strings.ReplaceAll(communityVideo.ChartPermissionIds, `'`, ``), ",")
			if len(cpIds) > 0 {
				cpList, e := chart_permission.GetListByIds(cpIds)
				if e != nil {
					err = errors.New("获取路演视频品种失败, Err: " + e.Error())
					return
				}
				cpArr := make([]string, 0)
				for i := range cpList {
					cpArr = append(cpArr, cpList[i].PermissionName)
				}
				extra = strings.Join(cpArr, ",")
			}
		}
	default:
		return
	}

	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

	messageInfo := company_approval_message.MessageInfo{
		CompanyName:          companyInfo.CompanyName,
		ProductId:            productId,
		CompanyProductStatus: companyProductInfo.Status,
		Title:                communityQuestionComment.Content,
		Content:              msgContent,
		UserId:               wxUser.UserID,
		UserName:             communityQuestionComment.RealName,
		CreateTime:           communityQuestionComment.CreateTime,
		Extra:                extra,         // 附加字段
		MessageSource:        messageSource, // 消息来源
	}
	//客户添加消息
	err = company_approval_message.AddCompanyApprovalMessage(utils.AdminId, receiveUserId, int(wxUser.CompanyID), int(communityQuestionComment.CommunityQuestionCommentID), msgType, sourceType, approvalStatus, companyName, remark, content, messageInfo)
	return
}

// wxMessageToAdmin 微信模板消息通知管理员
func wxMessageToAdmin(adminInfo admin.Admin, communityQuestionComment *yb_community_question_comment.YbCommunityQuestionComment) {
	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.SendQuestionCommentToAdmin(int(communityQuestionComment.CommunityQuestionCommentID), int(adminInfo.AdminID), adminInfo.OpenId, communityQuestionComment.Content)
	return
}

// 删除评论后的逻辑处理
func afterDelete(communityQuestionComment *yb_community_question_comment.YbCommunityQuestionComment) {
	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)
		}
	}()

	sourceType := 0
	switch communityQuestionComment.Source {
	case 1:
		sourceType = company_approval_message.CompanyApprovalMessageSourceTypeByQuestionComment
	case 2:
		sourceType = company_approval_message.CompanyApprovalMessageSourceTypeByVideoComment
	case 3:
		sourceType = company_approval_message.CompanyApprovalMessageSourceTypeByRoadVideoComment
	default:
		err = errors.New("sourceType有误")
		return
	}
	err = company_approval_message.CancelCompanyApprovalMessage(int(communityQuestionComment.CommunityQuestionCommentID), int8(sourceType))
	return
}
