package services

import (
	"encoding/json"
	"errors"
	"fmt"
	"hongze/hongze_yb/global"
	"hongze/hongze_yb/models/response"
	admin2 "hongze/hongze_yb/models/tables/admin"
	"hongze/hongze_yb/models/tables/company_product"
	"hongze/hongze_yb/models/tables/sys_role_admin"
	"hongze/hongze_yb/models/tables/voice_broadcast"
	"hongze/hongze_yb/models/tables/voice_broadcast_img"
	"hongze/hongze_yb/models/tables/voice_broadcast_statistics"
	"hongze/hongze_yb/models/tables/voice_section"
	"hongze/hongze_yb/services/user"
	"hongze/hongze_yb/services/wechat"
	"hongze/hongze_yb/utils"
	"strings"
	"time"
)

// GetVoiceBroadcastList 获取语音播报列表
func GetVoiceBroadcastList(pageIndex, pageSize, sectionId, broadcastId, authorId, mineStatus int, userInfo user.UserInfo) (resp []response.Broadcast, err error) {
	condition := ` 1=1`
	var pars []interface{}
	// 分享进来的指定语音播报
	if broadcastId > 0 {
		condition += ` AND broadcast_id = ? AND publish_state = 1`
		pars = append(pars, broadcastId)
	} else {
		// 我的-非我的只能看到已发布
		if authorId > 0 {
			condition += ` AND author_id = ?`
			pars = append(pars, authorId)
			// 我的语音播报状态: 0-未发布 1-已发布 2-全部
			if mineStatus != 2 {
				condition += ` AND publish_state = ?`
				pars = append(pars, mineStatus)
			}
		} else {
			condition += ` AND publish_state = 1`
		}
		// 板块
		if sectionId > 0 {
			condition += ` AND section_id = ?`
			pars = append(pars, sectionId)
		}
	}
	voiceList, e := voice_broadcast.GetPageListByCondition(condition, pars, pageIndex, pageSize)
	if e != nil {
		err = errors.New("获取语音播报列表失败, Err: " + e.Error())
		return
	}
	listLen := len(voiceList)
	if listLen == 0 {
		return
	}
	// 图片
	voiceIds := make([]int, 0)
	for i := 0; i < listLen; i++ {
		voiceIds = append(voiceIds, voiceList[i].BroadcastId)
	}
	imgList, e := voice_broadcast_img.GetVoiceImgListByVoiceIds(voiceIds)
	if e != nil {
		err = errors.New("获取语音播报列表图片失败, Err: " + e.Error())
		return
	}
	imgMap := make(map[int][]*voice_broadcast_img.YbVoiceBroadcastImg, 0)
	imgListLen := len(imgList)
	for i := 0; i < imgListLen; i++ {
		imgMap[imgList[i].BroadcastId] = append(imgMap[imgList[i].BroadcastId], imgList[i])
	}
	// 响应数据
	for i := 0; i < listLen; i++ {
		r, e := handleBroadcastItem(userInfo, voiceList[i], imgMap[voiceList[i].BroadcastId])
		if e != nil {
			err = errors.New("语音播报响应数据处理失败, Err: " + e.Error())
			return
		}
		resp = append(resp, r)
	}
	return
}

// GetVoiceAdminByUserInfo 判断当前用户是否为语音管理员
func GetVoiceAdminByUserInfo(userInfo user.UserInfo) (ok bool, adminInfo *admin2.Admin, err error) {
	mobile := userInfo.Mobile
	var email string
	if mobile == "" {
		// 用户有可能是通过邮箱登录
		email = userInfo.Email
		if email == "" {
			return
		}
	}

	if userInfo.CompanyID != 16 {
		return
	}
	if mobile != "" {
		adminInfo, err = admin2.GetAdminByMobile(mobile)
		if err != nil {
			if err == utils.ErrNoRow {
				err = nil
				return
			}
			return
		}
	} else {
		adminInfo, err = admin2.GetAdminByEmail(email)
		if err != nil {
			if err == utils.ErrNoRow {
				err = nil
				return
			}
			return
		}
	}

	if adminInfo.Enabled != 1 {
		return
	}
	_, err = sys_role_admin.GetVoiceAdmin(int(adminInfo.AdminID))
	if err != nil && err != utils.ErrNoRow {
		return
	}

	if err == utils.ErrNoRow {
		ok = false
		return
	}
	ok = true

	return
}

func AddBroadcastRecord(userinfo user.UserInfo, source, broadcastId int) (newId int, err error) {
	defer func() {
		if err != nil {
			global.LOG.Critical(fmt.Sprintf("AddBroadcastLog: userId=%d, err:%s", userinfo.UserID, err.Error()))
		}
	}()
	companyProduct, err := company_product.GetByCompany2ProductId(userinfo.CompanyID, 1)
	if err != nil {
		return
	}
	broadcast, err := voice_broadcast.GetBroadcastById(broadcastId)
	if err != nil {
		return
	}
	voiceBroadcastStatistics := voice_broadcast_statistics.VoiceBroadcastStatistics{
		CompanyId:     companyProduct.CompanyID,
		CompanyName:   companyProduct.CompanyName,
		UserId:        int(userinfo.UserID),
		RealName:      userinfo.RealName,
		Mobile:        userinfo.Mobile,
		Email:         userinfo.Email,
		CompanyStatus: companyProduct.Status,
		SellerId:      companyProduct.SellerID,
		Source:        source,
		BroadcastId:   broadcastId,
		BroadcastName: broadcast.BroadcastName,
		SectionId:     broadcast.SectionId,
		SectionName:   broadcast.SectionName,
		VarietyId:     broadcast.VarietyId,
		VarietyName:   broadcast.VarietyName,
		AuthorId:      broadcast.AuthorId,
		Author:        broadcast.Author,
		PublishTime:   broadcast.PublishTime,
		CreateTime:    time.Now().Format(utils.FormatDateTime),
	}
	err = voiceBroadcastStatistics.AddBroadcastStatistics()
	if err != nil {
		return
	}
	newId = voiceBroadcastStatistics.Id
	return
}

// SendBroadcastMsg 推送语音播报消息
func SendBroadcastMsg(broadcastId, userId int) (errMsg string, err error) {
	broadcast, e := voice_broadcast.GetBroadcastById(broadcastId)
	if e != nil {
		errMsg = "推送失败, 语音播报信息有误"
		err = errors.New("获取语音播报信息失败, Err: " + e.Error())
		return
	}
	if broadcast.PublishState != 1 {
		errMsg = "报告未发布, 不可推送"
		err = errors.New("报告未发布, 不可推送")
		return
	}
	if broadcast.AuthorId != userId {
		errMsg = "仅语音播报创建人可推送"
		err = errors.New("仅语音播报创建人可推送")
		return
	}
	if broadcast.MsgState != 0 {
		errMsg = "请勿重复推送"
		err = errors.New("请勿重复推送")
		return
	}
	// 更新语音播报信息
	updateCols := []string{"MsgState", "MsgTime"}
	broadcast.MsgState = 1
	broadcast.MsgTime = time.Now().Format(utils.FormatDateTime)
	if e = broadcast.Update(updateCols); e != nil {
		errMsg = "更新语音播报失败"
		err = errors.New("更新语音播报失败")
		return
	}
	// 推送模板消息
	go func() {
		_ = wechat.SendVoiceBroadcastWxMsg(broadcast.BroadcastId, broadcast.VarietyId, broadcast.SectionName, broadcast.BroadcastName)
	}()
	// 推送客群消息
	//go func() {
	//	_ = SendVoiceBroadcastToThs(broadcast)
	//}()
	return
}

// CreateVoiceBroadcast 新增语音播报
func CreateVoiceBroadcast(sectionId, varietyId, authorId int, broadcastName, sectionName, varietyName, author, voiceSeconds, voiceSize, voiceUrl, imgs, centralArguments string, userInfo user.UserInfo) (resp response.Broadcast, err error) {
	nowTime := time.Now().Local()
	if userInfo.UserID > 0 {
		authorId = int(userInfo.UserID)
		author = userInfo.RealName
	}

	item := &voice_broadcast.VoiceBroadcast{
		BroadcastName:    broadcastName,
		SectionId:        sectionId,
		SectionName:      sectionName,
		VarietyId:        varietyId,
		VarietyName:      varietyName,
		AuthorId:         authorId,
		Author:           author,
		VoiceUrl:         voiceUrl,
		VoicePlaySeconds: voiceSeconds,
		VoiceSize:        voiceSize,
		CentralArguments: centralArguments,
		CreateTime:       nowTime.Format(utils.FormatDateTime),
		ModifyTime:       nowTime.Format(utils.FormatDateTime),
	}
	// 图片
	imgList := make([]*voice_broadcast_img.YbVoiceBroadcastImg, 0)
	if imgs != "" {
		imgArr := strings.Split(imgs, ",")
		imgLen := len(imgArr)
		for i := 0; i < imgLen; i++ {
			if imgArr[i] == "" {
				continue
			}
			imgList = append(imgList, &voice_broadcast_img.YbVoiceBroadcastImg{
				BroadcastId: item.BroadcastId,
				ImgUrl:      imgArr[i],
				CreateTime:  nowTime,
			})
		}
	}
	if e := voice_broadcast.CreateVoiceBroadcastAndImgs(item, imgList); e != nil {
		err = errors.New("新增语音播报及图片失败, Err: " + e.Error())
		return
	}
	respItem, e := handleBroadcastItem(userInfo, item, imgList)
	if e != nil {
		err = errors.New("语音播报响应数据处理失败, Err: " + e.Error())
		return
	}
	resp = respItem
	return
}

// EditVoiceBroadcast 编辑语音播报
func EditVoiceBroadcast(broadcastId, sectionId, varietyId, authorId int, broadcastName, sectionName, varietyName, author, voiceSeconds, voiceSize, voiceUrl, imgs, centralArguments string, userInfo user.UserInfo) (resp response.Broadcast, err error) {
	if broadcastId <= 0 {
		return
	}
	item, e := voice_broadcast.GetBroadcastById(broadcastId)
	if e != nil {
		err = errors.New("语音播报信息有误")
		return
	}
	nowTime := time.Now().Local()
	updateCols := []string{"BroadcastName", "SectionId", "SectionName", "VarietyId", "VarietyName", "AuthorId", "Author", "VoiceUrl",
		"VoicePlaySeconds", "VoiceSize", "ModifyTime", "CentralArguments"}
	item.BroadcastName = broadcastName
	item.SectionId = sectionId
	item.SectionName = sectionName
	item.VarietyId = varietyId
	item.VarietyName = varietyName
	item.AuthorId = authorId
	item.Author = author
	item.VoiceUrl = voiceUrl
	item.VoicePlaySeconds = voiceSeconds
	item.VoiceSize = voiceSize
	item.ModifyTime = nowTime.Format(utils.FormatDateTime)
	item.CentralArguments = centralArguments
	// 图片
	imgList := make([]*voice_broadcast_img.YbVoiceBroadcastImg, 0)
	if imgs != "" {
		imgArr := strings.Split(imgs, ",")
		imgLen := len(imgArr)
		for i := 0; i < imgLen; i++ {
			if imgArr[i] == "" {
				continue
			}
			imgList = append(imgList, &voice_broadcast_img.YbVoiceBroadcastImg{
				BroadcastId: item.BroadcastId,
				ImgUrl:      imgArr[i],
				CreateTime:  nowTime,
			})
		}
	}
	if e := voice_broadcast.UpdateVoiceBroadcastAndImgs(item, updateCols, imgList); e != nil {
		err = errors.New("更新语音播报及图片失败, Err: " + e.Error())
		return
	}
	resp, e = handleBroadcastItem(userInfo, item, imgList)
	if e != nil {
		err = errors.New("语音播报响应数据处理失败, Err: " + e.Error())
		return
	}
	return
}

// PublishVoiceBroadcast 发布语音播报
func PublishVoiceBroadcast(broadcastId, publishType int, prePublishTime string) (err error) {
	item, e := voice_broadcast.GetBroadcastById(broadcastId)
	if e != nil {
		err = errors.New("语音播报信息有误")
		return
	}
	if item.PublishState == 1 {
		err = errors.New("不可重复发布")
		return
	}
	// publishType: 0-仅发布 1-发布并推送 2-定时发布; 发布类型为定时发送时, 分享图时间取预发布时间
	updateCols := []string{"ImgUrl", "PublishState", "PublishTime", "PrePublishTime", "ModifyTime"}
	publishTime := time.Now().Local()
	if publishType == 2 {
		item.PublishState = 0
		item.PrePublishTime = prePublishTime
		publishTime, e = time.ParseInLocation(utils.FormatDateTime, prePublishTime, time.Local)
		if e != nil {
			err = errors.New("预发布时间有误, Err: " + e.Error())
			return
		}
	} else {
		// 非定时发布时重置预发布时间
		item.PublishState = 1
		item.PublishTime = publishTime.Format(utils.FormatDateTime)
		item.PrePublishTime = ""
	}
	// 分享背景图-取板块的图
	section, e := voice_section.GetVoiceSectionById(item.SectionId)
	if e != nil {
		err = errors.New("获取板块信息失败, Err: " + e.Error())
		return
	}
	shareTime := publishTime.Format(utils.FormatDate)
	shareImg, e := createVoiceBroadcastShareImg(section.ImgUrl, item.SectionName, shareTime)
	if e != nil {
		err = errors.New("生成分享图失败, Err: " + e.Error())
		return
	}
	item.ImgUrl = shareImg
	// 发布
	if e = item.Update(updateCols); e != nil {
		err = errors.New("发布语音播报失败, Err: " + e.Error())
		return
	}
	return
}

// VoiceBroadcastShareImgPars 语音播报分享图参数
type VoiceBroadcastShareImgPars struct {
	BackgroundImg string `json:"background_img"`
	Title         string `json:"title"`
	CreateTime    string `json:"create_time"`
}

// createVoiceBroadcastShareImg 生成动态分享图
func createVoiceBroadcastShareImg(baseImg, sectionName, createTime string) (shareImg string, err error) {
	pars := VoiceBroadcastShareImgPars{
		BackgroundImg: baseImg,
		Title:         sectionName,
		CreateTime:    createTime,
	}
	parsByte, e := json.Marshal(pars)
	if e != nil {
		err = e
		return
	}
	shareImg, e = GetDynamicShareImg(VoiceBroadcastShareImgSource, string(parsByte), 0, 0, "")
	if e != nil {
		err = e
		return
	}
	return
}

// GetVoiceBroadcastDetail 获取语音播报详情
func GetVoiceBroadcastDetail(broadcastId int, userInfo user.UserInfo) (detail response.Broadcast, err error) {
	item, e := voice_broadcast.GetBroadcastById(broadcastId)
	if e != nil {
		err = errors.New("获取语音播报详情失败, Err: " + e.Error())
		return
	}
	// 语音播报图片
	imgList, e := voice_broadcast_img.GetVoiceImgListByVoiceId(broadcastId)
	if e != nil {
		err = errors.New("获取语音播报图片失败, Err: " + e.Error())
		return
	}
	detail, e = handleBroadcastItem(userInfo, item, imgList)
	if e != nil {
		err = errors.New("语音播报响应数据处理失败, Err: " + e.Error())
		return
	}
	return
}

// handleBroadcastItem 语音播报响应数据处理
func handleBroadcastItem(userInfo user.UserInfo, item *voice_broadcast.VoiceBroadcast, imgs []*voice_broadcast_img.YbVoiceBroadcastImg) (resp response.Broadcast, err error) {
	if item == nil {
		return
	}
	resp.BroadcastId = item.BroadcastId
	resp.BroadcastName = item.BroadcastName
	resp.SectionId = item.SectionId
	resp.SectionName = item.SectionName
	resp.VarietyId = item.VarietyId
	resp.VarietyName = item.VarietyName
	resp.AuthorId = item.AuthorId
	resp.Author = item.Author
	resp.ImgUrl = item.ImgUrl
	resp.VoiceUrl = item.VoiceUrl
	resp.VoicePlaySeconds = item.VoicePlaySeconds
	resp.VoiceSize = item.VoiceSize
	resp.CreateTime = item.CreateTime
	resp.ModifyTime = item.ModifyTime
	resp.PublishState = item.PublishState
	resp.PublishTime = item.PublishTime
	resp.PrePublishTime = item.PrePublishTime
	// 是否为作者、是否可推送消息
	ok, _, err := user.GetAdminByUserInfo(userInfo)
	if err != nil {
		return
	}
	if int(userInfo.UserID) == item.AuthorId && ok {
		resp.IsAuthor = true
		if item.MsgState == 0 {
			resp.CouldSendMsg = true
		}
	}
	imgLen := len(imgs)
	imgArr := make([]string, 0)
	for i := 0; i < imgLen; i++ {
		imgArr = append(imgArr, imgs[i].ImgUrl)
	}
	resp.Imgs = imgArr
	resp.CentralArguments = item.CentralArguments
	return
}

// GetMyVoiceBroadcastListCount 获取我的语音播报列表计数
func GetMyVoiceBroadcastListCount(authorId, sectionId int) (resp response.BroadcastListStatusCount, err error) {
	condition := ` 1=1 `
	var pars []interface{}
	// 我的-非我的只能看到已发布
	if authorId > 0 {
		condition += ` AND author_id = ?`
		pars = append(pars, authorId)
	}
	// 板块
	if sectionId > 0 {
		condition += ` AND section_id = ?`
		pars = append(pars, sectionId)
	}
	counts, e := voice_broadcast.GetVoiceBroadcastListStatusCount(condition, pars)
	if e != nil {
		err = errors.New("获取语音播报列表计数失败, Err: " + e.Error())
		return
	}
	for _, v := range counts {
		if v.State == 0 {
			resp.Unpublished = v.Num
			continue
		}
		if v.State == 1 {
			resp.Published = v.Num
		}
	}
	resp.All = resp.Unpublished + resp.Published
	return
}
