package com.liquidnet.service.goblin.service.impl;

import com.huifu.bspay.sdk.opps.core.BasePay;
import com.huifu.bspay.sdk.opps.core.config.MerConfig;
import com.huifu.bspay.sdk.opps.core.net.BasePayRequest;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.goblin.config.properties.AppProperties;
import com.liquidnet.service.goblin.param.dougong.DougongJsPayData;
import com.liquidnet.service.goblin.param.dougong.DougongRequestParam;
import com.liquidnet.service.goblin.service.IGoblinDougongPayService;
import com.liquidnet.service.goblin.util.DougongSignUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Map;

@Slf4j
@Service
public class GoblinDougongPayServiceImpl implements IGoblinDougongPayService {

    private final AppProperties.AppInfo appInfo;

    public GoblinDougongPayServiceImpl(AppProperties appProperties) {
        this.appInfo = appProperties.getApps().get("dougong");
        if (this.appInfo == null) {
            throw new IllegalArgumentException("找不到应用配置");
        }
    }


    @PostConstruct
    public void init() {
        MerConfig merConfig = new MerConfig();
        merConfig.setProcutId(appInfo.getProductId());
        merConfig.setSysId(appInfo.getSysId());
        merConfig.setRsaPrivateKey(appInfo.getPrivateKey());
        merConfig.setRsaPublicKey(appInfo.getPublicKey());
        try {
            BasePay.initWithMerConfig(merConfig);
        } catch (Exception e) {
            log.error("初始化支付配置失败", e);
            throw new RuntimeException("初始化支付配置失败", e);
        }
    }

    @Override
    public Map<String, Object> jsPay(DougongJsPayData data) {
        DougongRequestParam requestParam = buildDougongRequestParam(data);
        log.info("request param: {}.", JsonUtils.toJson(requestParam));
        if (requestParam == null) {
            log.error("构建下单参数失败");
            return null;
        }
        try {
            Map<String, Object> map = JsonUtils.fromJson(JsonUtils.toJson(requestParam), Map.class);
            //3. 发起API调用
            Map<String, Object> response = BasePayRequest.requestBasePay("v3/trade/payment/jspay", map, null, false);
            log.info("response: {}.", JsonUtils.toJson(response));
            if (response != null && "00000100".equals(response.get("resp_code"))
                    && "P".equals(response.get("trans_stat"))){
                return response;
            }
        } catch (Exception e) {
            log.error("error", e);
        }
        return null;
    }

    @Override
    public boolean verifySign(String data, String sign) {
        boolean verify = DougongSignUtils.verify(data, appInfo.getPublicKey(), sign);
        return verify;
    }

    private DougongRequestParam buildDougongRequestParam(DougongJsPayData data){
        if (data == null) {
            return null;
        }
        DougongRequestParam requestParam = new DougongRequestParam();
        requestParam.setReqDate(data.getReqDate());
        requestParam.setReqSeqId(data.getReqSeqId());
        requestParam.setHuifuId(appInfo.getHuifuId());
        requestParam.setGoodsDesc(data.getGoodsDesc());
        requestParam.setTradeType(data.getTradeType());
        requestParam.setTransAmt(data.getTransAmt());
        requestParam.setTimeExpire(data.getTimeExpire());
        requestParam.setWxData(buildWxData(data));
        requestParam.setNotifyUrl(appInfo.getNotifyUrl());
        return requestParam;
    }

    private String buildWxData(DougongJsPayData data) {
        DougongRequestParam.WxData wxData = new DougongRequestParam.WxData();
        wxData.setSubAppid(appInfo.getSubAppId());
        wxData.setSubOpenid(data.getSubOpenid());
        wxData.setBody(data.getGoodsDesc());
        wxData.setDetail(buildWxDataDetail(data));
        return JsonUtils.toJson(wxData);
    }

    private DougongRequestParam.WxDataDetail buildWxDataDetail(DougongJsPayData data) {
        DougongRequestParam.WxDataDetail wxDataDetail = new DougongRequestParam.WxDataDetail();
        wxDataDetail.setCostPrice(data.getTransAmt());
        wxDataDetail.setGoodsDetail(data.getGoodsDetailList());
        return wxDataDetail;
    }
}
