package yb

import (
	"errors"
	"fmt"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/models/company"
	"hongze/hz_crm_api/models/system"
	"hongze/hz_crm_api/models/yb"
	"hongze/hz_crm_api/models/yb/response"
	"hongze/hz_crm_api/services"
	"hongze/hz_crm_api/services/alarm_msg"
	"hongze/hz_crm_api/utils"
	"strconv"
	"strings"
	"time"
)

// GetQuestionList 问题列表
func GetQuestionList(condition string, pars []interface{}, orderStr string, startSize, pageSize int) (total int, resp *response.CommunityQuestionListResp, err error) {
	resp = new(response.CommunityQuestionListResp)
	total, list, e := yb.GetCommunityQuestionList(condition, pars, orderStr, startSize, pageSize)
	if e != nil {
		err = errors.New("获取问题列表失败 Err:" + e.Error())
		return
	}
	if len(list) == 0 {
		return
	}
	// 判断是否存在已禁用的回复人, 需要重新分配回复人
	adminIdArr := make([]string, 0)
	questionLen := len(list)
	userIdArr := make([]string, 0)
	for i := 0; i < questionLen; i++ {
		if list[i].ReplierAdminId > 0 {
			adminIdArr = append(adminIdArr, strconv.Itoa(list[i].ReplierAdminId))
		}
		userIdArr = append(userIdArr, strconv.Itoa(list[i].UserId))
	}
	adminIds := strings.Join(adminIdArr, ",")
	adminList, e := system.GetSysAdminByIds(adminIds)
	adminLen := len(adminList)
	adminEnableMap := make(map[int]int, 0)
	if adminLen > 0 {
		for i := 0; i < adminLen; i++ {
			adminEnableMap[adminList[i].AdminId] = adminList[i].Enabled
		}
	}

	// 是否有提问人详情(可能存在提问人被删除的情况,无详情)
	userDetailMap := make(map[int]bool, 0)
	if len(userIdArr) > 0 {
		userIdStr := strings.Join(userIdArr, ",")
		userList, e := company.GetFiccCompanyUserByUserIds(userIdStr)
		if e != nil {
			err = errors.New("获取提问人列表信息失败, Err:" + e.Error())
			return
		}
		for i := range userList {
			userDetailMap[int(userList[i].UserId)] = true
		}
	}

	respList := make([]*response.CommunityQuestionItem, 0)
	for _, v := range list {
		// 根据回复人被禁用/待回答/已推送消息判断是否需要重新分配
		needReset := false
		adminEnable := 1
		if v.ReplierAdminId > 0 {
			adminEnable = adminEnableMap[v.ReplierAdminId]
		}
		if adminEnable == 0 && v.ReplyStatus == 2 && v.MsgSendStatus >= 1 {
			needReset = true
		}
		item := &response.CommunityQuestionItem{
			CommunityQuestionId:     v.CommunityQuestionId,
			UserId:                  v.UserId,
			Mobile:                  v.Mobile,
			RealName:                v.RealName,
			QuestionContent:         v.QuestionContent,
			ReplierUserId:           v.ReplierUserId,
			ReplierAdminId:          v.ReplierAdminId,
			ReplierRealName:         v.ReplierRealName,
			ReplierAvatar:           v.ReplierAvatar,
			ResearchGroupFirstId:    v.ResearchGroupFirstId,
			ResearchGroupSecondId:   v.ResearchGroupSecondId,
			ResearchGroupFirstName:  v.ResearchGroupFirstName,
			ResearchGroupSecondName: v.ResearchGroupSecondName,
			ReplyStatus:             v.ReplyStatus,
			MsgSendStatus:           v.MsgSendStatus,
			NeedRedistribute:        needReset,
			CreateTime:              v.CreateTime.Format(utils.FormatDateTime),
			ReplyTime:               v.ReplyTime.Format(utils.FormatDateTime),
			ClickNum:                v.ClickNum,
			UserQaCount:             v.UserQaCount,
			UserHasDetail:           userDetailMap[v.UserId],
			StopReason:              v.StopReason,
		}
		respList = append(respList, item)
	}
	// 数量统计
	countList, e := yb.GetCommunityQuestionCount()
	if e != nil {
		err = errors.New("获取问题数量统计失败 Err:" + e.Error())
		return
	}
	respCount := new(response.CommunityQuestionCount)
	for _, v := range countList {
		if v.ReplyStatus == 1 {
			respCount.Free = v.Total
			continue
		}
		if v.ReplyStatus == 2 {
			respCount.Wait = v.Total
			continue
		}
		if v.ReplyStatus == 3 {
			respCount.Replied = v.Total
			continue
		}
	}
	respCount.Total = respCount.Free + respCount.Wait + respCount.Replied
	resp.List = respList
	resp.Count = respCount
	return
}

func GetQuestionClickLogList(questionId, startSize, pageSize int) (pageTotal int64, resp *response.QuestionClickLogListResp, err error) {
	questionInfo, e := yb.GetQuestionById(questionId)
	if e != nil {
		err = errors.New("提问信息有误 Err:" + e.Error())
		return
	}
	resp = new(response.QuestionClickLogListResp)
	list, e := yb.GetAudioLogListByQuestionId(questionId, startSize, pageSize)
	if e != nil {
		err = errors.New("获取问题列表失败 Err:" + e.Error())
		return
	}
	pageTotal, err = yb.GetAudioLogListTotalByQuestionId(questionId)
	if err != nil {
		err = errors.New("查询该提问列表总点击量失败 Err:" + err.Error())
		return
	}

	count, err := yb.GetAudioLogTotalByQuestionId(questionId)
	if err != nil {
		err = errors.New("查询该提问总点击量失败 Err:" + err.Error())
		return
	}
	resp.Count = int(count)
	resp.QuestionContent = questionInfo.QuestionContent

	if len(list) == 0 {
		return
	}
	userIds := ""
	for _, v := range list {
		userIds += ", " + (strconv.Itoa(v.UserId))
	}
	companyUsersMap := make(map[int]*company.CompanyUser)
	if userIds != "" {
		userIds = strings.Trim(userIds, ",")
		//查询用户相关的客户信息
		companyUserList, tErr := company.GetFiccCompanyUserByUserIds(userIds)
		if tErr != nil {
			err = errors.New("获取客户信息失败 Err:" + tErr.Error())
			return
		}
		for _, v := range companyUserList {
			companyUsersMap[int(v.UserId)] = v
		}
	}
	respList := make([]*response.QuestionClickLogListItem, 0)
	for _, v := range list {
		tmp := new(response.QuestionClickLogListItem)
		tmp.UserId = v.UserId
		tmp.ClickNum = v.ClickNum
		tmp.LastCreateTime = v.LastCreateTime
		tmp.SourceAgent = v.NewSourceAgent
		if u, ok := companyUsersMap[v.UserId]; ok {
			tmp.RealName = u.RealName
			tmp.CompanyName = u.CompanyName
			tmp.CompanyStatus = u.Status
			tmp.CompanyId = u.CompanyId
		}
		respList = append(respList, tmp)
	}

	resp.List = respList

	return
}

// GetQuestionCompanyUser 获取提问者详情
func GetQuestionCompanyUser(questionId int) (ret *response.QuestionCompanyUser, err error) {
	questionInfo, e := yb.GetQuestionById(questionId)
	if e != nil {
		err = errors.New("提问信息有误 Err:" + e.Error())
		return
	}
	companyUserList, err := company.GetFiccCompanyUserByUserIds(strconv.Itoa(questionInfo.UserId))
	if err != nil {
		err = errors.New("获取客户信息失败 Err:" + err.Error())
		return
	}
	if len(companyUserList) > 0 {
		item := companyUserList[0]
		ret = &response.QuestionCompanyUser{
			UserId:              int(item.UserId),
			CompanyStatus:       item.Status,
			CompanyName:         item.CompanyName,
			RealName:            item.RealName,
			CompanyId:           item.CompanyId,
			QuestionContent:     questionInfo.QuestionContent,
			CommunityQuestionId: questionInfo.CommunityQuestionId,
			SellerName:          item.SellerName,
		}
	} else {
		err = errors.New("用户不存在")
		return
	}
	return
}

// DistributeQuestion 分配回复人
func DistributeQuestion(questionId, adminId, researchGroupFirstId, researchGroupSecondId, distributeId int) (errMsg string, err error) {
	errMsg = "操作成功"
	// 校验提问信息
	item, e := yb.GetQuestionById(questionId)
	if e != nil {
		errMsg = "分配失败, 提问信息有误"
		err = errors.New("提问信息有误 Err:" + e.Error())
		return
	}
	contentRune := []rune(item.QuestionContent)
	if len(contentRune) > 28 {
		errMsg = "问题字数不可超过28个字符"
		err = errors.New("问题字数不可超过28个字符")
		return
	}
	if item.ReplyStatus == 3 {
		errMsg = "分配失败, 回复状态有误"
		err = errors.New(fmt.Sprintf("分配失败, 回复状态有误, ReplyStatus:%d", item.ReplyStatus))
		return
	}
	// 获取研究员信息
	adminInfo, e := system.GetSysAdminById(adminId)
	if e != nil {
		errMsg = "分配失败, 研究员信息有误"
		err = errors.New("研究员信息有误 Err:" + e.Error())
		return
	}
	if adminInfo.Mobile == "" {
		errMsg = "分配失败, 研究员手机号有误"
		err = errors.New("研究员手机号为空")
		return
	}
	if adminInfo.OpenId == "" {
		errMsg = "该研究员未关注公众号，无法收到消息通知"
		err = errors.New("该研究员未关注公众号，无法收到消息通知")
		return
	}
	// 获取研究员关联的联系人信息
	companyId := 16
	userInfo, e := models.GetWxUserByCompanyIdAndMobile(companyId, adminInfo.Mobile)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			errMsg = "分配失败, 未找到研究员手机号对应的联系人信息"
			err = errors.New("未获取到相关联系人信息")
			return
		}
		errMsg = "分配失败"
		err = errors.New("获取手机号所属联系人失败, Err:" + e.Error())
		return
	}
	// 回复人openid, 此处可能会出现取不到openid的情况, 可直接忽略掉
	replierUserId := int(userInfo.UserId)

	replierOpenid := ""

	// 研究员研究方向分组-研报10.0替换成标签库
	//firstGroup, e := system.GetResearchGroupById(researchGroupFirstId)
	firstGroup, e := models.GetVarietyClassifyById(researchGroupFirstId)
	if e != nil {
		errMsg = "分配失败, 一级分组信息有误"
		err = errors.New("获取一级分组信息失败, Err:" + e.Error())
		return
	}
	//secondGroup, e := system.GetResearchGroupById(researchGroupSecondId)
	secondGroup, e := models.GetVarietyTagById(researchGroupSecondId)
	if e != nil {
		errMsg = "分配失败, 二级分组信息有误"
		err = errors.New("获取二级分组信息失败, Err:" + e.Error())
		return
	}
	// 更新提问信息
	updateCols := make([]string, 0)
	updateCols = append(updateCols, "ReplierUserId", "ReplierOpenid", "ReplierAdminId", "ReplierRealName", "ReplierAvatar",
		"ResearchGroupFirstId", "ResearchGroupSecondId", "ResearchGroupFirstName", "ResearchGroupSecondName", "VarietyTagId", "VarietyTagName",
		"DistributeAdminId", "DistributeTime", "ReplyStatus", "ReplierIsRead", "MsgSendStatus", "ModifyTime")
	item.ReplierUserId = replierUserId
	item.ReplierOpenid = replierOpenid
	item.ReplierAdminId = adminId
	item.ReplierRealName = adminInfo.RealName
	item.ReplierAvatar = adminInfo.AdminAvatar
	item.ResearchGroupFirstId = researchGroupFirstId
	item.ResearchGroupSecondId = researchGroupSecondId
	item.ResearchGroupFirstName = firstGroup.ClassifyName
	item.ResearchGroupSecondName = secondGroup.TagName
	item.VarietyTagId = secondGroup.VarietyTagId
	item.VarietyTagName = secondGroup.TagName
	item.DistributeAdminId = distributeId
	item.DistributeTime = time.Now().Local()
	item.ReplyStatus = 2
	item.ReplierIsRead = 0
	item.MsgSendStatus = 0
	item.ModifyTime = time.Now().Local()
	if e := item.Update(updateCols); e != nil {
		errMsg = "分配失败，更新提问信息失败"
		err = errors.New("更新提问信息失败, Err:" + e.Error())
	}
	return
}

// SoftDeleteQuestion 删除问题
func SoftDeleteQuestion(questionId int) (err error) {
	if _, e := yb.GetQuestionById(questionId); e != nil {
		err = errors.New("提问信息有误 Err:" + e.Error())
		return
	}
	if e := yb.DeleteQuestion(questionId); e != nil {
		err = errors.New("删除提问失败 Err:" + e.Error())
	}

	// 删除问答后的逻辑处理
	go afterDeleteQuestion(questionId)
	return
}

// SendMsgToReplier 推送消息给回复人
func SendMsgToReplier(questionId int) (errMsg string, err error) {
	errMsg = "推送成功"
	item, e := yb.GetQuestionById(questionId)
	if e != nil {
		errMsg = "问答信息有误"
		err = errors.New("提问信息有误, Err:" + e.Error())
		return
	}
	if item.MsgSendStatus >= 1 {
		return
	}
	if item.ReplierUserId == 0 {
		errMsg = "请先分配回复人"
		err = errors.New("未分配回复人, 不可推送")
		return
	}
	// 回复人openid为空时查询当前是否已有openid
	updateCols := make([]string, 0)
	// 找到研究员的手机号，并查到管理员绑定的账号，找到对应的openid
	adminInfo, e := system.GetSysAdminById(item.ReplierAdminId)
	if e != nil {
		errMsg = "发送失败, 研究员账号查询失败"
		err = errors.New("发送失败, 研究员账号查询失败, Err:" + e.Error())
		return
	}
	if adminInfo.OpenId == "" {
		errMsg = "该研究员未关注公众号，无法发送消息通知"
		err = errors.New("回复人openid为空, 不可推送")
		return
	}

	// 推送消息
	if e := services.SendYbQuestionDistributeWxMsg(item.CommunityQuestionId, adminInfo.AdminId, adminInfo.OpenId, item.QuestionContent, ""); e != nil {
		err = errors.New("推送模板消息失败, Err:" + e.Error())
		return
	}
	// 更新问答信息
	updateCols = append(updateCols, "ModifyTime", "MsgSendStatus")
	item.ModifyTime = time.Now().Local()
	item.MsgSendStatus = 1
	if e := item.Update(updateCols); e != nil {
		err = errors.New("更新问答信息失败, Err:" + e.Error())
	}
	return
}

// EditQuestion 编辑问题
func EditQuestion(questionId int, content string) (errMsg string, err error) {
	item, e := yb.GetQuestionById(questionId)
	if e != nil {
		errMsg = "提问信息有误"
		err = errors.New("提问信息有误 Err:" + e.Error())
		return
	}
	if item.MsgSendStatus >= 1 {
		errMsg = "问题状态有误，不可编辑"
		err = errors.New(fmt.Sprintf("问题状态不可编辑, MsgSendStatus:%d", item.MsgSendStatus))
		return
	}
	updateCols := make([]string, 0)
	updateCols = append(updateCols, "QuestionContent", "ModifyTime")
	item.QuestionContent = content
	item.ModifyTime = time.Now().Local()
	if e := item.Update(updateCols); e != nil {
		errMsg = "更新提问信息失败"
		err = errors.New("更新提问信息失败, Err:" + e.Error())
	}
	return
}

// CheckCommunityQuestionPermission 查询当前操作用户是否运营管理员权限
func CheckCommunityQuestionPermission(adminId int) (errMsg string, err error) {
	roleInfo, e := system.GetSysRoleByRoleTypeCode("yb_question_admin")
	if e != nil {
		errMsg = "角色信息有误"
		if e.Error() == utils.ErrNoRow() {
			err = errors.New("角色不存在, Err: " + e.Error())
			return
		}
		err = errors.New("角色信息有误, Err: " + e.Error())
		return
	}
	_, e = system.GetRoleIdsByAdminIdRoleId(adminId, roleInfo.RoleId)
	if e != nil {
		errMsg = "无权操作"
		err = errors.New("无权操作, Err: " + e.Error())
		return
	}
	return
}

// afterDeleteQuestion 删除问答后的逻辑处理
func afterDeleteQuestion(questionId int) {
	var err error
	defer func() {
		if err != nil {
			go alarm_msg.SendAlarmMsg("问答信息删除后，标记站内消息失败"+time.Now().Format(utils.FormatDateTime)+";Err:"+err.Error(), 3)
		}
	}()
	err = company.CancelCompanyApprovalMessage(questionId, services.CompanyApprovalMessageSourceTypeByQuestion)
	return
}

// TransferQuestion 转移问题并通知
func TransferQuestion(questionId, adminId, researchGroupFirstId, researchGroupSecondId, distributeId int, distributeName string) (errMsg string, err error) {
	errMsg = "操作失败"
	// 校验提问信息
	item, e := yb.GetQuestionById(questionId)
	if e != nil {
		errMsg = "转移失败, 提问信息有误"
		err = errors.New("提问信息有误 Err:" + e.Error())
		return
	}
	if item.ReplyStatus != yb.ReplyStatusWait {
		errMsg = "当前状态不可转移"
		err = errors.New("回复状态有误")
		return
	}

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

	// 获取研究员信息失败
	researcher, e := system.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", "DistributeAdminId", "DistributeTime", "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.DistributeAdminId = distributeId
	item.DistributeTime = nowTime
	item.ModifyTime = nowTime
	if e = item.Update(updateCols); e != nil {
		err = errors.New("更新问答失败 Err:" + e.Error())
		return
	}

	// 新增问答流程
	go func() {
		pro := new(yb.CommunityQuestionProcess)
		pro.CommunityQuestionId = item.CommunityQuestionId
		pro.TransferUserId = 0
		pro.TransferAdminId = distributeId
		pro.TransferAdminName = distributeName
		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转至%s", distributeName, researcher.AdminName)
		pro.ProcessType = yb.ProcessTypeTransfer
		pro.CreateTime = nowTime
		if e = pro.Create(); e != nil {
			return
		}
	}()

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