package services

import (
	"encoding/json"
	"errors"
	"eta/eta_api/models"
	"eta/eta_api/models/company"
	"eta/eta_api/services/alarm_msg"
	"eta/eta_api/services/third"
	"eta/eta_api/utils"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"strings"
)

type SendTemplateResponse struct {
	Errcode int    `json:"errcode"`
	Errmsg  string `json:"errmsg"`
	MsgID   int    `json:"msgid"`
}

type ClearQuotaResponse struct {
	Errcode int    `json:"errcode"`
	Errmsg  string `json:"errmsg"`
}

// SendMiniProgramReportWxMsg 推送报告微信模板消息-小程序链接
func SendMiniProgramReportWxMsg(reportId int) (err error) {
	fmt.Println("推送模板消息1 services SendMsg:", reportId)
	var msg string
	reportIdStr := strconv.Itoa(reportId)
	if utils.ETAMiniBridgeUrl != "" {
		err = third.DwSendTemplatedMsg(reportId)
		return
	}
	defer func() {
		if err != nil {
			fmt.Println("msg:", msg)
			utils.FileLog.Error(fmt.Sprintf("SendMiniProgramReportWxMsg, 发送报告模版消息失败, ReportId:%s, Err:%s", reportIdStr, err.Error()))
			go alarm_msg.SendAlarmMsg("SendMiniProgramReportWxMsg发送报告模版消息失败;"+"ReportId:"+reportIdStr+",Err:"+err.Error()+";msg:"+msg, 3)
			//go utils.SendEmail("SendMiniProgramReportWxMsg发送报告模版消息失败"+"【"+utils.APPNAME+"】"+"【"+utils.RunMode+"】"+time.Now().Format("2006-01-02 15:04:05"), "ReportId:"+reportIdStr+";"+msg+";Err:"+err.Error(), toUser)
		}
	}()
	fmt.Println("推送模板消息 services SendMsg:", reportId)

	report, err := models.GetReportByReportId(reportId)
	if err != nil {
		msg = "GetReportInfo Err:" + err.Error()
		return
	}
	if report == nil {
		utils.FileLog.Info("报告信息不存在")
		return
	}
	//if report.MsgIsSend == 1 {
	//	return
	//}
	//accessToken, err := models.GetWxAccessToken()
	//if err != nil {
	//	msg = "GetWxAccessToken Err:" + err.Error()
	//	return
	//}
	//if accessToken == "" {
	//	msg = "accessToken is empty"
	//	return
	//}

	var openIdArr []string

	// 如果是弘则,且报告分类是晨报,那么就所有人推送
	if (utils.BusinessCode == utils.BusinessCodeRelease || utils.BusinessCode == utils.BusinessCodeSandbox || utils.BusinessCode == utils.BusinessCodeDebug) && report.ClassifyNameFirst == "晨报" {
		// 如果是章节,那就推送所有用户
		openIdArr, err = models.GetOpenIdArr()
		if err != nil {
			msg = "get GetOpenIdArr err:" + err.Error()
			return
		}
	} else {
		minClassifyId, _, err := getMinClassify(report)
		if err != nil {
			msg = "获取报告的最小分类失败 err:" + err.Error()
			return err
		}

		// 判断分类是否存在
		_, err = models.GetClassifyById(minClassifyId)
		if err != nil {
			msg = "获取报告分类失败 err:" + err.Error()
			return err
		}

		// 获取该分类关联的openid列表
		openIdArr, err = models.GetOpenIdArrByClassifyId(minClassifyId)
		if err != nil {
			msg = "GetOpenIdArrByClassifyNameSecond err:" + err.Error()
			return err
		}
	}

	//sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
	//fmt.Println("send start")
	//utils.FileLog.Info("send start")
	//sendMap := make(map[string]interface{})
	//sendData := make(map[string]interface{})

	title := fmt.Sprintf("弘则%s", report.ClassifyNameFirst)
	if CheckTwoWeekOrMonthReport(report.ClassifyIdFirst, report.ClassifyNameFirst) {
		title = fmt.Sprintf("弘则%s", report.ClassifyNameSecond)
	}
	//redirectUrl := utils.TemplateRedirectUrl + strconv.Itoa(reportId)
	first := fmt.Sprintf("Hi,最新一期%s已上线,欢迎查看", report.ClassifyNameFirst)
	keyword1 := title
	keyword2 := report.Title
	keyword3 := report.PublishTime.Format(utils.FormatDateTime)
	keyword4 := report.Abstract

	//sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
	//sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
	//sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
	//sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
	//sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": "#173177"}
	//
	//sendMap["template_id"] = utils.TemplateIdByProduct
	////sendMap["url"] = redirectUrl
	//sendMap["data"] = sendData

	var wxAppPath string
	weekClassifyId, err := company.GetReportClassifyIdByConfigKey("report_week_classify_id")
	if err != nil && err.Error() != utils.ErrNoRow() {
		msg = "获取周报ID配置失败:" + err.Error()
		return err
	}

	// 周报走这个逻辑,我也不清楚为什么,原先就是这样(2024-6-20 16:46:07)
	if report.ClassifyIdFirst == weekClassifyId {
		wxAppPath = fmt.Sprintf("pages-report/chapterList?reportId=%s", reportIdStr)
	} else {
		wxAppPath = fmt.Sprintf("pages-report/reportDetail?reportId=%s", reportIdStr)
	}

	//if wxAppPath != "" {
	//	sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxYbAppId, "pagepath": wxAppPath}
	//}
	//err = sendTemplateMsg(sendUrl, sendMap, openIdList, wxAppPath, utils.TEMPLATE_MSG_REPORT)

	sendInfo := new(SendWxTemplate)
	sendInfo.First = first
	sendInfo.Keyword1 = keyword1
	sendInfo.Keyword2 = keyword2
	sendInfo.Keyword3 = keyword3
	sendInfo.Keyword4 = keyword4
	sendInfo.TemplateId = utils.TemplateIdByProduct
	sendInfo.RedirectUrl = wxAppPath
	sendInfo.Resource = wxAppPath
	sendInfo.SendType = utils.TEMPLATE_MSG_REPORT
	sendInfo.OpenIdArr = openIdArr
	sendInfo.RedirectTarget = 1
	err = SendTemplateMsg(sendInfo)

	return
}

// CheckTwoWeekOrMonthReport 校验推送报告是否为双周报或者月报
func CheckTwoWeekOrMonthReport(classifyId int, classifyName string) (ok bool) {
	if utils.RunMode == "debug" {
		miniStrArr := []string{
			"双周报", "月报",
		}
		if utils.InArrayByStr(miniStrArr, classifyName) {
			ok = true
		}
	} else {
		// 此处生产环境用ID主要是担心分类改了名字...
		IdArr := []int{
			96, 112,
		}
		if utils.InArrayByInt(IdArr, classifyId) {
			ok = true
		}
	}
	return
}

type SendWxTemplate struct {
	WxAppId        string   `description:"公众号appId"`
	First          string   `description:"模板消息first字段"`
	Keyword1       string   `description:"模板消息keyword1字段"`
	Keyword2       string   `description:"模板消息keyword2字段"`
	Keyword3       string   `description:"模板消息keyword3字段"`
	Keyword4       string   `description:"模板消息keyword4字段"`
	Keyword5       string   `description:"模板消息keyword5字段"`
	Remark         string   `description:"模板消息remark字段"`
	TemplateId     string   `description:"模板id"`
	RedirectUrl    string   `description:"跳转地址"`
	RedirectTarget int      `description:"小程序跳转目标:1:弘则研报小程序,2:随手办公小程序"`
	Resource       string   `description:"资源唯一标识"`
	SendType       int      `description:"发送的消息类型:1:报告,2:指标更新提醒,3:审批通知,4:销售领取客户通知,5:活动取消通知,6活动更改时间通知,7:关注的作者发布报告通知,8:发送日报(周报、双周报、月报)模板消息,9:活动预约/报名时间通知"`
	OpenIdArr      []string `description:"消息接收者openid"`
}

// SendTemplateMsg 推送模板消息
func SendTemplateMsg(sendInfo *SendWxTemplate) (err error) {
	if utils.SendWxTemplateMsgUrl == `` {
		// 找不到推送服务
		return
	}
	postData, err := json.Marshal(sendInfo)
	if err != nil {
		alarm_msg.SendAlarmMsg("SendTemplateMsg json.Marshal Err:"+err.Error(), 1)
		return err
	}
	body := io.NopCloser(strings.NewReader(string(postData)))
	client := &http.Client{}
	req, err := http.NewRequest("POST", utils.SendWxTemplateMsgUrl, body)
	if err != nil {
		alarm_msg.SendAlarmMsg("SendTemplateMsg http.NewRequest Err:"+err.Error(), 1)
		return err
	}
	contentType := "application/json;charset=utf-8"
	req.Header.Set("Content-Type", contentType)
	req.Header.Set("Authorization", utils.SendTemplateMsgAuthorization)
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("http client.Do Err:" + err.Error())
		return err
	}
	defer resp.Body.Close()
	b, err := io.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	result := new(models.BaseResponse)
	err = json.Unmarshal(b, &result)
	if err != nil {
		return err
	}
	if result.Ret != 200 {
		err = errors.New(string(b))
		return err
	}
	return
}