package com.community.commom.fushi;

import com.alibaba.fastjson.JSONObject;
import com.community.commom.fushi.error.FuShiException;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.TreeMap;

/**
 * 富士请求 API
 * @author weiximei
 */
@Data
@Slf4j
public class FuShiRequestAPI {

    private FuShiHttpClient client;

    public FuShiRequestAPI(FuShiHttpClient client) {
        this.client = client;
    }

    public FuShiRequestAPI() {
    }

    // =======================   请求 API   =====================================

    @Data
    @AllArgsConstructor
    public class SignBuild {
        private String sign;
        private String timestamp;
    }

    /**
     * 请求签名
     * @param jsonString
     * @return
     */
    private SignBuild requestSign(String jsonString) {
        String sign = "";
        String timestamp = client.getTimestamp();
        TreeMap<String, String> map = new TreeMap();
		map.put("param", jsonString);
		map.put("secret", client.getAppSecret());
		map.put("timestamp", timestamp);
		sign = client.signWithoutMD5(map);
		sign = client.sign(sign, client.getPrivateKey());

		return new SignBuild(sign, timestamp);
    }

    /**
     * 校验code
     * @param jsonString
     */
    private void showException(String jsonString) {
        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        Integer messageCode = jsonObject.getInteger("MessageCode");
        if (messageCode != 200) {
            throw new FuShiException(messageCode, jsonObject.getString("MessageContent"));
        }
    }

    /**
     * 获取停车信息（通过车牌号）
     * @return
     */
    public String getParkInfoByCarNo(String ParkingCode, String CarNo) {
        Map<String, Object> map = Maps.newHashMap();
        map.put("ParkingCode", ParkingCode);
        map.put("CarNo", CarNo);
        String json = JSONObject.toJSONString(map);
        log.info("获取停车信息（通过车牌号）请求参数：{}", json);
        SignBuild signBuild = requestSign(json);
        String result = client.doJsonPost(FushiConstant.PARK_GETPARKINFOBYCARNO, json, signBuild.getSign(), signBuild.getTimestamp());
        log.info("获取停车信息（通过车牌号）返回数据：{}", result);
        showException(result);
        return result;
    }


    /**
     * 第三方月卡上发续费
     * @param RenewDayType 续费日期类型: 3:年; 2:月; 1:日;
     * @param RenewDay 续费日期数目
     * @param DealNo 交易编码
     * @param PayStyle 交易方式（汉字描述），例如：微信、支付宝、银联
     * @param CarNo 车牌号
     * @param CardNo 停车卡号
     * @param ParkingCode 停车场编码
     * @param RechargeAmt 充值续费金额
     * @param ThirdTransactionDate 第三方交易日期
     * @return
     */
    public String apiThirdPartyMonthCardPay(String RenewDayType, String RenewDay, String DealNo, String PayStyle, String CarNo, String ParkingCode, String CardNo, String RechargeAmt, String ThirdTransactionDate) {
        Map<String, Object> map = Maps.newHashMap();
        map.put("RenewDayType", RenewDayType);
        map.put("RenewDay", RenewDay);
        map.put("DealNo", DealNo);
        map.put("PayStyle", PayStyle);
        map.put("CarNo", CarNo);
        map.put("ParkingCode", ParkingCode);
        map.put("CardNo", CardNo);
        map.put("RechargeAmt", RechargeAmt);
        map.put("ThirdTransactionDate", ThirdTransactionDate);

        String json = JSONObject.toJSONString(map);
        log.info("第三方月卡上发续费请求参数：{}", json);
        SignBuild signBuild = requestSign(json);
        String result = client.doJsonPost(FushiConstant.CALCULATIONCOST_APITHIRDPARTYMONTHCARDPAY, json, signBuild.getSign(), signBuild.getTimestamp());
        log.info("第三方月卡上发续费返回数据：{}", result);
        showException(result);
        return result;
    }

    /**
     * 第三方临时卡上发缴费
     * @param Amount 应缴金额（单位元）
     * @param ActualAmount 实缴金额（单位元）
     * @param DeductionAmount 抵扣金额（单位元）
     * @param Reason 抵扣原因
     * @param DealNo 交易编号
     * @param PayStyle 交易方式(汉字描述)，例如：微信、支付宝、银联
     * @param CarNo 车牌号
     * @param ParkingCode 停车场编码
     * @param CardNo 停车卡号
     * @param PayCostMachineOrderId 线下自助缴费机订单号，若不是自助缴费机缴费则该字段为空
     * @param CouponList 使用的优惠券列表(JSON字符串)
     *               MerchantName: 商户名称
     *               CouponType: 优惠券优惠类型1全免2减免金额3减免时长4减免百分比
     *               CouponValue： 对应优惠券类型的值 金额/时间/折扣
     *               CouponCode： 优惠券编码
     *               FavorableType： 优惠券类型1 纸质券 2 电子券 3 活动券
     *               UseStatus：标识优惠券是线上或线下使用的状态 1只在线上使用 2只在线下使用 3线上线下都可以使用
     *               IsAuto： 是否自动使用优惠券1是2否
     *               EndTime： 截至时间
     *               CouponDescribe： 优惠券描述
     *               CouponName： 优惠券名称
     *
     *
     *
     * @return
     */
    public String apiThirdPartyTemporaryCardPay(String Amount, String ActualAmount, String DeductionAmount, String Reason, String DealNo, String PayStyle, String CarNo, String ParkingCode, String CardNo, String PayCostMachineOrderId, String CouponList) {
        Map<String, Object> map = Maps.newHashMap();
        map.put("Amount", Amount);
        map.put("ActualAmount", ActualAmount);
        map.put("DeductionAmount", DeductionAmount);
        map.put("Reason", Reason);
        map.put("DealNo", DealNo);
        map.put("PayStyle", PayStyle);
        map.put("CarNo", CarNo);
        map.put("ParkingCode", ParkingCode);
        map.put("CardNo", CardNo);
        map.put("PayCostMachineOrderId", PayCostMachineOrderId);
        map.put("CouponList", JSONObject.parseObject(CouponList).getInnerMap());

        String json = JSONObject.toJSONString(map);
        log.info("第三方临时卡上发缴费请求参数：{}", json);
        SignBuild signBuild = requestSign(json);
        String result = client.doJsonPost(FushiConstant.CALCULATIONCOST_APITHIRDPARTYTEMPORARYCARDPAY, json, signBuild.getSign(), signBuild.getTimestamp());
        log.info("第三方临时卡上发缴费返回数据：{}", result);
        showException(result);
        return result;

    }


    /**
     * 获取线下算费结果
     * @return
     */
    public String apiGetOfflineFee(String ParkingCode, String CarNoOrCardNo) {
        Map<String, Object> map = Maps.newHashMap();
        map.put("ParkingCode", ParkingCode);
        map.put("CarNoOrCardNo", CarNoOrCardNo);
        String json = JSONObject.toJSONString(map);
        log.info("获取线下算费结果 请求参数：{}", json);
        SignBuild signBuild = requestSign(json);
        String result = client.doJsonPost(FushiConstant.CALCULATIONCOST_APIGETOFFLINEFEE, json, signBuild.getSign(), signBuild.getTimestamp());
        log.info("获取线下算费结果 返回数据：{}", result);
        showException(result);
        return result;
    }


    /**
     * 获取月租车信息（通过车牌号）
     * @return
     */
    public String parkGetMonthCardInfoByCarNo(String ParkingCode, String CarNo) {
        Map<String, Object> map = Maps.newHashMap();
        map.put("ParkingCode", ParkingCode);
        map.put("CarNo", CarNo);
        String json = JSONObject.toJSONString(map);
        log.info("获取月租车信息（通过车牌号） 请求参数：{}", json);
        SignBuild signBuild = requestSign(json);
        String result = client.doJsonPost(FushiConstant.PARK_GETMONTHCARDINFOBYCARNO, json, signBuild.getSign(), signBuild.getTimestamp());
        log.info("获取月租车信息（通过车牌号） 返回数据：{}", result);
        showException(result);
        return result;
    }

    /**
     * 获取临时车信息（通过车牌号）
     * @return
     */
    public String parkGetTempCarPaymentInfoByCarNo(String ParkingCode, String CarNo) {
        Map<String, Object> map = Maps.newHashMap();
        map.put("ParkingCode", ParkingCode);
        map.put("CarNo", CarNo);
        String json = JSONObject.toJSONString(map);
        log.info("获取临时车信息（通过车牌号） 请求参数：{}", json);
        SignBuild signBuild = requestSign(json);
        String result = client.doJsonPost(FushiConstant.PARK_GETTEMPCARPAYMENTINFOBYCARNO, json, signBuild.getSign(), signBuild.getTimestamp());
        log.info("获取临时车信息（通过车牌号） 返回数据：{}", result);
        showException(result);
        return result;
    }


}
