package app

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

	"bindbox-game/configs"
	"bindbox-game/internal/code"
	"bindbox-game/internal/pkg/core"
	"bindbox-game/internal/pkg/jwtoken"
	"bindbox-game/internal/pkg/validation"
	"bindbox-game/internal/pkg/wechat"
	"bindbox-game/internal/proposal"
	"bindbox-game/internal/service/sysconfig"
	usersvc "bindbox-game/internal/service/user"

	"go.uber.org/zap"
)

type weixinLoginRequest struct {
	Code       string `json:"code"`
	InviteCode string `json:"invite_code"`
	DouyinID   string `json:"douyin_id"`
}
type weixinLoginResponse struct {
	UserID     int64  `json:"user_id"`
	Nickname   string `json:"nickname"`
	Avatar     string `json:"avatar"`
	Mobile     string `json:"mobile"` // 新增手机号字段
	InviteCode string `json:"invite_code"`
	OpenID     string `json:"openid"`
	Token      string `json:"token"`
}

// WeixinLogin 微信登录
// @Summary 微信登录
// @Description 微信静默登录（需传递 code；可选 invite_code）
// @Tags APP端.用户
// @Accept json
// @Produce json
// @Param RequestBody body weixinLoginRequest true "请求参数"
// @Success 200 {object} weixinLoginResponse
// @Failure 400 {object} code.Failure
// @Router /api/app/users/weixin/login [post]
func (h *handler) WeixinLogin() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(weixinLoginRequest)
		rsp := new(weixinLoginResponse)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
			return
		}
		// Use dynamic config
		wxCfgVal := sysconfig.GetDynamicConfig().GetWechat(ctx.RequestContext().Context)
		wxcfg := &wechat.WechatConfig{AppID: wxCfgVal.AppID, AppSecret: wxCfgVal.AppSecret}

		fmt.Printf("DEBUG WeixinLogin: Using Config AppID=%s\n", wxcfg.AppID)

		c2s, err := wechat.Code2Session(ctx.RequestContext().Context, wxcfg, req.Code)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, 10006, err.Error()))
			return
		}

		in := usersvc.LoginWeixinInput{OpenID: c2s.OpenID, UnionID: c2s.UnionID, InviteCode: req.InviteCode, DouyinID: req.DouyinID}
		out, err := h.user.LoginWeixin(ctx.RequestContext(), in)
		if err != nil {
			ctx.AbortWithError(core.Error(http.StatusBadRequest, 10006, err.Error()))
			return
		}

		u := out.User
		rsp.UserID = u.ID
		rsp.Nickname = u.Nickname

		// 触发邀请奖励逻辑
		if out.IsNewUser && out.InviterID > 0 {
			if err := h.task.OnInviteSuccess(ctx.RequestContext(), out.InviterID, u.ID); err != nil {
				h.logger.Error("触发邀请任务失败", zap.Error(err), zap.Int64("inviter_id", out.InviterID), zap.Int64("invitee_id", u.ID))
			}
		}
		rsp.Avatar = u.Avatar
		rsp.Mobile = u.Mobile // 返回手机号
		rsp.InviteCode = u.InviteCode
		rsp.OpenID = c2s.OpenID
		sessionUserInfo := proposal.SessionUserInfo{Id: int32(u.ID), UserName: u.Nickname, NickName: u.Nickname, IsSuper: 0, Platform: "APP"}
		tokenString, tErr := jwtoken.New(configs.Get().JWT.PatientSecret).Sign(sessionUserInfo, 30*24*time.Hour)
		if tErr == nil {
			rsp.Token = tokenString
		}
		ctx.Payload(rsp)
	}
}
