package com.jpsoft.shinestar.modules.baidu.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jpsoft.shinestar.modules.baidu.service.BceFaceService;
import com.jpsoft.shinestar.modules.common.dto.MessageResult;
import com.jpsoft.shinestar.modules.common.utils.BaiduAuthUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Transactional
@Component(value="bceFaceService")
public class BceFaceServiceImpl implements BceFaceService {
    @Autowired
    private BaiduAuthUtil baiduAuthUtil;

    @Autowired
    private ValueOperations<String,Object> valueOperations;

    @Override
    public JSONObject detect(String imageUrl) {
        JSONObject responseJson = null;

        try {
            String url = "https://aip.baidubce.com/rest/2.0/face/v3/detect";
            String accessToken = baiduAuthUtil.getAuth();

            Map<String, Object> bodyMap = new HashMap<>();
            bodyMap.put("image_type", "URL");
            bodyMap.put("image", imageUrl);
            bodyMap.put("face_field", "face_type,age,beauty,gender,mask,quality");

            String responseText = HttpUtil.post(url + "?access_token=" + accessToken, bodyMap);

            responseJson = JSONObject.parseObject(responseText);
        }
        catch (Exception ex){
            log.error(ex.getMessage(),ex);
        }

        return responseJson;
    }

    @Override
    public MessageResult<String> smartDetect(String imageUrl) {
        MessageResult<String> messageResult = new MessageResult<>();
        messageResult.setMessage("");

        boolean result = false;

        try {
            JSONObject detectResultJson = detect(imageUrl);

            if (detectResultJson != null && detectResultJson.getInteger("error_code") == 0) {
                JSONArray faceList = detectResultJson.getJSONObject("result").getJSONArray("face_list");

                if (faceList.size() > 0) {
                    JSONObject face = faceList.getJSONObject(0);

                    String faceType = face.getJSONObject("face_type").getString("type");
                    Integer maskType = face.getJSONObject("mask").getInteger("type");
                    Double leftEye = face.getJSONObject("quality").getJSONObject("occlusion").getDouble("left_eye");
                    Double rightEye = face.getJSONObject("quality").getJSONObject("occlusion").getDouble("right_eye");
                    Double nose = face.getJSONObject("quality").getJSONObject("occlusion").getDouble("nose");
                    Double mouth = face.getJSONObject("quality").getJSONObject("occlusion").getDouble("mouth");

                    if (!faceType.equals("human")) {
                        throw new Exception("请上传真人登记照!");
                    }

                    if (maskType == 1) {
                        throw new Exception("上传登记照中不能佩戴口罩!");
                    }

                    if (leftEye > 0.5) {
                        throw new Exception("登记照中左眼被遮挡!");
                    }

                    if (rightEye > 0.5) {
                        throw new Exception("登记照中右眼被遮挡!");
                    }

                    if (nose > 0.5) {
                        throw new Exception("登记照中鼻子被遮挡!");
                    }

                    if (mouth > 0.5) {
                        throw new Exception("登记照中嘴巴被遮挡!");
                    }

                    result = true;
                } else {
                    messageResult.setMessage("照片中未找到人脸!");
                    result = false;
                }
            } else {
                messageResult.setMessage("照片人脸检测失败!");
                result = false;
            }
        }
        catch (Exception ex){
            result = false;
            messageResult.setMessage(ex.getMessage());
        }

        messageResult.setResult(result);

        return messageResult;
    }
}
