package com.iformall.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * 停简单 停车管理
 */
@Component
public class TJDCarUtil {

    private final static Logger logger = LoggerFactory.getLogger(TJDCarUtil.class);

    private static String baseurl = "http://prep.tingjiandan.com/openapi/gateway";

    private static String partner = "7dbc8ec9037d403b822cb60addfdc681";
    private static String key     = "f356cb1bf5a74fb7a564e86128d2c49f";
    private static String version = "1.0";

    public static void main(String[] args) throws Exception {
        String carNumber = "京HLTT01";

        String result = infoForFreeMins(baseurl, partner, key, version, carNumber);

        JSONObject obj = JSON.parseObject(result);
        /*

        Map<String, String> paramMap1 = MapUtil.getOrderMap();
        paramMap1.put("tradeId", obj.getString("tradeId"));
        paramMap1.put("deductionAmount", obj.getString("totalAmount"));
        paramMap1.put("outTradeNo", "utf-8");
        paramMap1.put("accountId", obj.getString("accountId"));
        paramMap1.put("charset", "utf-8");
        paramMap1.put("partner", partner);
        paramMap1.put("version", version);

        deductionNotSettle(baseurl, key, paramMap1);
        */
    }

    /**
     * md5算法
     * @param data
     * @return
     * @throws NoSuchAlgorithmException
     */

    public static String md5(String data) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(data.getBytes());
        StringBuffer buf = new StringBuffer();
        byte[] bits = md.digest();
        for(int i=0;i<bits.length;i++){
            int a = bits[i];
            if(a<0) a+=256;
            if(a<16) buf.append("0");
            buf.append(Integer.toHexString(a));
        }
        return buf.toString();
    }

    /**
     * getCurrentDate 获取当前时间
     */
    public static String getCurrentDate() {
        Date currentDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String  timestamp = sdf.format(currentDate);
        return timestamp;
    }

    /**
     * 签名
     * @param map
     * @param keysign
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static String getSign(Map<String,String> map, String keysign) throws NoSuchAlgorithmException {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (entry.getValue() != null || entry.getValue() != "") {
                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }
        sb.deleteCharAt(sb.length()-1);// ?
        sb.append(keysign);
        logger.debug("签名前的字符串输出："+sb.toString());
        String signValue = md5(sb.toString()).toUpperCase();
        logger.debug("sign: " + signValue);
        return signValue;
    }

    /**
     * 注册车牌
     * @param url
     * @param partner
     * @param key     // 密钥
     * @param version
     *
     *  {
     *    "carNum": "京A45781",
     *    "carNumColor": "blue",
     *    "phone": "15210501514",
     *    "outCarId": "45454545454",
     *    "partner": "5836b8b52ada463ebc6199579f029566",
     *    "timestamp": "2016-05-26 11:30:10",
     *    "version": "1.0"
     *  }
     * @throws Exception
     */
    public static String registerCar(String url, String partner, String key, String version,
                                     String carNum, String carNumColor, String phone, String outCarId) {
        String service = "parkhub.car.register";

        Map<String, String> paramMap = MapUtil.getOrderMap();
        paramMap.put("carNum", carNum);
        paramMap.put("carNumColor", carNumColor);
        if (phone != null) {
            paramMap.put("phone", phone);
        }
        if (outCarId != null) {
            paramMap.put("outCardId", outCarId);
        }
        paramMap.put("charset", "utf-8");
        paramMap.put("partner", partner);
        paramMap.put("version", version);

        String result = Proc(url, key, service, paramMap);

        /*
        {
            "timestamp": "1464235239561",
            "returnCode": "T",
            "errorMsg": "",
            "returnMsg": "OK",
            "isSuccess": "0",
            "carId": "5836b8b52ada463ebc6199579f029561"
         }*/
        return result;
    }

    /**
     * 注销车牌
     * @param url
     * @param partner
     * @param key     // 密钥
     * @param version
     *
     *  {
     *    "service": "parkhub.car.writeOff",
     *    "version":"1.0",
     *    "sign":"3347b109a1e44f3fd5baa78b74a84948",
     *    "partner":"5836b8b52ada463ebc6199579f029566",
     *    "carId":"3347b109a1e44f3fd5baa78b74a84948",
     *    "timestamp":"2016-05-26 11:30:10",
     *    "charset":"utf-8",
     *    "signType":"md5"
     *  }
     * @throws Exception
     */
    public static String writeOffCar(String url, String partner, String key, String version,
                                     String carId) {
        String service = "parkhub.car.writeOff";

        Map<String, String> paramMap = MapUtil.getOrderMap();
        paramMap.put("carId", carId);
        paramMap.put("charset", "utf-8");
        paramMap.put("partner", partner);
        paramMap.put("version", version);

        String result = Proc(url, key, service, paramMap);

        /*
        {
            "timestamp": "1464235239561",
            "returnCode": "T",
            "errorMsg": "",
            "returnMsg": "OK",
            "isSuccess": "0",
         }*/
        return result;
    }


    /**
     * 在场订单查询
     * @param url
     * @param partner
     * @param key     // 密钥
     * @param version
     *
     *  {
     *    "carNum": "京A45781",
     *    "freeMins": "0",
     *    "partner": "5836b8b52ada463ebc6199579f029566",
     *    "pmParkId": "5836b8b52ada463ebc6199579f029565",
     *    "timestamp": "2016-05-26 11:30:10",
     *    "tradeId": "5836b8b52ada463ebc6199579f029565",
     *    "version": "1.0"
     *  }
     * @throws Exception
     */
    public static String infoForFreeMins(String url, String partner, String key, String version, String carNum) {
        String service = "parkhub.order.infoForFreeMins";

        String freeMins = "0";

        Map<String, String> paramMap = MapUtil.getOrderMap();
        paramMap.put("carNum", carNum);
        //paramMap.put("carNumColor", "");
        //paramMap.put("pmParkId", "");
        paramMap.put("freeMins", freeMins);
        //paramMap.put("tradeId", "");
        paramMap.put("charset", "utf-8");
        paramMap.put("partner", partner);
        paramMap.put("version", version);

        String result = Proc(url, key, service, paramMap);

        /*
        "{
        \"wLon\":\"116.310335\",
        \"returnCode\":\"T\",
        \"lon\":\"116.316819\",
        \"accountId\":\"5b3c15e15235486eba9abae41ae3f820\",
        \"freeThroughTime\":\"30\",
        \"customerServicePhone\":\"400-001-0606\",
        \"tradeId\":\"3a3475c501f8464cbb3ff1b6670690d6\",
        \"returnMsg\":\"OK\",
        \"outDt\":\"20180609164753\",
        \"isSuccess\":\"0\",
        \"pmParkId\":\"7715622dff834b34a44448b801c27607\",
        \"unPayAmount\":\"12.00\",
        \"timestamp\":\"1528534070691\",
        \"errorMSG\":\"\",
        \"parkTime\":\"107273\",
        \"wLat\":\"39.93609\",
        \"totalAmount\":\"12.00\",
        \"paidAmount\":\"0.00\",
        \"freeMinsAmount\":\"0\",
        \"payUrl\":\"https://prep.tingjiandan.com/tcweixin/letter/prePay/payInPark.html?prePayType=16&channel=30040&isShowDetail=true&orderId=3a3475c501f8464cbb3ff1b6670690d6\",
        \"lat\":\"39.942078\",
        \"inDt\":\"20180608110000\"
        }\n";
        */
        return result;
    }

    /**
     * deductionNotSettle 停车费无结算抵扣
     * @param url
     * @param partner
     * @param key     // 密钥
     * @param version
     *  {
          "service": "",
          "version":"1.0",
          "sign":"3347b109a1e44f3fd5baa78b74a84948",
          "partner":"5836b8b52ada463ebc6199579f029566",
          "timestamp":"2016-05-26 11:30:10",
          "charset":"utf-8",
          "signType":"md5",
          "tradeId": "224478781859452794f2a68a756fe461",
          "deductionAmount": "0.1",
          "outTradeNo":"4738473847834378",
          "accountId":"3347b109a1e44f3fd5baa78b74a84941",
        }
     * @throws Exception
     */
    public static String deductionNotSettle(String url, String partner, String key, String version,
                                            String tradeId, String outTradeNo, String accountId, String deductionAmount) {
        // TODO
        // 为指定订单抵扣停车费，如果此时车辆已经出场，返回isSuccess错误码为3，
        // 停简单系统不再接收此笔抵扣信息，对方系统需要给用户发起退款(后续业务中无结算)
        String service = "parkhub.order.deductionNotSettle";
        Map<String, String> paramMap = MapUtil.getOrderMap();
        paramMap.put("tradeId", tradeId);
        paramMap.put("deductionAmount", deductionAmount);
        paramMap.put("outTradeNo", outTradeNo);
        paramMap.put("accountId", accountId);
        paramMap.put("charset", "utf-8");
        paramMap.put("partner", partner);
        paramMap.put("version", version);

        String result = Proc(url, key, service, paramMap);
        /*
        "{\"timestamp\":\"1528534986636\",
        \"returnCode\":\"T\",
        \"prePayId\":\"7a1d52aa77ca487db4e61130394285bd\",
        \"errorMSG\":\"\",
        \"returnMsg\":\"OK\",
        \"isSuccess\":\"0\"}[\\r][\\n]"
         */
        return result;
    }

    /**
     * bindTime 绑定时长优惠券
     * @param url
     * @param partner //
     * @param key     // 密钥
     * @param version // 1.0
     *
     *  {
     *      "service": "parkhub.ticket.bindTime",
     *      "version":"1.0",
     *      "sign":"3347b109a1e44f3fd5baa78b74a84948",
     *      "partner":"5836b8b52ada463ebc6199579f029566",
     *      "timestamp":"2016-05-26 11:30:10",
     *      "charset":"utf-8",
     *      "signType":"md5",
     *      "tradeId": "224478781859452794f2a68a756fe461",
     *      "outTicketNo": "224478781859452794f2a68a756fe461",
     *      "accountId":"3347b109a1e44f3fd5baa78b74a84941",
     *      "prePayType": "3",
     *      "minutes": "30",
     *      "memo": "测试绑定时长优惠券"
     *  }
     * @throws Exception
     */
    public static String bindTime(String url, String partner, String key, String version,
                                  String tradeId, String outTicketNo, String accountId, String prePayType, String minutes, String memo) throws Exception {
        String service = "parkhub.ticket.bindTime";

        Map<String, String> paramMap = MapUtil.getOrderMap();
        paramMap.put("tradeId", tradeId);
        paramMap.put("outTicketNo", outTicketNo);
        paramMap.put("accountId", accountId);
        paramMap.put("prePayType", prePayType);
        paramMap.put("minutes", minutes);
        paramMap.put("memo", memo);
        paramMap.put("charset", "utf-8");
        paramMap.put("partner", partner);
        paramMap.put("version", version);

        String result = Proc(url, key, service, paramMap);
        /*{
                "timestamp": "1464247094636",
                "returnCode": "T",
                "errorMsg": "",
                "returnMsg": "OK",
                "isSuccess": "0",
                "ticketId": "224478781859452794f2a68a756fe441"
          }*/
        return result;
    }

    /**
     * 绑定区间优惠券
     * @param url
     * @param partner
     * @param key     // 密钥
     * @param version
     *
     *  {
     *      "service": "parkhub.ticket.bindPeriod",
     *      "version": "1.0",
     *      "sign": "3347b109a1e44f3fd5baa78b74a84948",
     *      "partner": "5836b8b52ada463ebc6199579f029566",
     *      "timestamp": "2016-05-26 11:30:10",
     *      "charset": "utf-8",
     *      "signType": "md5",
     *      "tradeId": "224478781859452794f2a68a756fe461",
     *      "outTicketNo": "224478781859452794f2a68a756fe461",
     *      "accountId": "3347b109a1e44f3fd5baa78b74a84941",
     *      "prePayType": "3",
     *      "startDt": "20160526113010",
     *      "endDt": "20160526123010",
     *      "expireDt": "20160527113010",
     *      "memo": "测试绑定时长优惠券"
     *  }
     * @throws Exception
     */
    public static String bindPeriod(String url, String partner, String key, String version,
                                    String tradeId, String outTicketNo, String accountId, String prePayType,
                                    String startDt, String EndDt, String expireDt, String memo) throws Exception {
        String service = "parkhub.ticket.bindPeriod";

        Map<String, String> paramMap = MapUtil.getOrderMap();
        paramMap.put("tradeId", tradeId);
        paramMap.put("outTicketNo", outTicketNo);
        paramMap.put("accountId", accountId);
        paramMap.put("prePayType", prePayType);
        paramMap.put("startDt", startDt);
        paramMap.put("EndDt", EndDt);
        paramMap.put("expireDt", expireDt);
        paramMap.put("memo", memo);
        paramMap.put("charset", "utf-8");
        paramMap.put("partner", partner);
        paramMap.put("version", version);

        String result = Proc(url, key, service, paramMap);
        /*{
                "timestamp": "1464247094636",
                "returnCode": "T",
                "errorMsg": "",
                "returnMsg": "OK",
                "isSuccess": "0",
                "ticketId": "224478781859452794f2a68a756fe441"
          }*/
        return result;
    }

    /**
     * 绑定区间优惠券
     * @param url
     * @param partner     // 密钥
     * @param key     // 密钥
     * @param version
     *
     *  {
     *        "service": "parkhub.ticket.unbind",
     *        "version": "1.0",
     *        "sign": "3347b109a1e44f3fd5baa78b74a84948",
     *        "partner": "5836b8b52ada463ebc6199579f029566",
     *        "timestamp": "2016-05-26 11:30:10",
     *        "charset": "utf-8",
     *        "signType": "md5",
     *        "tradeId ": "3347b109a1e44f3fd5baa78b74a84948",
     *        "ticketId": "224478781859452794f2a68a756fe461"
     *  }
     * @throws Exception
     */
    public static String unbind(String url, String partner, String key, String version,
                                String tradeId, String ticketid) throws Exception {
        String service = "parkhub.ticket.unbind";

        Map<String, String> paramMap = MapUtil.getOrderMap();
        paramMap.put("tradeId", tradeId);
        paramMap.put("ticketid", ticketid);
        paramMap.put("charset", "utf-8");
        paramMap.put("partner", partner);
        paramMap.put("version", version);

        String result = Proc(url, key, service, paramMap);
        /*{
                "timestamp": "1464247094636",
                "returnCode": "T",
                "errorMsg": "",
                "returnMsg": "OK",
                "isSuccess": "0",
          }*/
        return result;
    }

    private static String Proc(String url, String key, String service, Map<String, String> paramMap) {
        CloseableHttpClient httpClient = HttpClients.createDefault();

        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader(HTTP.CONTENT_TYPE,"application/json");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Accept-Encoding", "UTF-8");

        String timestamp = getCurrentDate();
        paramMap.put("timestamp", timestamp);

        paramMap.put("service", service);

        String sign = null;
        try{
            sign = getSign(paramMap, key);
        }catch(NoSuchAlgorithmException e) {
            logger.error(e.getLocalizedMessage());
        }

        paramMap.put("sign", sign);
        paramMap.put("signType", "md5");

        String jsonstr = JSON.toJSONString(paramMap);

        try {
            StringEntity se = new StringEntity(jsonstr, Consts.UTF_8);
            se.setContentType("application/json");
            se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"UTF-8"));
            httpPost.setEntity(se);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }

        HttpResponse response = null;
        try {
            response = httpClient.execute(httpPost);
        } catch (Exception e) {
            logger.error(e.getLocalizedMessage());
        }

        String result = null;

        //打印StatusLine
        logger.debug("StatusLine: " + response.getStatusLine());
        try{
            //获取实体
            HttpEntity httpEntity= response.getEntity();
            result = EntityUtils.toString(httpEntity, "UTF-8");
            logger.debug(result);
        } catch (Exception e) {
            logger.error(e.getLocalizedMessage());
        }

        try {                //关闭流并释放资源
            httpClient.close();
        } catch (IOException e) {
            logger.error(e.getLocalizedMessage());
        }

        return result;
    }

}

