package localjx

import (
	"errors"
	"fmt"
	"git.rosy.net.cn/baseapi/platformapi/kuaishou_mini"
	beego "github.com/astaxie/beego/server/web"
	"strings"
	"time"

	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/auth2/authprovider/kuaishou"
	"git.rosy.net.cn/jx-callback/business/jxutils"
	"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"git.rosy.net.cn/jx-callback/globals"
	"git.rosy.net.cn/jx-callback/globals/api"
)

func getOrderBriefKs(order *model.GoodsOrder) string {
	sku := make([]string, len(order.Skus))
	for _, v := range order.Skus {
		sku = append(sku, fmt.Sprintf("%s x %d件商品", v.SkuName, v.Count))
	}
	return strings.Join(sku, ",")
}

func pay4OrderByKs(ctx *jxcontext.Context, order *model.GoodsOrder, vendorPayType, subAppID string) (orderPay *model.OrderPay, err error) {
	// 获取用户快手OpenId
	var (
		db = dao.GetDB()
	)
	authBindList, err := dao.GetUserBindAuthInfo(db, ctx.GetUserID(), model.AuthBindTypeAuth, []string{kuaishou.AuthTypeKuaiShouMini}, "", "", nil)
	if err != nil {
		return nil, err
	}
	if len(authBindList) == model.NO {
		return nil, errors.New("用户未绑定快手,无法快手支付")
	}

	param := &kuaishou_mini.PreCreateOrderReq{
		OutOrderNo:  utils.Int64ToStr(GenPayOrderID(order)),
		OpenId:      authBindList[0].AuthID,
		TotalAmount: order.ActualPayPrice,
		Subject:     "蔬菜水果日用品",
		Detail:      getOrderBriefKs(order),
		TypeDetail:  1832, // 蔬菜:费率2%,水果:1833%2
		ExpireTime:  60 * 10,
		Sign:        "",
		//Attach:               "",
		//GoodsId:              "",
		//GoodsDetailUrl:       "",
		//MultiCopiesGoodsInfo: "",
		CancelOrder: 0,
	}

	if beego.BConfig.RunMode == model.ServerTypeFruits {
		param.NotifyUrl = "https://callback-jxgy.jxc4.com/kuaishou/kuaiShouCallback"
	} else if beego.BConfig.RunMode == model.ServerTypePet {
		param.NotifyUrl = "https://callback.jxpet.com/kuaishou/kuaiShouCallback"
	} else {
		param.NotifyUrl = "https://callback.jxc4.com/kuaishou/kuaiShouCallback"
	}
	// 预下单
	prePayInfo, err := api.KuaiShouApi.PreCreateOrder(param)
	if err == nil {
		orderPay = &model.OrderPay{
			PayOrderID:    order.VendorOrderID, // 抖音订单id
			PayType:       model.PayTypeKuaiShou,
			VendorPayType: vendorPayType,
			VendorOrderID: order.VendorOrderID,
			VendorID:      order.VendorID,
			Status:        0,
			PayCreatedAt:  time.Now(),
			PrepayID:      prePayInfo.OrderNo,
			CodeURL:       prePayInfo.OrderInfoToken, // 抖音支付token
			TotalFee:      int(order.ActualPayPrice),
		}
	}
	return orderPay, err
}

func OnKSPayCallback(msg *kuaishou_mini.CallBackDetail, refund *kuaishou_mini.RefundCallBack, payType string) (err error) {
	switch payType {
	case kuaishou_mini.CallbackTypePay: // 支付回调
		err = onKSPayFinished(msg)
	case kuaishou_mini.CallbackTypeRefund: // 退款回调
		err = onKSPayRefund(refund)
	}
	return err
}

func onKSPayFinished(msg *kuaishou_mini.CallBackDetail) (err error) {
	orderPay := &model.OrderPay{
		PayOrderID: msg.OutOrderNo,
		PayType:    model.PayTypeKuaiShou,
	}
	orderPay.DeletedAt = utils.DefaultTimeValue
	db := dao.GetDB()
	if err = dao.GetEntity(db, orderPay, "PayOrderID", "PayType", "DeletedAt"); err == nil {
		orderPay.PayFinishedAt = utils.Time2Pointer(time.Now())
		orderPay.TransactionID = msg.TradeNo
		orderPay.OriginalData = utils.Format4Output(msg, true)
		switch msg.Status {
		case kuaishou_mini.OrderPayStatusHandleing:
			orderPay.Status = model.PayStatusNo
		case kuaishou_mini.OrderPayStatusSuccess:
			orderPay.Status = model.PayStatusYes
		case kuaishou_mini.OrderPayStatusFailed:
			orderPay.Status = model.PayStatusFailed
		}
		dao.UpdateEntity(db, orderPay)

		if msg.Status == kuaishou_mini.OrderPayStatusSuccess {
			err = OnPayFinished(orderPay)
		}
	} else {
		globals.SugarLogger.Debugf("onKSPayFinished msg:%s, err:%v", utils.Format4Output(msg, true), err)
	}
	return err
}

func onKSPayRefund(msg *kuaishou_mini.RefundCallBack) (err error) {
	orderPayRefund := &model.OrderPayRefund{
		RefundID: msg.OutRefundNo,
	}
	db := dao.GetDB()
	if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err == nil {
		switch msg.Status {
		case kuaishou_mini.OrderPayStatusHandleing:
			orderPayRefund.Status = model.PayStatusNo
		case kuaishou_mini.OrderPayStatusSuccess:
			orderPayRefund.Status = model.PayStatusYes
		case kuaishou_mini.OrderPayStatusFailed:
			orderPayRefund.Status = model.PayStatusFailed
		}

		orderPayRefund.OriginalData = utils.Format4Output(msg, true)
		dao.UpdateEntity(db, orderPayRefund)
	} else if dao.IsNoRowsError(err) {
		globals.SugarLogger.Warnf("收到异常的退款事件, msg:%s", utils.Format4Output(msg, true))
	}

	orderPay := &model.OrderPay{
		VendorOrderID: orderPayRefund.VendorOrderID,
		VendorID:      jxutils.GetPossibleVendorIDFromVendorOrderID(orderPayRefund.VendorOrderID),
		PayType:       model.PayTypeKuaiShou,
		Status:        model.PayStatusYes,
	}
	orderPay.DeletedAt = utils.DefaultTimeValue
	if err = dao.GetEntity(db, orderPay, "VendorOrderID", "VendorID", "PayType", "Status", "DeletedAt"); err == nil {
		orderPay.Status = model.PayStatusRefund
		dao.UpdateEntity(db, orderPay)
	}
	return err
}

// RefundOrderByKS 申请退款
func RefundOrderByKS(ctx *jxcontext.Context, orderPay *model.OrderPay, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) {

	param := kuaishou_mini.RefundParam{
		OutOrderNo:           orderPay.VendorOrderID,
		OutRefundNo:          refundID,
		Reason:               refundDesc,
		Attach:               "",
		NotifyUrl:            "https://callback.jxc4.com/kuaishou/kuaiShouCallback",
		RefundAmount:         int64(orderPay.TotalFee),
		Sign:                 "",
		MultiCopiesGoodsInfo: "",
	}
	result, err := api.KuaiShouApi.RefundOrder(&param)
	if err == nil {
		orderPayRefund = &model.OrderPayRefund{
			RefundID:        refundID,
			VendorRefundID:  result,
			VendorOrderID:   orderPay.VendorOrderID,
			VendorID:        orderPay.VendorID,
			Status:          model.RefundStatusNo,
			TransactionID:   orderPay.TransactionID,
			RefundFee:       refundFee,
			RefundCreatedAt: time.Now(),
		}
		dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName())
		db := dao.GetDB()
		if result != "" {
			orderPayRefund.Status = model.RefundStatusYes
		} else {
			orderPayRefund.Status = model.RefundStatusFailed
		}
		orderPayRefund.OriginalData = utils.Format4Output(result, true)
		dao.CreateEntity(db, orderPayRefund)

		orderPay.Status = model.PayStatusRefund
		dao.UpdateEntity(db, orderPay)
	}
	return orderPayRefund, err
}
