package com.hai.config;

import com.alibaba.fastjson.JSONObject;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.utils.HttpsUtils;
import com.hai.enum_type.TripartiteReqLogReqType;
import com.hai.enum_type.TripartiteReqLogType;
import com.hai.service.BsTripartiteReqLogService;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.security.*;
import java.util.HashMap;
import java.util.Map;

/**
 * 金猪加油服务
 */
@Component
public class JinZhuJiaYouService {

    private final static String reqUrl = "http://api.jianshiyun.com/api/gateway";

    private final static String appId = CommonSysConst.getSysConfig().getJzAppId();

    private final static String privateKeyUrl = CommonSysConst.getSysConfig().getJzPrivateKeyUrl();

    private final static String publicKeyUrl = CommonSysConst.getSysConfig().getJzPublicKeyUrl();

    @Resource
    private BsTripartiteReqLogService reqLogService;

    /**
     * 查询加油站列表
     * @param pageNum 分页页数 默认为0，从0开始
     * @param pageSize 每页数量，最大100条
     * @return
     * @throws Exception
     */
    public JSONObject getStationListPage(Integer pageNum, Integer pageSize) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("requestNo", System.currentTimeMillis()+"");
        param.put("page", pageNum);
        param.put("size", pageSize);
        return request("STATION_TREE_PAGE", param);
    }

    /**
     * 查询加油站列表
     * @param stationCode 油站编号
     * @return
     * @throws Exception
     */
    public JSONObject getStationDetail(String stationCode) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("requestNo", System.currentTimeMillis()+"");
        param.put("code", stationCode);
        return request("STATION_VIEW", param);
    }

    /**
     * 创建加油订单
     * @param merchantOrderNo   订单号
     * @param orderAmount       加油金额
     * @param stationCode       油站code
     * @param oilNo             油号
     * @param gunNo             枪号
     * @param userMobile        用户手机号
     * @return
     * @throws Exception
     */
    public JSONObject createOrder(String merchantOrderNo,
                                         BigDecimal orderAmount,
                                         String stationCode,
                                         String oilNo,
                                         String gunNo,
                                         String userMobile) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("requestNo", System.currentTimeMillis()+"");
        param.put("merchantOrderNo", merchantOrderNo);
        param.put("orderAmount", orderAmount);
        param.put("stationCode", stationCode);
        param.put("oilNo", oilNo);
        param.put("gunNo", gunNo);
        param.put("userMobile", userMobile);
        return request("ORDER_CREATE", param);
    }

    /**
     * 查询加油站列表
     * @param merchantOrderNo   订单号
     * @param paymentAmount
     * @return
     * @throws Exception
     */
    public JSONObject payOrder(String merchantOrderNo, BigDecimal paymentAmount) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("requestNo", System.currentTimeMillis()+"");
        param.put("merchantOrderNo", merchantOrderNo);
        param.put("paymentAmount", paymentAmount);
        return request("ORDER_PAYMENT", param);
    }

    /**
     * 接口请求
     * @param param  参数
     * @return
     * @throws Exception
     */
    private JSONObject request(String service, Map<String,Object> param) throws Exception {
        // 请求头部
        Map<String, Object> heard = new HashMap<>();
        heard.put("Request-App-Id", appId);
        heard.put("Request-Service-Name", service);
        heard.put("Request-Signature", generateSign(param));

        JSONObject repsObject = HttpsUtils.doPost(reqUrl, param, heard);
        reqLogService.insert(
                TripartiteReqLogType.type8,
                MapUtils.getString(param, "requestNo"),
                TripartiteReqLogReqType.type1,
                reqUrl,
                JSONObject.toJSONString(heard),
                repsObject.toString()
        );
        if (repsObject == null
                || !repsObject.getInteger("status").equals(200)
                || !repsObject.getString("type").equals("OK")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, repsObject == null?"请求失败":repsObject.getString("detail"));
        }
        return repsObject;
    }

    /**
     * 生成签名
     * @param data
     * @return
     * @throws Exception
     */
    private static String generateSign(final Map<String, Object> data) throws IOException {
        PrivateKey privateKey = PemUtil.loadPrivateKey(new FileInputStream(privateKeyUrl));
        String signStr = null;
        try {
            Signature sign = Signature.getInstance("SHA256withRSA");
            sign.initSign(privateKey);
            sign.update(JSONObject.toJSONString(data).getBytes("utf-8"));
            signStr = java.util.Base64.getEncoder().encodeToString(sign.sign());
        } catch (SignatureException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return signStr;
    }

}
