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

import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.dragon.biz.DragonServiceCommonBiz;
import com.liquidnet.service.dragon.channel.alipay.req.AlipayTradePayReq;
import com.liquidnet.service.dragon.channel.alipay.strategy.IAlipayStrategy;
import com.liquidnet.service.dragon.channel.strategy.biz.DragonPayBiz;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseRespDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Map;

/**
 * @author AnJiabin <anjiabin@zhengzai.tv>
 * @version V1.0
 * @Description: TODO
 * @class: AbstractAlipayStrategy
 * @Package com.liquidnet.service.dragon.channel.alipay.strategy.impl
 * @Copyright: LightNet @ Copyright (c) 2021
 * @date 2021/7/12 12:36
 */
@Slf4j
public abstract class AbstractAlipayStrategy implements IAlipayStrategy {

    @Autowired
    private DragonPayBiz dragonPayBiz;

    @Autowired
    private DragonServiceCommonBiz dragonServiceCommonBiz;


    protected String productCode = "QUICK_WAP_PAY";

    @Override
    public ResponseDto<DragonPayBaseRespDto> dragonPay(DragonPayBaseReqDto dragonPayBaseReqDto) {
        //设置productCode
        setProductCode();

        AlipayTradePayReq alipayTradePayReq = AlipayTradePayReq.getNew();
        alipayTradePayReq.setProductCode(this.productCode);
        alipayTradePayReq.setTotalAmount(dragonPayBaseReqDto.getPrice());
        alipayTradePayReq.setSubject(dragonPayBaseReqDto.getName());
        alipayTradePayReq.setBody(dragonPayBaseReqDto.getDetail());
        //dragon中支付编号
        alipayTradePayReq.setOutTradeNo(dragonPayBaseReqDto.getCode());
        //设置订单过期时间
        String timeExpire = DateUtil.format(DateUtil.Formatter.yyyyMMddHHmmss.parse(dragonPayBaseReqDto.getCreateDate()).plusMinutes(Long.parseLong(dragonPayBaseReqDto.getExpireTime())),DateUtil.Formatter.yyyyMMddHHmmss);
        alipayTradePayReq.setTimeExpire(timeExpire);
        alipayTradePayReq.setNotifyUrl(this.getNotifyUrl());
        alipayTradePayReq.setTimestamp(dragonPayBaseReqDto.getCreateDate());
        alipayTradePayReq.setAuthCode(dragonPayBaseReqDto.getAuthCode());

        //调用支付
        long startTime = System.currentTimeMillis();
        Map<String, Object> result = this.executePay(alipayTradePayReq);
//        log.info("dragonPay:alipay:"+dragonPayBaseReqDto.getDeviceFrom()+" response xmlStr: {} ", JSON.toJSONString(result));
        log.info("alipay-dragonPay->耗时:{}",(System.currentTimeMillis() - startTime)+"毫秒");
        if(null!=result.get("code")&&result.get("code").toString().equals("40004")){
            return null;
        }
        //拼接返回参数
        DragonPayBaseRespDto respDto = buildCommonRespDto(dragonPayBaseReqDto);
        respDto = this.buildResponseDto(respDto,result);

        //支付订单持久化
        dragonServiceCommonBiz.buildPayOrders(dragonPayBaseReqDto,null);

        return ResponseDto.success(respDto);
    }

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

    /**
     * 设置productCode
     */
    protected abstract void setProductCode();

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

    /**
     * 构造公共返回参数
     * @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;
    }

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

}
