package wechatrepoimpl

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/wechatpay-apiv3/wechatpay-go/core"
	"net/http"
	err2 "voucher/api/err"
	"voucher/internal/biz/bo"
	"voucher/internal/biz/businesserr"
	"voucher/internal/biz/wechatrepo"
	"voucher/internal/conf"
	"voucher/internal/data"
	"voucher/internal/pkg/wechat/srv/marketing"
	"voucher/internal/pkg/wechat/utils"
)

type BankMultiActivityImpl struct {
	bc *conf.Bootstrap
	wx *data.Wx
}

func NewBankMultiActivityImpl(bc *conf.Bootstrap, wx *data.Wx) wechatrepo.BankMultiActivityRepo {
	return &BankMultiActivityImpl{bc: bc, wx: wx}
}

func (w *BankMultiActivityImpl) Order(order *bo.OrderBo) (couponId string, err error) {

	req := &marketing.SendReq{
		OutRequestNo:      core.String(order.OrderNo),
		Appid:             core.String(order.AppID),
		StockId:           core.String(order.BatchNo),
		StockCreatorMchId: core.String(order.MerchantNo),
		ActivityId:        core.String(order.ActivityId),
	}

	t, err := w.wx.Get(w.bc.Wechat.MchID)
	if err != nil {
		return "", err
	}

	resp, err := t.Send(order.Account, req)

	if err != nil {

		var e *utils.ApiException
		if errors.As(err, &e) {
			// 格式：{"code":"INVALID_REQUEST","message":"对应单号已超出重试期;请查单确认后决定是否换单请求"}
			var beer *businesserr.BusinessErr
			if err = json.Unmarshal(e.Body(), &beer); err != nil {
				log.Errorf("微信错误返回body解析报错,body:%s,err:%s", string(e.Body()), err.Error())
				return "", err2.ErrorWechatFAIL(fmt.Sprintf("微信错误返回内容解析错误:%s", err.Error()))
			}

			//apiErr, err3 := marketing.BuildErr(e.Body())
			//if err3 != nil {
			//	return "", fmt.Errorf("ApiException analysis err: %+v", err3)
			//}
			//return "", err2.ErrorWechatFAIL("%s-%s", apiErr.Code, apiErr.Message)

			return "", beer
		}

		return "", err
	}

	return *resp.CouponId, nil
}

func (w *BankMultiActivityImpl) Notify(ctx context.Context, mchId string, headers *http.Header, respBody []byte) (*bo.WechatVoucherNotifyBo, error) {

	t, err := w.wx.Get(mchId)
	if err != nil {
		return nil, err
	}

	body, decodeBodyStr, err := t.Notify(ctx, headers, respBody)
	if err != nil {
		return nil, err
	}

	var plainText bo.PlainText
	if err = json.Unmarshal([]byte(decodeBodyStr), &plainText); err != nil {
		return nil, fmt.Errorf("plainText json.Unmarshal error: %v", err)
	}

	return &bo.WechatVoucherNotifyBo{
		ID:             body.Id,
		CreateTime:     body.CreateTime,
		ResourceType:   body.ResourceType,
		EventType:      body.EventType,
		Summary:        body.Summary,
		OriginalType:   body.Resource.OriginalType,
		AssociatedData: body.Resource.AssociatedData,
		PlainText:      plainText,
	}, nil
}

func (w *BankMultiActivityImpl) DecodeBody(ctx context.Context, mchId string, respBody []byte) (*bo.WechatVoucherNotifyBo, error) {

	t, err := w.wx.Get(mchId)
	if err != nil {
		return nil, err
	}

	var body utils.WxNotifyBody
	if err = json.Unmarshal(respBody, &body); err != nil {
		return nil, err
	}

	decryptedText, err := t.DecodeBody(&body)
	if err != nil {
		return nil, err
	}

	var plainText bo.PlainText
	if err = json.Unmarshal([]byte(decryptedText), &plainText); err != nil {
		return nil, fmt.Errorf("plainText json.Unmarshal error: %v", err)
	}

	return &bo.WechatVoucherNotifyBo{
		ID:             body.Id,
		CreateTime:     body.CreateTime,
		ResourceType:   body.ResourceType,
		EventType:      body.EventType,
		Summary:        body.Summary,
		OriginalType:   body.Resource.OriginalType,
		AssociatedData: body.Resource.AssociatedData,
		PlainText:      plainText,
	}, nil
}
