package controller

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

	"github.com/QuantumNous/new-api/common"
	"github.com/QuantumNous/new-api/model"
	"github.com/QuantumNous/new-api/setting"

	"github.com/gin-gonic/gin"
	"github.com/thanhpk/randstr"
)

// SubscriptionWechatPayRequest 微信支付订阅请求参数
type SubscriptionWechatPayRequest struct {
	PlanId int `json:"plan_id"`
}

// SubscriptionRequestWechatPay 微信支付订阅购买
func SubscriptionRequestWechatPay(c *gin.Context) {
	var req SubscriptionWechatPayRequest
	if err := c.ShouldBindJSON(&req); err != nil || req.PlanId <= 0 {
		common.ApiErrorMsg(c, "参数错误")
		return
	}

	plan, err := model.GetSubscriptionPlanById(req.PlanId)
	if err != nil {
		common.ApiError(c, err)
		return
	}
	if !plan.Enabled {
		common.ApiErrorMsg(c, "套餐未启用")
		return
	}

	if !setting.IsWechatPayConfigured() {
		common.ApiErrorMsg(c, "微信支付未配置")
		return
	}

	userId := c.GetInt("id")
	user, err := model.GetUserById(userId, false)
	if err != nil {
		common.ApiError(c, err)
		return
	}
	if user == nil {
		common.ApiErrorMsg(c, "用户不存在")
		return
	}

	if plan.MaxPurchasePerUser > 0 {
		count, err := model.CountUserSubscriptionsByPlan(userId, plan.Id)
		if err != nil {
			common.ApiError(c, err)
			return
		}
		if count >= int64(plan.MaxPurchasePerUser) {
			common.ApiErrorMsg(c, "已达到该套餐购买上限")
			return
		}
	}

	client, err := getWechatPayClient()
	if err != nil {
		log.Println("获取微信支付客户端失败:", err)
		c.JSON(http.StatusOK, gin.H{"message": "error", "data": "微信支付配置错误"})
		return
	}

	tradeNo := fmt.Sprintf("ws%d%s", time.Now().UnixMilli(), randstr.String(8))

	totalFee := int(math.Round(plan.PriceAmount * 100)) // 元 -> 分

	codeUrl, err := createWechatNativeOrder(client, plan.Title, tradeNo, totalFee)
	if err != nil {
		log.Println(err)
		c.JSON(http.StatusOK, gin.H{"message": "error", "data": "拉起支付失败"})
		return
	}

	order := &model.SubscriptionOrder{
		UserId:        userId,
		PlanId:        plan.Id,
		Money:         plan.PriceAmount,
		TradeNo:       tradeNo,
		PaymentMethod: PaymentMethodWechatPay,
		CreateTime:    time.Now().Unix(),
		Status:        common.TopUpStatusPending,
	}
	if err := order.Insert(); err != nil {
		c.JSON(http.StatusOK, gin.H{"message": "error", "data": "创建订单失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "success",
		"data": gin.H{
			"trade_no":    tradeNo,
			"qr_code_url": codeUrl,
		},
	})
}
