package wechatrepoimpl

import (
	"context"
	"fmt"
	"github.com/wechatpay-apiv3/wechatpay-go/core"
	"github.com/wechatpay-apiv3/wechatpay-go/services/cashcoupons"
	"voucher/internal/biz/bo"
	"voucher/internal/biz/vo"
	"voucher/internal/biz/wechatrepo"
	"voucher/internal/conf"
	"voucher/internal/data"
)

type CpnRepoImpl struct {
	Server *data.Server
}

func NewCpnRepoImpl(bc *conf.Bootstrap) (wechatrepo.WechatCpnRepo, error) {
	server := &data.Server{
		MchID:                      bc.Wechat.MchID,
		MchCertificateSerialNumber: bc.Wechat.MchCertificateSerialNumber,
	}

	if err := server.Validate(); err != nil {
		return nil, err
	}

	return &CpnRepoImpl{Server: server}, nil
}

func (c *CpnRepoImpl) Order(ctx context.Context, orderWechat *bo.OrderWechatBo) (couponId string, err error) {

	req := cashcoupons.SendCouponRequest{
		Openid:       core.String(orderWechat.OpenID),
		StockId:      core.String(orderWechat.StockID),
		OutRequestNo: core.String(orderWechat.OutRequestNo),
		// 微信为发券方商户分配的公众账号ID，接口传入的所有appid应该为公众号的appid（在mp.weixin.qq.com申请的），不能为APP的appid（在open.weixin.qq.com申请的）。
		Appid:             core.String(orderWechat.AppID),
		StockCreatorMchid: core.String(orderWechat.StockCreatorMchid),
	}

	client, err := data.GetClient(ctx, c.Server)
	if err != nil {
		return
	}

	svc := cashcoupons.CouponApiService{Client: client}

	resp, result, err := svc.SendCoupon(ctx, req)
	if err != nil {
		return
	}

	if result.Response.StatusCode != CodeSuccess {
		err = fmt.Errorf("Order微信返回错误StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status)
		return
	}

	couponId = *resp.CouponId

	return
}

func (c *CpnRepoImpl) Query(ctx context.Context, orderWechat *bo.OrderWechatBo) (vo.OrderWechatStatus, error) {

	req := cashcoupons.QueryCouponRequest{
		CouponId: core.String(orderWechat.CouponID),
		Appid:    core.String(orderWechat.AppID),
		Openid:   core.String(orderWechat.OpenID),
	}

	client, err := data.GetClient(ctx, c.Server)
	if err != nil {
		return 0, err
	}

	svc := cashcoupons.CouponApiService{Client: client}

	resp, result, err := svc.QueryCoupon(ctx, req)
	if err != nil {
		return 0, err
	}

	if result.Response.StatusCode != CodeSuccess {
		err = fmt.Errorf("Query微信返回错误StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status)
		return 0, err
	}

	return CpnStatus(*resp.Status).GetStatus()
}

func (c *CpnRepoImpl) QueryProduct(ctx context.Context, stockCreatorMchId, stockId string) (*cashcoupons.Stock, error) {

	client, err := data.GetClient(ctx, c.Server)
	if err != nil {
		return nil, err
	}

	svc := cashcoupons.StockApiService{Client: client}

	response, result, err := svc.QueryStock(ctx, cashcoupons.QueryStockRequest{
		StockId:           core.String(stockId),
		StockCreatorMchid: core.String(stockCreatorMchId),
	})

	if err != nil {
		return nil, err
	}

	if result.Response.StatusCode != CodeSuccess {
		err = fmt.Errorf("查询活动微信返回错误StatusCode[%d]Status[%s]", result.Response.StatusCode, result.Response.Status)
		return nil, err
	}

	return response, nil
}

func (c *CpnRepoImpl) Notify(ctx context.Context) error {
	return nil
}
