package com.fzm.mall.midea.pay.component;

import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import com.fzm.mall.midea.pay.properties.MideaPayProperties;
import com.fzm.mall.midea.pay.enums.MideaPayEnum;
import com.fzm.mall.midea.pay.model.BaseResponse;
import com.fzm.mall.midea.pay.model.HttpResponse;
import com.fzm.mall.midea.pay.params.BaseParam;
import com.fzm.mall.midea.pay.utils.HttpClientUtils;
import com.fzm.mall.midea.pay.utils.SignUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

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

/**
 * @author tangtuo
 * @date 2021/5/24 16:44
 */
@Slf4j
@Component
public class MideaPayComponent {

    private static final String SUCCESS_CODE = "1001";

    @Resource
    private MideaPayProperties mideaPayProperties;

    @Resource
    private SignUtil signUtil;


    /**
     * 发送美的支付请求
     *
     * @param param 请求参数具体类型根据service判断,具体参考枚举类MideaPayEnum
     * @return  响应参数类型参考MideaPayEnum
     */
    public BaseResponse sendRequest(BaseParam param) {
        String service = param.getService();
        MideaPayEnum mideaPayEnum = MideaPayEnum.getByService(service);
        if (!mideaPayEnum.getParam().isInstance(param)) {
            throw new RuntimeException("请求参数类型和接口名不对应");
        }
        Map<String, String> map = formatParam(param);
        log.info("请求接口是:{},参数是:{}", service, map);
        HttpResponse httpResponse = HttpClientUtils.doPost(mideaPayProperties.getUrl(), map);
        if (StringUtils.isBlank(httpResponse.getEntity()) || HttpStatus.HTTP_OK != httpResponse.getHttpCode()) {
            throw new RuntimeException(service + "接口调用失败");
        }
        log.info("{}接口返回参数: {}", service, httpResponse);
        BaseResponse response = JSONUtil.toBean(httpResponse.getEntity(), mideaPayEnum.getResponse());
        if (!SUCCESS_CODE.equals(response.getResult_code())) {
            throw new RuntimeException(service + " 接口响应失败 , " + response.getResult_info());
        }
        return response;
    }


    private Map<String, String> formatParam(BaseParam param) {
        Map<String, String> map = param.beanToMap(param);
        // 获取签名
        String sign = signUtil.getSign(SignUtil.getStringToSignOfStr(map));
        map.put("sign", sign);
        // 校验签名
        signUtil.checkSign(map);
        return map;
    }

}
