package cn.hanghui.outapi.platform.xinghuo.api;

import cn.hanghui.outapi.platform.common.config.CacheConfig;
import cn.hanghui.outapi.platform.common.config.OutApiConfig;
import cn.hanghui.outapi.platform.common.utils.Sm4Util;
import cn.hanghui.outapi.platform.xinghuo.constant.MhBaseParam;
import cn.hanghui.outapi.platform.xinghuo.constant.XinghuoApiUrl;
import cn.hanghui.outapi.platform.xinghuo.constant.XinghuoRespCode;
import cn.hanghui.outapi.platform.common.exception.CommonException;
import cn.hanghui.outapi.platform.xinghuo.constant.XinghuoBaseParam;
import cn.hanghui.outapi.platform.xinghuo.entity.dto.GetQrCodeDto;
import cn.hanghui.outapi.platform.xinghuo.entity.param.*;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Component
@AllArgsConstructor(onConstructor_ = @Autowired)
public class XinghuoQrCodeApi {

    private static final Logger log = LoggerFactory.getLogger(XinghuoQrCodeApi.class);

    private final XinghuoBaseParam xinghuoBaseParam;

    private final MhBaseParam mhBaseParam;

    private final byte[] iv = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

    /**
     * 申请凭证接口
     *
     * @param applyProofApiParam ApplyProofApiParam
     * @return XinghuoApiResp<String>
     */
    public XinghuoApiResp<ApplyProofApiResult> applyProof(ApplyProofApiParam applyProofApiParam) {
        XinghuoApiParam xinghuoApiParam = new XinghuoApiParam();
        xinghuoApiParam.setAppCode(xinghuoBaseParam.getAppCode());
        xinghuoApiParam.setBizData(Sm4Util.encode(JSON.toJSONString(applyProofApiParam), xinghuoBaseParam.getSecretKey(), iv));
        String data = HttpUtil.post(xinghuoBaseParam.getBaseUrl() + XinghuoApiUrl.APPLY_PROOF.url,
                BeanUtil.beanToMap(xinghuoApiParam), OutApiConfig.CALL_TIMEOUT);
        XinghuoApiResp<ApplyProofApiResult> xinghuoApiResp = JSON.parseObject(data, new TypeReference<XinghuoApiResp<ApplyProofApiResult>>() {
        });
        return xinghuoApiResp;
    }

    /**
     * 获取凭证二维码
     *
     * @param getQrCodeApiParam GetQrCodeApiParam
     * @return GetQrCodeApiResult
     */
    public GetQrCodeApiResult getQrCode(GetQrCodeApiParam getQrCodeApiParam) {
        XinghuoApiParam xinghuoApiParam = new XinghuoApiParam();
        xinghuoApiParam.setAppCode(xinghuoBaseParam.getAppCode());
        xinghuoApiParam.setBizData(Sm4Util.encode(JSON.toJSONString(getQrCodeApiParam), xinghuoBaseParam.getSecretKey(), iv));
        XinghuoApiResp<GetQrCodeApiResult> xinghuoApiResp = null;
        int count = 1;
        // 1秒一次调8次
        while (true) {
            String data = HttpUtil.post(xinghuoBaseParam.getBaseUrl() + XinghuoApiUrl.GET_PROOF_QRCODE.url,
                    BeanUtil.beanToMap(xinghuoApiParam), OutApiConfig.CALL_TIMEOUT);
            xinghuoApiResp = JSON.parseObject(data, new TypeReference<XinghuoApiResp<GetQrCodeApiResult>>() {
            });
            log.info("第" + count + "次调用返回：" + JSON.toJSONString(xinghuoApiResp));
            count++;
            if (!"2004".equals(xinghuoApiResp.getStatus()) || count > 8) {
                break;
            }
            long currTimestamp = System.currentTimeMillis();
            while (System.currentTimeMillis() < currTimestamp + 1000) {
            }
        }
        if (!XinghuoRespCode.SUCCESS.code.equals(xinghuoApiResp.getStatus())) {
            if (count > 8) {
                throw new CommonException("调用星火获取二维码超时");
            } else {
                throw new CommonException(xinghuoApiResp.getMsg());
            }
        }
        return xinghuoApiResp.getRows();
    }

    /**
     * 根据二维码获取凭证信息
     *
     * @param getProofByQrCodeApiParam GetProofByQrCodeApiParam
     * @return GetProofByQrCodeApiResult
     */
    public GetProofByQrCodeApiResult getProofByQrCode(GetProofByQrCodeApiParam getProofByQrCodeApiParam) {
        XinghuoApiParam xinghuoApiParam = new XinghuoApiParam();
        xinghuoApiParam.setAppCode(xinghuoBaseParam.getAppCode());
        xinghuoApiParam.setBizData(Sm4Util.encode(JSON.toJSONString(getProofByQrCodeApiParam), xinghuoBaseParam.getSecretKey(), iv));
        String data = HttpUtil.get(xinghuoBaseParam.getBaseUrl() + XinghuoApiUrl.GET_PROOF_BY_QRCODE.url,
                BeanUtil.beanToMap(xinghuoApiParam), OutApiConfig.CALL_TIMEOUT);
        log.info("星火根据二维码获取凭证信息返回：" + data);
        XinghuoApiResp<GetProofByQrCodeApiResult> xinghuoApiResp = JSON.parseObject(data, new TypeReference<XinghuoApiResp<GetProofByQrCodeApiResult>>() {
        });
        if (!XinghuoRespCode.SUCCESS.code.equals(xinghuoApiResp.getStatus())) {
            throw new CommonException(xinghuoApiResp.getMsg());
        }
        return xinghuoApiResp.getRows();
    }

    /**
     * 根据民航小程序二维码获取人员信息
     *
     * @param getProofByQrCodeApiParam GetProofByQrCodeApiParam
     * @return GetProofByQrCodeApiResult
     */
    public GetProofByQrCodeApiResult getProofByMiniAppletQrCode(GetProofByQrCodeApiParam getProofByQrCodeApiParam) {
        MhGetProofByQrCodeApiParam mhGetProofByQrCodeApiParam = new MhGetProofByQrCodeApiParam();
        mhGetProofByQrCodeApiParam.setCodeContent(getProofByQrCodeApiParam.getQrCodeText());
        mhGetProofByQrCodeApiParam.setSId(getProofByQrCodeApiParam.getMacAddress());
        String data = HttpRequest.post(mhBaseParam.getBaseUrl() + XinghuoApiUrl.MH_GET_PROOF_BY_QRCODE.url)
                .header("Trace-Id", UUID.randomUUID().toString())
                .form(BeanUtil.beanToMap(mhGetProofByQrCodeApiParam))
                .execute().body();
        log.info("根据民航小程序二维码获取人员信息返回：" + data);
        XinghuoApiResp<MhGetProofByQrCodeApiResult> xinghuoApiResp = JSON.parseObject(data, new TypeReference<XinghuoApiResp<MhGetProofByQrCodeApiResult>>() {
        });
        if (!XinghuoRespCode.SUCCESS.code.equals(xinghuoApiResp.getStatus())) {
            throw new CommonException(xinghuoApiResp.getMsg());
        }
        MhGetProofByQrCodeApiResult mhGetProofByQrCodeApiResult = xinghuoApiResp.getRows();
        GetProofByQrCodeApiResult getProofByQrCodeApiResult = new GetProofByQrCodeApiResult();
        getProofByQrCodeApiResult.setIdCardNo(mhGetProofByQrCodeApiResult.getPassengerIdCard());
        getProofByQrCodeApiResult.setName(mhGetProofByQrCodeApiResult.getPassengerName());
        getProofByQrCodeApiResult.setAddress(mhGetProofByQrCodeApiResult.getResidenceAddress());
        getProofByQrCodeApiResult.setNation(mhGetProofByQrCodeApiResult.getNation());
        getProofByQrCodeApiResult.setPhoto(mhGetProofByQrCodeApiResult.getPassengerPhoto());
        getProofByQrCodeApiResult.setPhone(mhGetProofByQrCodeApiResult.getPassengerPhone());
        getProofByQrCodeApiResult.setApplyTime(mhGetProofByQrCodeApiResult.getApplyTime());
        getProofByQrCodeApiResult.setValidTime(mhGetProofByQrCodeApiResult.getValidTime());
        getProofByQrCodeApiResult.setBirthday(mhGetProofByQrCodeApiResult.getBirthday());
        getProofByQrCodeApiResult.setSex(mhGetProofByQrCodeApiResult.getSex());
        return getProofByQrCodeApiResult;
    }
}
