package wechat

import (
	"fmt"
	"net/http"
	"time"

	"mini-chat/internal/code"
	"mini-chat/internal/pkg/core"
	"mini-chat/internal/pkg/miniprogram"
	"mini-chat/internal/pkg/validation"

	"gorm.io/gorm"
)

type templateRequest struct {
	AppID string `json:"app_id" binding:"required"` // 微信小程序 AppID
}

type templateResponse struct {
	Success    bool   `json:"success"`
	Message    string `json:"message"`
	AppID      string `json:"app_id"`      // 小程序 AppID
	TemplateID string `json:"template_id"` // 模板 ID
}

// GetTemplate 获取微信小程序模板ID
// @Summary 获取微信小程序模板ID
// @Description 根据 AppID 获取微信小程序的模板ID
// @Tags 微信
// @Accept json
// @Produce json
// @Param request body templateRequest true "请求参数"
// @Success 200 {object} templateResponse
// @Failure 400 {object} code.Failure
// @Failure 404 {object} code.Failure
// @Failure 500 {object} code.Failure
// @Router /api/wechat/template [post]
func (h *handler) GetTemplate() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(templateRequest)
		res := new(templateResponse)

		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.ParamBindError,
				validation.Error(err),
			))
			return
		}

		// 根据 AppID 查询小程序信息
		miniProgram, err := h.readDB.MiniProgram.WithContext(ctx.RequestContext()).
			Where(h.readDB.MiniProgram.AppID.Eq(req.AppID)).
			First()

		if err != nil {
			if err == gorm.ErrRecordNotFound {
				ctx.AbortWithError(core.Error(
					http.StatusNotFound,
					code.ServerError,
					fmt.Sprintf("未找到 AppID 为 %s 的小程序", req.AppID),
				))
				return
			}

			h.logger.Error(fmt.Sprintf("查询小程序信息失败: %s", err.Error()))
			ctx.AbortWithError(core.Error(
				http.StatusInternalServerError,
				code.ServerError,
				"查询小程序信息失败",
			))
			return
		}

		// 检查模板ID是否存在
		if miniProgram.TemplateID == "" {
			ctx.AbortWithError(core.Error(
				http.StatusNotFound,
				code.ServerError,
				"该小程序未配置模板ID",
			))
			return
		}

		res.Success = true
		res.Message = "获取模板ID成功"
		res.AppID = miniProgram.AppID
		res.TemplateID = miniProgram.TemplateID

		ctx.Payload(res)
	}
}

type sendSubscribeMessageRequest struct {
	AppID      string `json:"app_id" binding:"required"`      // 微信小程序 AppID
	TemplateID string `json:"template_id" binding:"required"` // 模板 ID
	AppSecret  string `json:"app_secret" binding:"required"`  // 小程序 AppSecret
	Touser     string `json:"touser" binding:"required"`      // 接收者（用户）的 openid
}

type sendSubscribeMessageResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message"`
}

// SendSubscribeMessage 发送订阅消息
// @Summary 发送订阅消息
// @Description 根据模板ID发送订阅消息
// @Tags 微信
// @Accept json
// @Produce json
// @Param request body sendSubscribeMessageRequest true "请求参数"
// @Success 200 {object} sendSubscribeMessageResponse
// @Failure 400 {object} code.Failure
// @Failure 404 {object} code.Failure
// @Failure 500 {object} code.Failure
// @Router /api/wechat/subscribe [post]
func (h *handler) SendSubscribeMessage() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(sendSubscribeMessageRequest)
		res := new(sendSubscribeMessageResponse)

		// 参数绑定和验证
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.ParamBindError,
				validation.Error(err),
			))
			return
		}

		// 发送模版消息
		accessToken, err := h.servicesMiniProgram.GetAccessToken(req.AppID, req.AppSecret, ctx)
		if err != nil {
			h.logger.Error(fmt.Sprintf("获取access_token失败: %s", err.Error()))
		} else {
			sendSubscribeMessageRequest := new(miniprogram.SendSubscribeMessageRequest)
			sendSubscribeMessageRequest.Touser = req.Touser
			sendSubscribeMessageRequest.TemplateID = req.TemplateID
			sendSubscribeMessageRequest.Page = "pages/index/detail?url=1"
			sendSubscribeMessageRequest.MiniprogramState = "formal" // 需要改成正式版 目前是体验版 跳转小程序类型：developer 为开发版；trial为体验版；formal 为正式版；默认为正式版
			sendSubscribeMessageRequest.Lang = "zh_CN"
			sendSubscribeMessageRequest.Data.Thing1.Value = "留言提醒"
			sendSubscribeMessageRequest.Data.Time2.Value = time.Now().Format("2006-01-02 15:04:05")
			sendSubscribeMessageRequest.Data.Thing3.Value = "您有一条新的消息..."

			sendSubscribeMessageResponse := new(miniprogram.SendSubscribeMessageResponse)
			err = miniprogram.SendSubscribeMessage(accessToken, sendSubscribeMessageRequest, sendSubscribeMessageResponse)
			if err != nil {
				res.Success = false
				res.Message = "发送订阅消息失败" + err.Error()
				h.logger.Error(fmt.Sprintf("发送模版消息失败: %s", err.Error()))
			} else {
				res.Success = true
				res.Message = "订阅消息发送成功"
			}
		}

		ctx.Payload(res)
	}
}
