package localjx

import (
	"fmt"
	"git.rosy.net.cn/baseapi/platformapi/lakala"
	"git.rosy.net.cn/baseapi/utils"
	"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/business/partner"
	"git.rosy.net.cn/jx-callback/globals"
	"git.rosy.net.cn/jx-callback/globals/api"
	"time"
)

// RefundBarCodeScannerOrderByLaKaLa 拉卡拉退款
func RefundBarCodeScannerOrderByLaKaLa(ctx *jxcontext.Context, vendorOrderId string, skuIds map[int]int, reason string, refund string) (resp interface{}, err error) {
	db := dao.GetDB()
	txDB, _ := dao.Begin(db)
	defer func() {
		if r := recover(); r != nil || err != nil {
			dao.Rollback(db, txDB)
			if r != nil {
				panic(r)
			}
		}
	}()

	goodsOrder, err := partner.CurOrderManager.LoadOrder(vendorOrderId, model.VendorIDJX)
	if err != nil {
		dao.Rollback(db, txDB)
		return nil, err
	}

	// 检查订单售后
	refundType, refundMoney, err := checkJxAfsOrder(db, goodsOrder, vendorOrderId, skuIds)
	if err != nil {
		dao.Rollback(db, txDB)
		return nil, err
	}

	// 本地添加售后数据
	afsOrder, orderSkuFinancial, afsOrderSkuFinancial, err := addRefundSku(ctx, goodsOrder, skuIds, reason, refundType)
	if err != nil {
		dao.Rollback(db, txDB)
		return nil, err
	}
	afsOrder.SkuUserMoney = int64(refundMoney)

	if err = dao.CreateEntity(db, afsOrder); err != nil {
		dao.Rollback(db, txDB)
		return nil, err
	}
	if err = dao.CreateMultiEntities(db, orderSkuFinancial); err != nil {
		dao.Rollback(db, txDB)
		return nil, err
	}
	if err = dao.CreateMultiEntities(db, afsOrderSkuFinancial); err != nil {
		dao.Rollback(db, txDB)
		return nil, err
	}
	goodsOrder.TotalShopMoney -= int64(refundMoney)
	dao.UpdateEntity(db, goodsOrder, "TotalShopMoney")
	dao.Commit(db, txDB)

	return resp, nil
}

func RefundOrderByLaKaLa(ctx *jxcontext.Context, orderPay *model.OrderPay, afsOrder *model.AfsOrder, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) {
	var (
		db = dao.GetDB()
	)
	order, err := partner.CurOrderManager.LoadOrder(orderPay.VendorOrderID, orderPay.VendorID)
	if err != nil {
		return nil, err
	}
	// 通知退款,等待回传
	incoming, err := dao.GetStoreInfoByMerchantID(db, "", order.JxStoreID, "", "")
	if err != nil {
		return nil, err
	}
	switch orderPay.VendorPayType {
	case /*lakala.PayWayAPP*/ "2": // 收银台
		param := &lakala.RefundOrderReq{
			MerchantNo:      incoming.MerchantNo2,
			TermNo:          incoming.TermNo,
			OutTradeNo:      afsOrder.AfsOrderID,
			RefundAmount:    utils.Int2Str(refundFee),
			OriginBizType:   "3",
			OriginTradeDate: order.OrderCreatedAt.Format("20060102"),
			OriginLogNo:     order.VendorOrderID2,
			OriginTradeNo:   "",
			OriginCardNo:    "",
			LocationInfo:    nil,
			RefundType:      "",
		}

		globals.SugarLogger.Debugf("-----param-RefundOrder := %s", utils.Format4Output(param, false))
		resp, err := api.LaKaLaApi.RefundOrder(param)
		if err != nil {
			return nil, err
		}
		orderPayRefund = &model.OrderPayRefund{
			RefundID:        refundID,
			VendorRefundID:  resp.LogNo,
			VendorOrderID:   orderPay.VendorOrderID,
			VendorID:        orderPay.VendorID,
			Status:          model.RefundStatusYes,
			TransactionID:   resp.LogNo,
			RefundFee:       refundFee,
			RefundCreatedAt: time.Now(),
		}
		orderPayRefund.Status = model.RefundStatusYes
		orderPayRefund.OriginalData = utils.Format4Output(resp, true)
		orderPay.Status = model.PayStatusRefund
		dao.UpdateEntity(db, orderPay, "Status")
		dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName())
		dao.CreateEntity(db, orderPayRefund)
	case lakala.PayWayMini, lakala.PayWayRegister, lakala.PayWayAPP: // 主扫被扫
		param := &lakala.AggregateRefundReq{
			MerchantNo:       incoming.MerchantNo2,
			TermNo:           incoming.TermNo,
			OutTradeNo:       afsOrder.AfsOrderID,
			RefundAmount:     utils.Int2Str(refundFee),
			RefundReason:     refundDesc,
			OriginOutTradeNo: order.VendorOrderID,
			OriginTradeNo:    "",
			OriginLogNo:      order.VendorOrderID2,
			LocationInfo:     lakala.LocationInfoObj{RequestIp: ctx.GetRealRemoteIP()},
		}
		globals.SugarLogger.Debugf("-----param-AggregateRefund := %s", utils.Format4Output(param, false))
		resp, err := api.LaKaLaApi.AggregateRefund(param)
		if err != nil {
			return nil, err
		}
		orderPayRefund = &model.OrderPayRefund{
			RefundID:        refundID,
			VendorRefundID:  resp.LogNo,
			VendorOrderID:   orderPay.VendorOrderID,
			VendorID:        orderPay.VendorID,
			Status:          model.RefundStatusYes,
			TransactionID:   orderPay.TransactionID,
			RefundFee:       refundFee,
			RefundCreatedAt: time.Now(),
		}
		orderPayRefund.Status = model.RefundStatusYes
		orderPayRefund.OriginalData = utils.Format4Output(resp, true)
		orderPay.Status = model.PayStatusRefund
		dao.UpdateEntity(db, orderPay, "Status")
		dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName())
		dao.CreateEntity(db, orderPayRefund)
	}

	if order.TotalShopMoney == int64(refundFee) && err == nil {
		order.Status = model.OrderStatusCanceled
		order.VendorStatus = "laKaLaRefund"
		dao.UpdateEntity(db, order, "Status", "VendorStatus")
	}
	return orderPayRefund, err
}

// QueryBarCodeRefundStatus 退款订单状态查询
func QueryBarCodeRefundStatus(afsOrderID string) (resp []*lakala.RefundOrderQueryResp, err error) {
	db := dao.GetDB()
	txDB, _ := dao.Begin(db)
	defer func() {
		if r := recover(); r != nil || err != nil {
			dao.Rollback(db, txDB)
			if r != nil {
				panic(r)
			}
		}
	}()

	afsOrder, err := partner.CurOrderManager.LoadAfsOrder(afsOrderID, model.VendorIDJX)
	if err != nil {
		return nil, err
	}

	goodsOrder, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, model.VendorIDJX)
	if err != nil {
		dao.Rollback(db, txDB)
		return nil, err
	}
	// 通知退款,等待回传
	incoming, err := dao.GetStoreInfoByMerchantID(db, "", goodsOrder.JxStoreID, "", "")
	if err != nil {
		return nil, err
	}

	param := &lakala.RefundOrderQueryReq{
		MerchantNo:       incoming.MerchantNo,
		TermNo:           incoming.TermNo,
		OutTradeNo:       lakala.GetOrderNumber(8),
		OriginTradeDate:  afsOrder.AfsCreatedAt.Format("20060102"),
		OriginBizType:    "3",
		OriginTradeNo:    "",
		OriginTradeRefNo: "",
		OriginOutTradeNo: afsOrderID,
	}
	result, err := api.LaKaLaApi.RefundOrderQuery(param)
	if err != nil {
		return nil, err
	}
	for _, v := range result {
		if v.OutTradeNo == afsOrderID && v.TradeState == "SUCCESS" {
			afsOrder.Status = model.AfsOrderStatusFinished
			afsOrder.VendorStatus = v.TradeState
			afsOrder.AfsFinishedAt = time.Now()
			dao.UpdateEntity(db, afsOrder, "Status", "VendorStatus", "AfsFinishedAt")
		}
	}

	return result, err
}

// BarCodeScannerPayByLaKaLa 拉卡拉扫码枪扫码
func BarCodeScannerPayByLaKaLa(ctx *jxcontext.Context, vendorOrderId, userPaymentLabel, ip string) (*lakala.PayMicroPayResp, error) {
	db := dao.GetDB()
	goodsOrder, err := dao.GetSimpleOrder(db, vendorOrderId)
	if err != nil {
		return nil, err
	}
	if goodsOrder.VendorID != model.VendorIDJX {
		return nil, fmt.Errorf("此订单不是京西订单,无法使用该功能")
	}

	merchantObj, err := dao.GetStoreInfoByMerchantID(db, "", goodsOrder.JxStoreID, "", "")
	if err != nil {
		return nil, err
	}
	parma := &lakala.PayMicroPayReq{
		MerchantNo:  merchantObj.MerchantNo,
		TermNo:      merchantObj.TermNo,
		OutTradeNo:  goodsOrder.VendorOrderID,
		AuthCode:    userPaymentLabel,
		TotalAmount: utils.Int64ToStr(goodsOrder.ActualPayPrice),
		LocationInfo: lakala.LocationInfoObj{
			RequestIp: ip,
		},
		NotifyUrl:  lakala.PayStatusCallback,
		SettleType: "1",
		Subject:    fmt.Sprintf("感谢您在本店%s消费,欢迎下次再来", goodsOrder.StoreName),
	}
	resp, err := api.LaKaLaApi.ScannerPayMicroPay(parma)
	if err != nil {
		return nil, err
	}
	goodsOrder.Status = model.OrderStatusFinished
	goodsOrder.VendorStatus = lakala.PayStatusSUCCESS
	goodsOrder.VendorOrderID2 = resp.LogNo
	goodsOrder.OrderFinishedAt = time.Now()
	dao.UpdateEntity(db, goodsOrder, "Status", "VendorStatus", "OrderFinishedAt", "VendorOrderID2")

	payInfo := &model.OrderPay{
		PayOrderID:    resp.TradeNo,
		PayType:       model.PayTypeLaKaLa,
		VendorPayType: lakala.PayWayRegister,
		TransactionID: resp.LogNo,
		VendorOrderID: goodsOrder.VendorOrderID,
		VendorID:      goodsOrder.VendorID,
		Status:        0,
		PayCreatedAt:  time.Now(),
		PrepayID:      resp.TradeNo,
		CodeURL:       "",
		TotalFee:      int(goodsOrder.ActualPayPrice),
	}
	dao.WrapAddIDCULDEntity(payInfo, ctx.GetUserName())
	dao.CreateEntity(db, payInfo)

	separate := &model.LakalaSeparateAmt{
		MerchantNo:        merchantObj.MerchantNo2,
		VendorOrderID:     goodsOrder.VendorOrderID,
		StoreId:           goodsOrder.JxStoreID,
		CmdType:           lakala.SeparateType_SEPATRATE,
		Status:            "1",
		LogNo:             resp.LogNo,
		LogDate:           time.Now(),
		OutSeparateNo:     "",
		SeparateNo:        "",
		CalType:           "",
		FinishDate:        "",
		TotalAmt:          "",
		ActualSeparateAmt: "",
		TotalFeeAmt:       "",
		FinalStatus:       "",
		DetailData:        "",
		Remark:            "扫码枪支付",
	}
	dao.WrapAddIDCULEntity(separate, ctx.GetUserName())
	dao.CreateEntity(db, separate)

	return resp, err
}

// LaKaLaBarCodeScannerStatus 刷新当前订单的支付状态
func LaKaLaBarCodeScannerStatus(vendorOrderId string) (vendorStatus string, err error) {
	db := dao.GetDB()
	goodsOrder, err := dao.GetSimpleOrder(db, vendorOrderId)
	if err != nil {
		return "", err
	}
	if goodsOrder.VendorID != model.VendorIDJX {
		return "", fmt.Errorf("此订单不是京西订单,无法使用该功能")
	}

	merchantObj, err := dao.GetStoreInfoByMerchantID(db, "", goodsOrder.JxStoreID, "", "")
	if err != nil {
		return "", err
	}
	param := &lakala.PayStatusQueryReq{
		MerchantNo: merchantObj.MerchantNo,
		TermNo:     merchantObj.TermNo,
		OutTradeNo: goodsOrder.VendorOrderID,
		TradeNo:    "",
	}
	result, err := api.LaKaLaApi.PayStatusQuery(param)
	if err != nil {
		return "", err
	}

	switch result.TradeState {
	case lakala.PayStatusINIT, lakala.PayStatusCREATE, lakala.PayStatusDEAL:
		goodsOrder.Status = model.OrderStatusWaitPay
		goodsOrder.VendorStatus = lakala.PayStatusINIT
	case lakala.PayStatusSUCCESS, lakala.PayStatusPARTREFUND:
		goodsOrder.Status = model.OrderStatusFinished
		goodsOrder.VendorStatus = lakala.PayStatusSUCCESS
		goodsOrder.OrderFinishedAt = time.Now()
	case lakala.PayStatusFAIL, lakala.PayStatusCLOSE, lakala.PayStatusREFUND:
		goodsOrder.Status = model.OrderStatusCanceled
		goodsOrder.VendorStatus = lakala.PayStatusFAIL
		goodsOrder.OrderFinishedAt = time.Now()
	case lakala.PayStatusUNKNOWN:

	}
	dao.UpdateEntity(db, goodsOrder, "Status", "VendorStatus", "OrderFinishedAt")
	partner.CurOrderManager.OnOrderMsg(goodsOrder, result.TradeState, fmt.Sprintf("扫码枪扫码刷新结果:[code:%s,说明:%s,异常原因:%s],本地状态[%d]", result.TradeState, result.TradeStateDesc, "", goodsOrder.Status))

	return result.TradeStateDesc, err
}
