/**
 * 核心服务接口sdk（golang版）
 *
 * @desc 啪啪运动 核心服务接口sdk
 * ---------------------------------------------------------------------
 * @author		tang <unphp@qq.com>
 * @date		2020-06-18
 * @copyright	core-utils
 * ---------------------------------------------------------------------
 */
package cooper

import (
	"PPOSUtils/utils"
	"encoding/json"
	"errors"
	"net/url"
)

//NewPayWxAuthCodeRequest ... 微信支付（授权码）
func (that *CooperClient) NewPayWxAuthCodeRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/wxAuthCode",
		},
	}
}

//NewPayWxH5Request ... 微信支付（H5）
func (that *CooperClient) NewPayWxH5Request() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "pay/wxH5",
		},
	}
}

//NewPayWxNativeRequest ... 微信支付（Native）
func (that *CooperClient) NewPayWxNativeRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "pay/wxNative",
		},
	}
}

//NewPayAliAuthCodeRequest ... 支付宝支付（授权码）
func (that *CooperClient) NewPayAliAuthCodeRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/authCode",
		},
	}
}

//NewPayAliAuthCodeRequest ...会员一卡通支付（一卡通）
func (that *CooperClient) NewPayMemberCardRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/memberCard",
		},
	}
}

//NewPayMemberCardCountRequest ...会员一卡通扣次（一卡通）
func (that *CooperClient) NewPayMemberCardCountRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/memberCount",
		},
	}
}

//NewPayMoneyRequest ...会员支付（现金）
func (that *CooperClient) NewPayMoneyRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/money",
		},
	}
}

//NewPayPosRequest ...POS支付（pos机）
func (that *CooperClient) NewPayPosRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/pos",
		},
	}
}

//NewPayBulkRequest ...团购支付（团购券）
func (that *CooperClient) NewPayBulkRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/bulk",
		},
	}
}

//NewPayTransferRequest ...转账支付（转账）
func (that *CooperClient) NewPayTransferRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/transfer",
		},
	}
}

//NewPayWxJsUnifiedRequest ...微信支付（JsSDK）
func (that *CooperClient) NewPayWxJsUnifiedRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/wxJsUnified",
		},
	}
}

//NewPayWxMiniJsUnifiedRequest ...微信支付 - C端小程序
func (that *CooperClient) NewPayWxMiniJsUnifiedRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/wxMiniJsUnified",
		},
	}
}

//NewPayWxMiniJsECrapRequest ...微信支付 - 电商收付通 - C端小程序
func (that *CooperClient) NewPayWxMiniJsECrapRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/wxECrapMiniJs",
		},
	}
}

//NewPayClassCourseRequest ...课程课时卡支付方式
func (that *CooperClient) NewPayClassCourseRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/classCourse",
		},
	}
}

//NewPayUmsWebRequest ...银联支付 - web
func (that *CooperClient) NewPayUmsWebRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/umsWeb",
		},
	}
}

//NewPayUmsH5Request ...银联支付 - h5
func (that *CooperClient) NewPayUmsH5Request() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/umsH5",
		},
	}
}

//NewPayUmsOpenMiniRequest ...银联商务 - 小程序（开放平台）
func (that *CooperClient) NewPayUmsOpenMiniRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/umsOpenMini",
		},
	}
}

//NewPayUmsOpenWebRequest ...银联商务 - 公众号（开放平台）
func (that *CooperClient) NewPayUmsOpenWebRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/umsOpenWeb",
		},
	}
}

//NewPayUmsPosRequest ...银联支付 - pos
func (that *CooperClient) NewPayUmsPosRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/umsPos",
		},
	}
}

//NewPayUmsOpenPosRequest ...银联支付 - pos V4版本
func (that *CooperClient) NewPayUmsOpenPosRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/umsOpenPos",
		},
	}
}

//NewPayBookingRequest ...记账支付 - 通用
func (that *CooperClient) NewPayBookingRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/booking",
		},
	}
}

//NewPayAllPayPosRequest ... 聚合支付（pos扫码）
func (that *CooperClient) NewPayAllPayPosRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "pay/allPos",
		},
	}
}

//NewPayAllPayJsUnifiedRequest ... 聚合支付（微信公众号扫码）
func (that *CooperClient) NewPayAllPayJsUnifiedRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "pay/allJsUnified",
		},
	}
}

//NewPayGdCloudPayRequest ... 光大云缴费支付（小程序支付）
func (that *CooperClient) NewPayGdCloudPayRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "pay/gdCloudPay",
		},
	}
}

//NewPayPaPaCloudPayRequest ... 啪啪云支付（啪啪运动为支付服务商模式）
func (that *CooperClient) NewPayPaPaCloudPayRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "pay/papaCloudPay",
		},
	}
}

//NewPayIPosAuthCodeRequest ... 翼码支付（授权码）
func (that *CooperClient) NewPayIPosAuthCodeRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/iPosAuthCode",
		},
	}
}

//NewPayIPosJsUnifiedRequest ... 翼码支付（JDK、小程序支付）
func (that *CooperClient) NewPayIPosJsUnifiedRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/iPosJsUnified",
		},
	}
}

//NewPayIPosBcmRequest ... 翼码支付（银行卡支付）
func (that *CooperClient) NewPayIPosBcmRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/iPosBcm",
		},
	}
}

//NewPayRzCreateRequest ... 日照通：聚合支付（下单）
func (that *CooperClient) NewPayRzCreateRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/rzAllCreate",
		},
	}
}

//NewPayRechargeCardRequest ...充值卡支付（会员中台）
func (that *CooperClient) NewPayRechargeCardRequest() *PayRequest {
	return &PayRequest{
		Request: Request{
			Client: that,
			publicParamsSlice: []string{
				"order_no",
				//...
			},
			apiAddress: "/pay/rechargeCard",
		},
	}
}

//PayRequest
type PayRequest struct {
	Request
}

func (that *PayRequest) SetAuthCode(value string) *PayRequest {
	that.initParams()
	that.params.Set("auth_code", value) //授权支付码
	return that
}
func (that *PayRequest) SetTradeNo(value string) *PayRequest {
	that.initParams()
	that.params.Set("trade_no", value) //交易号
	return that
}
func (that *PayRequest) SetOrderNo(value string) *PayRequest {
	that.initParams()
	that.params.Set("order_no", value) //订单号
	return that
}
func (that *PayRequest) SetPrice(value string) *PayRequest {
	that.initParams()
	that.params.Set("price", value) //订单支付价格
	return that
}
func (that *PayRequest) SetOrderSubject(value string) *PayRequest {
	that.initParams()
	that.params.Set("order_subject", value) //订单标题
	return that
}
func (that *PayRequest) SetOrderInfo(value string) *PayRequest {
	that.initParams()
	that.params.Set("order_info", value) //订单详情
	return that
}
func (that *PayRequest) SetNotifyURL(value string) *PayRequest {
	that.initParams()
	that.params.Set("notify_url", value) //回调地址
	return that
}
func (that *PayRequest) SetWxOpenId(value string) *PayRequest {
	that.initParams()
	that.params.Set("wx_open_id", value) //jssdk的预支付
	return that
}
func (that *PayRequest) SetUserId(value string) *PayRequest {
	that.initParams()
	that.params.Set("user_id", value) //用户ID
	return that
}
func (that *PayRequest) SetMemberCardId(value string) *PayRequest {
	that.initParams()
	that.params.Set("member_card_id", value) //会员卡ID
	return that
}
func (that *PayRequest) SetMemberCardCount(value string) *PayRequest {
	that.initParams()
	that.params.Set("price", value) //会员卡次数 => price:1次
	return that
}
func (that *PayRequest) SetPassWord(value string) *PayRequest {
	that.initParams()
	that.params.Set("password", value) //会员卡密码
	return that
}
func (that *PayRequest) SetOrderFrom(value int64) *PayRequest {
	that.initParams()
	that.params.Set("order_from", utils.ToString(value)) //订单来源
	return that
}
func (that *PayRequest) SetReturnUrl(value string) *PayRequest {
	that.initParams()
	that.params.Set("return_url", value) //支付完成后跳转
	return that
}
func (that *PayRequest) SetPaymentWay(value string) *PayRequest {
	that.initParams()
	that.params.Set("payment_way", value) //支付方式,例如60，70等
	return that
}
func (that *PayRequest) SetPaymentType(value string) *PayRequest {
	that.initParams()
	that.params.Set("payment_type", value) //支付类型，例如JSAPI、authcode等
	return that
}
func (that *PayRequest) SetTimeExpire(value string) *PayRequest {
	that.initParams()
	that.params.Set("time_expire", value) //订单失效时间，遵循rfc3339标准格式，格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE
	return that
}
func (that *PayRequest) SetDeviceType(value string) *PayRequest {
	that.initParams()
	that.params.Set("device_type", value) //光大云缴费： 设备类型，1：PC个人电脑 2：手机终端 3：微信公众号 4：扫码缴费（支持微信和支付宝扫码支付） 5：微信小程序 6：支付宝服务商支付
	return that
}
func (that *PayRequest) SetExtendField(value string) *PayRequest {
	that.initParams()
	that.params.Set("extend_field", value) //扩展字段，存放一些扩展的信息:比如内部支付的一些公共字段、支付类型渠道等
	return that
}

func (that *PayRequest) SetTConfigId(value int64) *PayRequest {
	that.initParams()
	that.params.Set("t_config_id", utils.ToString(value)) //支付账户配置ID
	return that
}

func (that *PayRequest) SetProfitSharingConf(value string) *PayRequest {
	that.initParams()
	that.params.Set("profit_sharing_conf", value) //分账方案配置
	return that
}
func (that *PayRequest) SetIp(value string) *PayRequest {
	that.initParams()
	that.params.Set("ip", value) //客户端ip
	return that
}

func (that *PayRequest) UmsOpenWeb() {
	that.apiAddress = "/pay/umsOpenWeb"
}

//Params ...
func (that *PayRequest) Params() (url.Values, error) {
	that.initParams()
	_params := that.params
	if that.publicParamsSlice != nil {
		for _, _v := range that.publicParamsSlice {
			if _params.Get(_v) == "" {
				return nil, errors.New(that.apiAddress + "缺少参数:" + _v)
			}
		}
	}
	return _params, nil
}

//支付相应体
type PayResponse struct {
	//公共参数：订单基础信息
	OrderNo     interface{} `json:"order_no"`     //订单号（要保证唯一）
	TradeNo     interface{} `json:"trade_no"`     //交易号（要保证唯一）
	PaymentType interface{} `json:"payment_type"` //支付类别：6微信，7支付宝
	PaymentWay  interface{} `json:"payment_way"`  //支付渠道
	Price       interface{} `json:"price"`        //到帐金额，单位：分
	MerchantNo  string      `json:"merchant_no"`  //商户号

	//公共参数：交易状态
	TransactionStatus string `json:"transaction_status"` //交易状态
	TransactionCode   string `json:"transaction_code"`   //交易错误码
	TransactionMsg    string `json:"transaction_msg"`    //交易提示

	//微信支付jsAPI返回
	PrepayId  string `json:"prepay_id"` //预支付交易会话标识
	PaySign   string `json:"pay_sign"`  //签名
	NonceStr  string `json:"nonce_str"` //随机字符串
	Timestamp string `json:"timestamp"` //时间戳
	SignType  string `json:"sign_type"` //签名类型

	//微信authCode支付返回
	OpenId string `json:"open_id"` //open_id

	//微信Native支付返回
	CodeUrl string `json:"code_url"` //code_url

	//微信H5支付返回
	MwebUrl string `json:"mweb_url"` //mweb_url

	//云缴费小程序支付返回
	WxAppId string `json:"wx_app_id"` //小程序支付所需appId
	Path    string `json:"path"`      //小程序收银台支付路径

	//PaymentWay为6、7（微信支付/支付宝）
	OutTransactionNo    string `json:"out_transaction_no"`    //交易号
	OutTransactionPayer string `json:"out_transaction_payer"` //第三方号

	//PaymentWayExt为90-1（会员卡），90-2（会员卡次卡）
	MemberId        int64  `json:"member_id"`          //会员ID
	MemberCardId    int64  `json:"member_card_id"`     //会员卡ID
	BuyMemberId     int64  `json:"buy_member_id"`      //会员ID(办理人)
	BuyMemberCardId int64  `json:"buy_member_card_id"` //会员卡ID(办理人)
	CardNum         string `json:"card_num"`           //会员卡号
	PCardNum        string `json:"p_card_num"`         //物理卡号
	Name            string `json:"name"`               //会员名称
	Phone           string `json:"phone"`              //手机号
}

//Do ...
func (that *PayRequest) Do() (*PayResponse, error) {
	//返回data
	_data, _err := that.Client.Post(that.apiAddress, that)
	if _err != nil {
		return nil, _err
	}
	//
	_slice := []string{
		//...
	}
	//
	_sliceData, _ok := _data.(map[string]interface{})
	if !_ok {
		return nil, errors.New(that.apiAddress + "请求响应格式不正确")
	}
	//
	for _, _val := range _slice {
		if _, _ok := _sliceData[_val]; !_ok {
			return nil, errors.New(that.apiAddress + "请求响应参数不正确")
		}
	}
	//
	_str, _err := json.Marshal(_sliceData)
	if _err != nil {
		return nil, errors.New(that.apiAddress + "Umarshal failed!" + _err.Error())
	}
	//返回结果
	_rs := new(PayResponse)
	_err = json.Unmarshal(_str, &_rs)
	_rs.TradeNo = utils.ToString(_rs.TradeNo, true)
	if _err != nil {
		return _rs, errors.New(that.apiAddress + "Umarshal failed2!" + _err.Error())
	}
	return _rs, nil
}
