package service

import (
	"context"
	"enterprise/common/config"
	"enterprise/common/dao"
	"enterprise/common/global"
	"enterprise/common/model"
	"enterprise/server/api"
	"enterprise/server/session"
	"fmt"
	"git.u8t.cn/open/gosdk/qyweixin"
	"github.com/gogap/errors"
	log "github.com/sirupsen/logrus"
	"github.com/smartwalle/alipay/v3"
	"github.com/smbrave/goutil"
	"github.com/spf13/cast"
	"strings"
)

type Pay struct {
}

func NewPay() *Pay {
	return &Pay{}
}

func (p *Pay) Pay(corp *model.Corp, req *api.PayReq) {

	user, err := dao.NewStaffUserDao().GetByUsername(corp.Id, req.Username)
	session.CheckDBError(err)
	session.CheckNilError(user, fmt.Sprintf("用户[%s]不存在", req.Username))

	payType := ""
	payee := user.GetPayee()
	if req.PayType == "alipay" {
		if payee.AlipayUid == "" {
			panic("请绑定支付宝账号")
		}
		err = p.payAlipay(corp, user, req)
		payType = "alipay"
	} else {
		err = p.payWeixin(corp, user, req)
		payType = "weixin"
	}

	message := make([]string, 0)
	message = append(message, fmt.Sprintf("【企业转账】[%s]", req.Username))
	message = append(message, fmt.Sprintf("发放金额:%s", goutil.FormatMoney(req.Amount)))
	message = append(message, fmt.Sprintf("支付类型:%s", payType))
	message = append(message, fmt.Sprintf("员工名称:%s", req.Username))
	message = append(message, fmt.Sprintf("费用说明:%s", req.Title))
	if err != nil {
		message = append(message, fmt.Sprintf("错误信息:%s", err.Error()))
		global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n"))
		log.Errorf("pay req[%s] error :%s", goutil.EncodeJSON(req), err.Error())
		panic(config.ErrInternal.New().Append(err))
	}

	global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n"))
}

func (p *Pay) payAlipay(corp *model.Corp, user *model.StaffUser, req *api.PayReq) error {
	corpConfig := corp.GetConfig()
	userPayee := user.GetPayee()
	cli := config.GetAliPayClient(goutil.If(corpConfig.PayChannel != "", corpConfig.PayChannel, "batiao"))
	var payReq alipay.FundTransUniTransfer
	payReq.Remark = req.Title
	payReq.OutBizNo = cast.ToString(goutil.GetBigID(0, 0))
	payReq.TransAmount = goutil.FormatMoney(req.Amount)
	payReq.ProductCode = "TRANS_ACCOUNT_NO_PWD"
	payReq.BizScene = "DIRECT_TRANSFER"
	payReq.OrderTitle = req.Title
	payee := new(alipay.PayeeInfo)
	payReq.PayeeInfo = payee
	payee.IdentityType = "ALIPAY_USER_ID"
	payee.Identity = userPayee.AlipayUid

	rsp, err := cli.FundTransUniTransfer(context.Background(), payReq)
	if err != nil {
		panic(err)
	}
	if !rsp.IsSuccess() {
		log.Errorf("FundTransUniTransfer error :%s", goutil.EncodeJSON(rsp))
		return errors.New(goutil.EncodeJSON(rsp))
	}
	return nil
}

func (p *Pay) payWeixin(corp *model.Corp, user *model.StaffUser, req *api.PayReq) error {

	cfg := corp.GetConfig()

	// 获取openid
	approve := qyweixin.NewAppApprove(&qyweixin.AppConfig{
		Corpid: cfg.CorpId,
		Secret: cfg.EnterpriseSecret,
		Agent:  cfg.EnterpriseAgent,
	})
	openid, err := approve.GetOpenid(req.Username)
	if err != nil {
		log.Errorf("GetOpenid[%s] error :%s ", req.Username, err.Error())
		return err
	}

	// 支付费用
	var payReq qyweixin.PayReq
	payReq.BillNo = cast.ToString(goutil.GetBigID(0, 0))
	payReq.Title = req.Title
	payReq.Openid = openid
	payReq.TotalAmount = req.Amount
	qyPay := qyweixin.NewAppPay(&qyweixin.PayConfig{
		Corpid:       cfg.CorpId,
		Secret:       cfg.PaySecret,
		Agent:        cfg.PayAgent,
		SerialNumber: cfg.PaySerialNumber,
		ApiKey:       cfg.PayApiKeyV2,
		MchId:        cfg.PayMchid,
		CertPem:      cfg.PayCertPem,
		KeyPem:       cfg.PayKeyPem,
	})

	if err = qyPay.PayMoney(&payReq); err != nil {
		log.Errorf("pay req[%s] error :%s", goutil.EncodeJSON(req), err.Error())
		return err
	}
	return nil
}