package cn.pluss.platform.baidu.impl;

import cn.pluss.platform.IdCardService;
import cn.pluss.platform.baidu.BaiduFaceDetectService;
import cn.pluss.platform.entity.IdCard;
import cn.pluss.platform.entity.OperationRecord;
import cn.pluss.platform.entity.UserApp;
import cn.pluss.platform.entity.UserInfo;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.merchant.AccountService;
import cn.pluss.platform.operationRecord.OperationRecordService;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.userInfo.UserInfoService;
import cn.pluss.platform.util.DateUtils;
import cn.pluss.platform.util.FileUtil;
import cn.pluss.platform.util.HttpUtil;
import cn.pluss.platform.util.ParametersUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.java_websocket.util.Base64;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;

/**
 *
 * @author DJH
 */
@Slf4j
@Service
public class BaiduFaceDetectServiceImpl implements BaiduFaceDetectService {

    @Autowired
    private RestTemplate restTemplate;
    
    @Autowired
    private UserAppService uaService;

    @Autowired
    private UserInfoService uiService;

    @Autowired
    private IdCardService idCardService;

    @Autowired
    private OperationRecordService opService;

    @Override
    public String getAuth() {
        String baiduApiKey = ParametersUtil.baiduAK2;
        String baiduSecretKey = ParametersUtil.baiduSK2;
        String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
        String getAccessTokenUrl = authHost + "grant_type=client_credentials" + "&client_id=" + baiduApiKey + "&client_secret=" + baiduSecretKey;
        return HttpUtil.baiduGET(getAccessTokenUrl);
    }

    @Override
    public String apiGetAuth() {
        final UserApp tokenUa = uaService.queryUserAppByToken();
        faceCertCheck(tokenUa);

        return getAuth();
    }

    /**
     * 人脸识别请求前的校验
     * @return
     */
    private void faceCertCheck(UserApp tokenUa) {
        LambdaQueryWrapper<OperationRecord> qWrapper2 = Wrappers.lambdaQuery();
        qWrapper2.eq(OperationRecord::getUserId, tokenUa.getUserId());
        qWrapper2.in(OperationRecord::getDictValue, "APP_FACE_CERT");
        qWrapper2.between(OperationRecord::getCreateTime, DateUtils.getDayBegin(), DateUtils.getDayEnd());
        final int faceCertCount = opService.count(qWrapper2);
        if (faceCertCount >= 3) {
            throw new MsgException("人脸认证次数超限，请明天再试");
        }

        LambdaQueryWrapper<OperationRecord> qWrapper = Wrappers.lambdaQuery();
        qWrapper.eq(OperationRecord::getUserId, tokenUa.getUserId());
        qWrapper.in(OperationRecord::getDictValue, "BAIDU_ACCESS_TOKEN");
        qWrapper.between(OperationRecord::getCreateTime, DateUtils.getDayBegin(), DateUtils.getDayEnd());
        final int reqAccessTokenCount = opService.count(qWrapper);
        if (reqAccessTokenCount >= 10) {
            throw new MsgException("人脸认证次数超限，请明天再试");
        }
    }

    @Override
    public void checkFaceMatch(String src, String dist) {
        String url = "https://aip.baidubce.com/rest/2.0/face/v4/mingjing/match";
        final String accessToken = getAuth();
        url += "?access_token=" + accessToken;

        JSONObject param = new JSONObject();
        param.put("image", src);
        param.put("image_type", "URL");
        param.put("face_type", "CERT");
        param.put("register_image", dist);
        param.put("register_face_type", "LIVE");
        param.put("register_liveness_control", "NONE");


        final JSONObject result = restTemplate.postForObject(url, param, JSONObject.class);
        if (result == null) {
            throw new MsgException("人脸对比不通过");
        }

        log.info("result : " + result);

        final JSONObject result1 = result.getJSONObject("result");
        if (result1 == null) {
            throw new MsgException("人脸对比不通过");
        }

        final BigDecimal score = result1.getBigDecimal("score");

        if (score.compareTo(BigDecimal.valueOf(80L)) <= 0) {
            throw new MsgException("人脸对比不通过");
        }
    }

    @Override
    public void apiCheckFaceMatch(String dist) {
        final UserApp tokenUa = uaService.queryUserAppByToken();
        faceCertCheck(tokenUa);
        final IdCard certIdCard = idCardService.getCertIdCard(tokenUa.getUserId());
        final String imgPositive = certIdCard.getImgPositive();

        byte[] bytes = DatatypeConverter.parseBase64Binary(dist);
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //TODO 图片压缩 暂时注释
//        try {
//            Thumbnails.of(bais).size(1920, 1080).toOutputStream(baos);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }

        dist = DatatypeConverter.printBase64Binary(baos.toByteArray());

        checkFaceMatch(imgPositive, dist);

        UserInfo userInfo = new UserInfo();
        userInfo.setId(tokenUa.getUserId());
        userInfo.setFaceCert("1");
        userInfo.setFaceCompare("1");

        uiService.updateById(userInfo);
    }
}
