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.pay.util.sdk.WXPayConstants;
import com.hai.common.utils.DateUtil;
import com.hai.common.utils.HttpsUtils;
import com.hai.common.utils.MD5Util;
import com.hai.enum_type.TripartiteReqLogReqType;
import com.hai.enum_type.TripartiteReqLogType;
import com.hai.service.BsTripartiteReqLogService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;

/**
 * 壳牌接口服务
 */
@Component
public class ShellGroupService {

    @Resource
    private BsTripartiteReqLogService reqLogService;

    /**
     * 查询全量加油站
     * @param pageNum   当前页码
     * @param pageSize  每页数据量。最大值50
     * @return
     */
    public JSONObject gasPageQueryAllStation(Integer pageNum,Integer pageSize) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("platMerchantId", CommonSysConst.getSysConfig().getShellPlatMerchantId());
        param.put("pageNo", pageNum);
        param.put("pageSize", pageSize);
        return request(System.currentTimeMillis()+"","gasPageQueryAllStation", param);
    }

    /**
     * 查询单个油站全量信息
     * @param stationCode   油站编码
     * @return
     */
    public JSONObject gasStationQueryDetail(String stationCode) {
        try {
            Map<String, Object> param = new HashMap<>();
            param.put("platMerchantId", CommonSysConst.getSysConfig().getShellPlatMerchantId());
            param.put("stationCode", stationCode);
            return request(System.currentTimeMillis()+"","gasPageQueryAllStation", param);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 【同步】油站付款
     * @param orderNo      订单号
     * @param stationCode  油站编码
     * @param finishTime   完成时间
     * @param oilPrice     加油金额
     * @param oilCode      油品编码
     * @param oilGun       油枪
     * @param settlementAmount   支付金额
     * @param channelFavourAmount       优惠金额
     * @return
     */
    public JSONObject gasSyncPayment(String orderNo,
                                     String stationCode,
                                     Date finishTime,
                                     BigDecimal oilPrice,
                                     String oilCode,
                                     String oilGun,
                                     BigDecimal settlementAmount,
                                     BigDecimal channelFavourAmount) {
        try {
            Map<String, Object> param = new HashMap<>();
            param.put("platMerchantId", CommonSysConst.getSysConfig().getShellPlatMerchantId());
            param.put("stationCode", stationCode);
            param.put("orderType", "OIL");
            param.put("finishTime", DateUtil.date2String(finishTime, "yyyy-MM-dd HH:mm:ss"));
            param.put("channelFavourAmount", channelFavourAmount);

            Map<String, Object> tradeOilOrder = new HashMap<>();
            tradeOilOrder.put("amount", oilPrice);
            tradeOilOrder.put("code", oilCode);
            tradeOilOrder.put("oilGun", oilGun);
            tradeOilOrder.put("channelSettlementAmount", settlementAmount);
            param.put("tradeOilOrder", JSONObject.toJSONString(tradeOilOrder));
            return request(orderNo.replace("HF",""), "gas_sync_payment_notify", param);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 【同步】油站退款
     * @param finishTime   业务完成时间
     * @param tradeNo      交易流水号
     * @return
     */
    public JSONObject gasSyncRefund(Date finishTime,String tradeNo) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("platMerchantId", CommonSysConst.getSysConfig().getShellPlatMerchantId());
        param.put("finishTime", DateUtil.date2String(finishTime, "yyyy-MM-dd HH:mm:ss"));
        param.put("tradeNo", tradeNo.replace("HF",""));
        // 请求接口
        return request(System.currentTimeMillis()+"" ,"gas_sync_refund_notify", param);
    }

    /**
     * 接口请求
     * @param map
     * @return
     * @throws Exception
     */
    private JSONObject request(String logSerialNo, String service, Map<String,Object> map) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("merchantOrderNo", logSerialNo);
        param.put("partnerId", CommonSysConst.getSysConfig().getShellGroupPartnerId());
        param.put("service", service);
        param.put("version", "1.0.0");
        param.put("signType", "MD5");

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            param.put(entry.getKey(), entry.getValue());
        }
        param.put("sign", MD5Util.encode(generateSignature(param, CommonSysConst.getSysConfig().getShellPlatMerchantKey()).getBytes()).toLowerCase());

        // 请求接口
        JSONObject object = HttpsUtils.doPost(CommonSysConst.getSysConfig().getShellGroupUrl(), param);
        reqLogService.insert(
                TripartiteReqLogType.type2,
                logSerialNo,
                TripartiteReqLogReqType.type1,
                CommonSysConst.getSysConfig().getShellGroupUrl(),
                this.generateParam(param),
                object.toString()
        );

        if (object == null || !object.getString("status").equals("SUCCESS")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, object == null?"请求失败":object.getString("message"));
        }
        return object;
    }

    /**
     * 生成签名
     * @param data  数据
     * @param key   秘钥app_secret
     * @return 加密结果
     */
    public static String generateSignature(final Map<String, Object> data, String key) {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (data.get(k) != null) {
                if (StringUtils.isBlank(sb.toString())) {
                    sb.append(k).append("=").append(data.get(k));
                } else {
                    sb.append("&").append(k).append("=").append(data.get(k));
                }
            }
        }
        sb.append(key);
        return sb.toString();
    }

    /**
     * 生成参数
     * @param data  数据
     * @return 加密结果
     */
    public static String generateParam(final Map<String, Object> data) {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (data.get(k) != null) {
                if (StringUtils.isBlank(sb.toString())) {
                    sb.append(k).append("=").append(data.get(k));
                } else {
                    sb.append("&").append(k).append("=").append(data.get(k));
                }
            }
        }
        return sb.toString();
    }

}
