package activity

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"hongze/hongze_yb/controller/response"
	"hongze/hongze_yb/models/tables/yb_activity"
	"hongze/hongze_yb/models/tables/yb_view_log"
	"hongze/hongze_yb/services/activity"
	"hongze/hongze_yb/services/user"
	"hongze/hongze_yb/services/view_log"
	"hongze/hongze_yb/utils"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
	"time"
)

// GetPageList 活动列表
// @Tags 活动模块
// @Summary  活动列表
// @Description 获取活动列表
// @Security ApiKeyAuth
// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
// @Accept  json
// @Product json
// @Param title query string false "活动类别/标题"
// @Param active_state query int false "活动状态 1-本周预告 2-进行中 3-已结束"
// @Param activity_type query int false "活动类型 1-线上会议 3-线下沙龙"
// @Param has_permission query int false "是否查看仅有权限的 0-否 1-是"
// @Param page query int false "当前页码"
// @Param limit query int false "每页数量"
// @Success 200 {object} []activity.ActivityList
// @failure 400 {string} string "活动获取失败"
// @Router /activity/getPageList [get]
func GetPageList(c *gin.Context) {
	page, _ := strconv.Atoi(c.Query("page"))
	limit, _ := strconv.Atoi(c.Query("limit"))
	userInfo := user.GetInfoByClaims(c)
	condition, pars, order := _handleListQuery(c, userInfo)
	listData, err := activity.PageList(condition, pars, page, limit, order, userInfo)
	if err != nil {
		response.Fail("活动获取失败", c)
		return
	}
	response.OkData("获取成功", listData, c)
}

func _handleListQuery(c *gin.Context, userInfo user.UserInfo) (string, []interface{}, string) {
	condition := "is_delete = 0 AND publish_status = 1"
	pars := make([]interface{}, 0)
	// 活动类别/标题
	reqTitle := c.DefaultQuery("title", "")
	if reqTitle != "" {
		condition += ` AND (activity_type_name LIKE ? OR activity_name LIKE ?)`
		pars = append(pars, "%" + reqTitle + "%")
		pars = append(pars, "%" + reqTitle + "%")
	}
	order := ""
	reqState := c.DefaultQuery("active_state", "0")
	if reqState != "0" {
		state, _ := strconv.Atoi(reqState)
		nowTime := time.Now().Format(utils.FormatDateTime)
		switch state {
		case 1:
			condition += ` AND start_time > ?`
			pars = append(pars, nowTime)
		case 2:
			condition += ` AND start_time <= ?`
			pars = append(pars, nowTime)
			condition += ` AND end_time > ?`
			pars = append(pars, nowTime)
		case 3:
			condition += ` AND end_time < ?`
			pars = append(pars, nowTime)
			order = "start_time desc"
		}
	}
	reqType := c.DefaultQuery("activity_type", "0")
	if reqType != "0" {
		activityTypeId, _ := strconv.Atoi(reqType)
		condition += ` AND first_activity_type_id = ?`
		pars = append(pars, activityTypeId)
	}
	// 是否仅查看有权限的
	reqHasPermission := c.DefaultQuery("has_permission", "0")
	if reqHasPermission != "0" {
		activityIds, _ := activity.GetUserAuthActivityIds(userInfo)
		condition += ` AND activity_id IN (?)`
		pars = append(pars, activityIds)
	}

	return condition, pars, order
}

// GetActivityDetail 获取活动详情
// @Tags 活动模块
// @Summary  获取活动详情
// @Description 获取活动详情
// @Security ApiKeyAuth
// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
// @Accept  json
// @Product json
// @Param activity_id query int true "活动ID"
// @Success 200 {object} yb_activity.ActivityDetail
// @failure 400 {string} string "获取失败"
// @Router /activity/getActivityDetail [get]
func GetActivityDetail(c *gin.Context) {
	reqActivityId := c.DefaultQuery("activity_id", "0")
	if reqActivityId == "0" {
		response.Fail("参数异常", c)
		return
	}
	activityId, _ := strconv.Atoi(reqActivityId)
	userInfo := user.GetInfoByClaims(c)
	ok, permissionCheckInfo, err := activity.CheckActivityPermission(userInfo, activityId)
	if !ok {
		response.AuthError(permissionCheckInfo, "暂无权限", c)
		return
	}
	data, err := activity.GetActivityDetail(activityId, int(userInfo.UserID))
	if err != nil {
		response.Fail("未找到记录", c)
		return
	}
	response.OkData("获取成功", data, c)
}

// GetActivityVoices 获取活动录音
// @Tags 活动模块
// @Summary  获取活动录音
// @Description 获取活动录音
// @Security ApiKeyAuth
// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
// @Accept  json
// @Product json
// @Param activity_id query int true "活动ID"
// @Success 200 {object} []yb_activity_voice.YbActivityVoice
// @failure 400 {string} string "获取失败"
// @Router /activity/getActivityVoices [get]
func GetActivityVoices(c *gin.Context) {
	reqActivityId := c.DefaultQuery("activity_id", "0")
	if reqActivityId == "0" {
		response.Fail("参数异常", c)
		return
	}
	activityId, _ := strconv.Atoi(reqActivityId)
	userInfo := user.GetInfoByClaims(c)
	ok, permissionCheckInfo, err := activity.CheckActivityPermission(userInfo, activityId)
	if !ok {
		response.AuthError(permissionCheckInfo, "暂无权限", c)
		return
	}
	listData, err := activity.GetVoicesByActivity(activityId)
	if err != nil {
		response.Fail("录音获取失败", c)
		return
	}
	response.OkData("获取成功", listData, c)
}

// GetActivityShareImg 生成活动分享图片
// @Tags 活动模块
// @Summary  生成活动分享图片
// @Description 生成活动分享图片
// @Security ApiKeyAuth
// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
// @Accept  json
// @Product json
// @Param activity_id query int true "活动ID"
// @Success 200 {string} string "获取成功"
// @failure 400 {string} string "获取失败"
// @Router /activity/getActivityShareImg [get]
func GetActivityShareImg(c *gin.Context)  {
	reqActivityId := c.DefaultQuery("activity_id", "0")
	activityId, _ := strconv.Atoi(reqActivityId)
	if activityId <= 0 {
		response.Fail("参数异常", c)
		return
	}
	activityInfo, err := yb_activity.GetDetailById(activityId)
	if err != nil {
		if err == utils.ErrNoRow {
			response.Fail("获取活动信息失败", c)
		}
		response.FailMsg("获取活动信息失败", "GetActivityShareImg: 获取活动信息失败" + err.Error(), c)
		return
	}
	if activityInfo == nil {
		response.FailMsg("获取活动信息失败", "GetActivityShareImg: 活动不存在", c)
		return
	}

	// 时间处理
	activityDate := activityInfo.StartTime.Format("2006-01-02")
	activityStart := activityInfo.StartTime.Format("15:04")
	activityEnd := activityInfo.EndTime.Format("15:04")
	activityWeek := activityInfo.StartTime.Weekday().String()
	var WeekDayMap = map[string]string{
		"Monday":    "星期一",
		"Tuesday":   "星期二",
		"Wednesday": "星期三",
		"Thursday":  "星期四",
		"Friday":    "星期五",
		"Saturday":  "星期六",
		"Sunday":    "星期日",
	}
	weekStr := WeekDayMap[activityWeek]
	dateStr := "会议时间：" + activityDate
	timeStr := activityStart + "-" + activityEnd + " " + weekStr

	// 获取原分享图
	originShareUrl := "static/img/report_share.png"
	if activityInfo.FirstActivityTypeID == 3 {
		originShareUrl = "static/img/report_share_sl.png"
	}
	fp, err := os.OpenFile(originShareUrl, os.O_CREATE|os.O_APPEND, 6)
	if err != nil {
		response.Fail("读取封面图失败", c)
		return
	}
	defer fp.Close()
	bytes, err := ioutil.ReadAll(fp)
	if err != nil {
		response.Fail("读取封面图失败", c)
		return
	}

	// 处理文字x轴y轴点
	drawText := activityInfo.ActivityTypeName
	fontSize := 42
	fontWidth := 50
	x, y, newSize, err := calcuDrawXandY(drawText, fontSize, 500, 400)
	if err != nil {
		response.Fail("生成新封面图失败", c)
		return
	}

	// 生成新分享图
	var drawInfo []*utils.DrawTextInfo
	text := &utils.DrawTextInfo{
		Text: drawText, X: x, Y: y - 50, FontSize: fontSize,
	}
	textDate := &utils.DrawTextInfo{
		Text: dateStr, X: 100, Y: y + 15, FontSize: 28,
	}
	textTime := &utils.DrawTextInfo{
		Text: timeStr, X: 120, Y: y + 75, FontSize: 28,
	}
	drawInfo = append(drawInfo, text, textDate, textTime)
	var colorRGBA = utils.FontRGBA{
		R: 255, G: 255, B: 255, A: 255,
	}
	picByte, err := utils.DrawStringRowsOnImage(bytes, drawInfo, colorRGBA, float64(newSize), fontWidth)
	if err != nil {
		response.Fail("生成新封面图失败", c)
		return
	}

	c.Header("Content-Type", "image/png")
	c.Header("Content-Disposition", fmt.Sprintf("inline; filename=\"%s\"", "图片地址"))
	c.Writer.WriteString(picByte.String())
}

// calcuDrawXandY 计算写入文字的x轴和y轴
func calcuDrawXandY(drawText string, fontSize, canvasLength, canvasWidth int) (x, y, newSize int, err error) {
	// y轴取画布宽度的一半
	y = canvasWidth / 2
	// 拆分文字计算总宽度
	lenText := 0
	strArr := strings.Split(drawText, "")
	for _, str := range strArr {
		if len(str) == 1 {
			// 将字母符号算作2个长度
			lenText += 2
		} else {
			lenText += 3
		}
	}
	textUnit := float64(lenText) / 3
	textWidth := int(textUnit * float64(fontSize))
	// x轴上的起点位置
	newSize = fontSize
	doubleX := canvasLength - textWidth
	if doubleX < 50 {
		// 文字总宽太长则调整文字大小
		maxTextWidth := float64(canvasLength - 50)
		newSize = int(maxTextWidth / textUnit)
		x = 25
	} else {
		x = doubleX / 2
	}

	return
}

// AddStatistics
// @Description 新增语音点击记录
// @Success 200 {string} string "新增成功"
// @Router /activity/voice_log/add [post]
func AddActivityAudioLog(c *gin.Context) {
	var req yb_view_log.ActivityAudioLogAddReq
	if err := c.Bind(&req); err != nil {
		response.Fail("参数有误:"+err.Error(), c)
		return
	}
	if req.PrimaryId == 0 {
		response.Fail("请输入音频ID", c)
		return
	}
	if req.ExtendId == 0 {
		response.Fail("请输入活动ID", c)
		return
	}

	if req.Source == 0 {
		response.Fail("请输入操作来源", c)
		return
	}
	userinfo := user.GetInfoByClaims(c)

	data, err := view_log.AddActivityAudioLog(userinfo, req)
	if err != nil {
		response.FailMsg("添加日志失败", err.Error(), c)
		return
	}
	response.OkData("新增记录成功", data, c)
}

// AddStatistics
// @Description 新增语音点击记录
// @Success 200 {string} string "新增成功"
// @Router /activity/voice_log/update [post]
func UpdateActivityAudioLog(c *gin.Context) {
	var req yb_view_log.ActivityAudioLogStopReq
	if err := c.Bind(&req); err != nil {
		response.Fail("参数有误:"+err.Error(), c)
		return
	}
	if req.Id == 0 {
		response.Fail("请输入日志ID", c)
		return
	}
	userinfo := user.GetInfoByClaims(c)

	err := view_log.UpdateActivityAudioLog(userinfo, req)
	if err != nil {
		response.FailMsg("更新日志失败", err.Error(), c)
		return
	}
	response.Ok("更新日志成功", c)
}