package callback

import (
	"context"
	"net/http"
	"strings"

	"github.com/gofiber/fiber/v2"
	"github.com/valyala/fasthttp/fasthttpadaptor"

	"github.com/break/junhong_cmp_fiber/internal/model"
	orderService "github.com/break/junhong_cmp_fiber/internal/service/order"
	rechargeService "github.com/break/junhong_cmp_fiber/internal/service/recharge"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
	"github.com/break/junhong_cmp_fiber/pkg/response"
	"github.com/break/junhong_cmp_fiber/pkg/wechat"
)

type PaymentHandler struct {
	orderService    *orderService.Service
	rechargeService *rechargeService.Service
	wechatPayment   wechat.PaymentServiceInterface
}

func NewPaymentHandler(orderService *orderService.Service, rechargeService *rechargeService.Service, wechatPayment wechat.PaymentServiceInterface) *PaymentHandler {
	return &PaymentHandler{
		orderService:    orderService,
		rechargeService: rechargeService,
		wechatPayment:   wechatPayment,
	}
}

// WechatPayCallback 微信支付回调（带签名验证）
// POST /api/callback/wechat-pay
func (h *PaymentHandler) WechatPayCallback(c *fiber.Ctx) error {
	if h.wechatPayment == nil {
		return errors.New(errors.CodeWechatCallbackInvalid, "微信支付服务未配置")
	}

	var httpReq http.Request
	fasthttpadaptor.ConvertRequest(c.Context(), &httpReq, true)

	ctx := context.Background()
	_, err := h.wechatPayment.HandlePaymentNotify(&httpReq, func(result *wechat.PaymentNotifyResult) error {
		if result.TradeState != "SUCCESS" {
			return nil
		}

		// 根据订单号前缀判断订单类型
		if strings.HasPrefix(result.OutTradeNo, constants.RechargeOrderPrefix) {
			// 充值订单回调
			return h.rechargeService.HandlePaymentCallback(ctx, result.OutTradeNo, model.PaymentMethodWechat, result.TransactionID)
		}

		// 套餐订单回调
		return h.orderService.HandlePaymentCallback(ctx, result.OutTradeNo, model.PaymentMethodWechat)
	})

	if err != nil {
		return errors.Wrap(errors.CodeWechatCallbackInvalid, err, "处理微信支付回调失败")
	}

	return response.Success(c, map[string]string{"return_code": "SUCCESS"})
}

type AlipayCallbackRequest struct {
	OrderNo string `json:"out_trade_no" form:"out_trade_no"`
}

func (h *PaymentHandler) AlipayCallback(c *fiber.Ctx) error {
	var req AlipayCallbackRequest
	if err := c.BodyParser(&req); err != nil {
		return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
	}

	if req.OrderNo == "" {
		return errors.New(errors.CodeInvalidParam, "订单号不能为空")
	}

	ctx := c.UserContext()

	// 根据订单号前缀判断订单类型
	if strings.HasPrefix(req.OrderNo, constants.RechargeOrderPrefix) {
		// 充值订单回调
		if err := h.rechargeService.HandlePaymentCallback(ctx, req.OrderNo, model.PaymentMethodAlipay, ""); err != nil {
			return err
		}
	} else {
		// 套餐订单回调
		if err := h.orderService.HandlePaymentCallback(ctx, req.OrderNo, model.PaymentMethodAlipay); err != nil {
			return err
		}
	}

	return c.SendString("success")
}
