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

import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.dragon.channel.strategy.biz.DragonPayBiz;
import com.liquidnet.service.dragon.channel.strategy.impl.PayChannelStrategyWepayImpl;
import com.liquidnet.service.dragon.channel.wepay.biz.WepayBiz;
import com.liquidnet.service.dragon.channel.wepay.resp.WepayPayRespDto;
import com.liquidnet.service.dragon.channel.wepay.strategy.annotation.StrategyWepayHandler;
import com.liquidnet.service.dragon.constant.DragonConstant;
import com.liquidnet.service.dragon.constant.DragonErrorCodeEnum;
import com.liquidnet.service.dragon.dto.DragonOrdersDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseRespDto;
import com.liquidnet.service.dragon.dto.DragonPayOrderQueryRespDto;
import com.liquidnet.service.dragon.utils.DataUtils;
import com.liquidnet.service.dragon.utils.PayWepayUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * @author AnJiabin <anjiabin@zhengzai.tv>
 * @version V1.0
 * @Description: TODO
 * @class: AlipayStrategyWapImpl
 * @Package com.liquidnet.service.dragon.channel.alipay.strategy.impl
 * @Copyright: LightNet @ Copyright (c) 2021
 * @date 2021/7/10 14:34
 */
@Slf4j
@Component
@StrategyWepayHandler(DragonConstant.DeviceFromEnum.MICROPAY)
public class WepayStrategyMicropayImpl extends AbstractWepayStrategy {
    @Value("${liquidnet.dragon.url}")
    private String notifyUrl;
    @Autowired
    private DataUtils dataUtils;
    @Autowired
    private WepayBiz wepayBiz;
    @Autowired
    private DragonPayBiz dragonPayBiz;
    @Autowired
    private PayChannelStrategyWepayImpl payChannelStrategyWepay;

    @Override
    SortedMap<String, Object> appendRequestParam(SortedMap<String, Object> requestMap,DragonPayBaseReqDto dragonPayBaseReqDto) {
        requestMap.put("trade_type", "MICROPAY");
        requestMap.put("appid", PayWepayUtils.getInstance().getAPP_ID());
        requestMap.remove("notify_url");
        requestMap.put("auth_code",dragonPayBaseReqDto.getAuthCode());
        return requestMap;
    }

    @Override
    DragonPayBaseRespDto buildResponseDto(DragonPayBaseRespDto payBaseRespDto, WepayPayRespDto respDto) {
        payBaseRespDto.getPayData().setPackages("Sign=WXPay");
        //设置签名
        SortedMap<String, Object> paramMap = new TreeMap<String, Object>();
        paramMap.put("appid", payBaseRespDto.getPayData().getAppId());
        paramMap.put("partnerid", payBaseRespDto.getPayData().getPartnerId());
        paramMap.put("prepayid", payBaseRespDto.getPayData().getPrepayId());
        paramMap.put("package", payBaseRespDto.getPayData().getPackages());
        paramMap.put("noncestr", payBaseRespDto.getPayData().getNonceStr());
        paramMap.put("timestamp", payBaseRespDto.getPayData().getTimeStamp());
        log.info("wepay sercond sign param :{} ", JsonUtils.toJson(paramMap));
        String sign = PayWepayUtils.getInstance().createSign(paramMap);
        payBaseRespDto.getPayData().setPaySign(sign);
        return payBaseRespDto;
    }

    @Override
    protected String getRequestUrl() {
        return "https://api.mch.weixin.qq.com/pay/micropay";
    }

    @Override
    protected String getNotifyUrl() {
        return notifyUrl + "";
    }

    @Override
    protected String getAppid() {
        return PayWepayUtils.getInstance().getAPP_ID();
    }
    @Override
    public DragonPayOrderQueryRespDto checkOrderStatus(String code) {
        DragonOrdersDto ordersDto = dataUtils.getPayOrderByCode(code);
        //持久化通知记录
        // 根据银行订单号获取支付信息
        DragonOrdersDto dragonOrdersDto = dataUtils.getPayOrderByCode(code);
        if (dragonOrdersDto == null) {
            throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_ERROR_NOT_EXISTS.getCode(),DragonErrorCodeEnum.TRADE_ERROR_NOT_EXISTS.getMessage());
        }
        if (DragonConstant.PayStatusEnum.STATUS_PAID.getCode().equals(dragonOrdersDto.getStatus())) {
            throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_ERROR_HAS_PAID.getCode(),DragonErrorCodeEnum.TRADE_ERROR_HAS_PAID.getMessage());
        }

        Map<String, String> resultMap = wepayBiz.tradeQueryString(code,this.getAppid());
        DragonPayOrderQueryRespDto respDto = dragonPayBiz.buildPayOrderQueryRespDto(ordersDto);
        Object returnCode = resultMap.get("return_code");
        // 查询失败
        if (null == returnCode || "FAIL".equals(returnCode)) {
            throw new LiquidnetServiceException(DragonErrorCodeEnum.TRADE_WEPAY_QUERY_ERROR.getCode(),DragonErrorCodeEnum.TRADE_WEPAY_QUERY_ERROR.getMessage());
        }
        // 当trade_state为SUCCESS时才返回result_code
        if ("SUCCESS".equals(resultMap.get("trade_state"))) {
            if(PayWepayUtils.getInstance().notifySign(resultMap, resultMap.get("sign"))){
                // 修改订单状态等。
                payChannelStrategyWepay.completeSuccessOrder(dragonOrdersDto,resultMap.get("transaction_id"), LocalDateTime.now(),resultMap.toString());
                respDto.setStatus(Integer.valueOf(DragonConstant.PayStatusEnum.STATUS_PAID.getCode()));
            }else{
                payChannelStrategyWepay.completeFailOrder(dragonOrdersDto,resultMap.toString());
            }
        }
        return respDto;
    }

}
