package com.liquidnet.service.dragon.channel.unionpay.strategy.impl;

import com.alibaba.fastjson.JSON;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.dragon.biz.DragonServiceCommonBiz;
import com.liquidnet.service.dragon.channel.strategy.biz.DragonPayBiz;
import com.liquidnet.service.dragon.channel.unionpay.req.UnionpayTradePayReq;
import com.liquidnet.service.dragon.channel.unionpay.sdk.SDKConfig;
import com.liquidnet.service.dragon.channel.unionpay.sdk.SDKConstants;
import com.liquidnet.service.dragon.channel.unionpay.strategy.IUnionpayStrategy;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseRespDto;
import com.liquidnet.service.dragon.dto.DragonPayOrderQueryRespDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.math.BigDecimal;
import java.util.Map;

/**
 * @author AnJiabin <anjiabin@zhengzai.tv>
 * @version V1.0
 * @Description: TODO
 * @class: AbstractUnionPayStrategy
 * @Package com.liquidnet.service.dragon.channel.unionpay.strategy.impl
 * @Copyright: LightNet @ Copyright (c) 2021
 * @date 2021/11/08 18:36
 */
@Slf4j
public abstract class AbstractUnionPayStrategy implements IUnionpayStrategy {

    @Autowired
    private DragonPayBiz dragonPayBiz;

    @Autowired
    private SDKConfig sdkConfig;

    @Autowired
    private DragonServiceCommonBiz dragonServiceCommonBiz;

    @Value("${liquidnet.dragon.unionpay.merchantId}")
    private String merchantId;

    @Override
    public ResponseDto<DragonPayBaseRespDto> dragonPay(DragonPayBaseReqDto dragonPayBaseReqDto) {
        try {
//构造公共请求参数
            UnionpayTradePayReq payReq = this.buildRequestParamMap(dragonPayBaseReqDto);
            //构造个性化参数
            payReq = this.appendRequestParam(payReq,dragonPayBaseReqDto);

            //调用支付
            long startTime = System.currentTimeMillis();
            Map<String, String> result = this.executePay(payReq);
            log.debug("dragonPay:unionpay:"+dragonPayBaseReqDto.getDeviceFrom()+" response : {} ", JSON.toJSONString(result));
            log.info("unionpay-dragonPay->耗时:{}",(System.currentTimeMillis() - startTime)+"毫秒");
            //拼接返回参数
            DragonPayBaseRespDto respDto = buildCommonRespDto(dragonPayBaseReqDto);
            respDto = this.buildResponseDto(respDto,result);
            //支付订单持久化
            dragonServiceCommonBiz.buildPayOrders(dragonPayBaseReqDto,null);
            return ResponseDto.success(respDto);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 支付请求
     * @param payReq
     * @return
     */
    protected abstract Map<String, String> executePay(UnionpayTradePayReq payReq);

    /**
     * 设置notifyUrl
     */
    protected abstract String getNotifyUrl();


    /**
     * 构造请求参数
     * @param dragonPayBaseReqDto
     * @return
     */
    protected UnionpayTradePayReq buildRequestParamMap(DragonPayBaseReqDto dragonPayBaseReqDto){
        UnionpayTradePayReq payReq = UnionpayTradePayReq.getNew();
        payReq.setVersion(sdkConfig.getVersion());
        payReq.setEncoding(SDKConstants.UTF_8_ENCODING);
        payReq.setSignMethod(sdkConfig.getSignMethod());
        payReq.setTxnType("01");
        payReq.setTxnSubType("01");
        payReq.setBizType("000201");
        payReq.setChannelType("08");
        payReq.setMerId(merchantId);
        payReq.setAccessType("0");
        payReq.setOrderId(dragonPayBaseReqDto.getCode());
        payReq.setTxnTime(dragonPayBaseReqDto.getCreateDate());
        payReq.setTxnAmt(dragonPayBaseReqDto.getPrice().multiply(BigDecimal.valueOf(100L)).intValue()+"");
        payReq.setCurrencyCode("156");
        payReq.setBackUrl(this.getNotifyUrl());
        return payReq;
    };

    /**
     * 追加请求参数
     * @param payReq
     * @return
     */
    abstract UnionpayTradePayReq appendRequestParam(UnionpayTradePayReq payReq,DragonPayBaseReqDto dragonPayBaseReqDto);


    /**
     * 构造公共返回参数
     * @param dragonPayBaseReqDto
     * @return
     */
    protected DragonPayBaseRespDto buildCommonRespDto(DragonPayBaseReqDto dragonPayBaseReqDto){
        DragonPayBaseRespDto respDto = new DragonPayBaseRespDto();
        respDto.setPayType(dragonPayBaseReqDto.getPayType());
        respDto.setCode(dragonPayBaseReqDto.getCode());
        respDto.setOrderCode(dragonPayBaseReqDto.getOrderCode());
        DragonPayBaseRespDto.PayData payData = new DragonPayBaseRespDto.PayData();
        respDto.setPayData(payData);
        return respDto;
    }

    @Override
    public DragonPayOrderQueryRespDto checkOrderStatus(String code) {
        return null;
    }

    /**
     * 构造返回参数
     */
    abstract DragonPayBaseRespDto buildResponseDto(DragonPayBaseRespDto payBaseRespDto,Map<String, String> respResult);

}
