package com.xueyi.system.resource.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xueyi.system.utils.common.ImageUtil;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

@Slf4j
@Component
public class FaceServiceImpl {

   @Value("${face.server}")
   private String faceServer;

   @Value("${face.authorizePath}")
   private String authorizePath;

   @Value("${face.extractionPath}")
   private String extractionPath;

   @Value("${face.qualityPath}")
   private String qualityPath;

   @Value("${faceServerI.user}")
   private String user;

   @Value("${faceServerI.password}")
   private String password;

   private String imgPath;

   @Autowired
   private RestTemplate restTemplate;


   public static String execCurl(String[] cmds) {
      ProcessBuilder process = new ProcessBuilder(cmds);
      Process p;
      try {
         p = process.start();
         BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
         StringBuilder builder = new StringBuilder();
         String line;
         while ((line = reader.readLine()) != null) {
            builder.append(line);
            builder.append(System.getProperty("line.separator"));
         }
         return builder.toString();

      } catch (IOException e) {
         System.out.print("error");
         e.printStackTrace();
      }
      return null;
   }

   public String getToken(){

      /*****Unirest 请求方式*****/
      JSONObject paramJson = new JSONObject();
      paramJson.put("name", user);
      paramJson.put("password", password);
      String content = paramJson.toJSONString();
      HttpResponse<String> response = Unirest.post(faceServer + authorizePath)
              .header("Content-Type", "application/json")
              .body(content)
              .asString();
      String result = response.getBody();
      JSONObject resultJson = JSON.parseObject(result);
      return resultJson.getJSONObject("result").getString("token");


   }

   public JSONObject getFaceExtraction(String token, String imageId, String imgBase64) {

      /********restTemplate 请求方式*************/
      HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.APPLICATION_JSON);
//      headers.set("Authorization", "Bearer "+token);
      headers.set("Authorization", "Basic ZmFjZS1tYW5hZ2VtZW50OmZhY2UtbWFuYWdlbWVudA==");
     /* MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();

      map.add("faceName", "faceName");
      map.add("base64Data", imgBase64);
      map.add("detect", true);
      map.add("quality", true);*/
      JSONArray jsonArray = new JSONArray();
      JSONObject j1 = new JSONObject();
      j1.put("faceName", "faceName");
      j1.put("base64Data", imgBase64);
      j1.put("detect", true);
      j1.put("quality", true);
      jsonArray.add(j1);

      JSONObject js = new JSONObject();
      js.put("images", jsonArray);

//      MultiValueMap<String, Object> bMap = new LinkedMultiValueMap<String, Object>();
//      bMap.add("images", new Object[]{map});
      HttpEntity<Map<String, Object>> entity = new HttpEntity<>(js.getInnerMap(), headers);

      String path = faceServer;

      String result = restTemplate.postForObject(path + extractionPath, entity, String.class, "face-detection");
      System.err.println(path + extractionPath);
      JSONObject resultJson = JSON.parseObject(result);

      return resultJson;


   }


   public JSONObject getFaceCheck(String token, String imageId, String imgBase64) throws Exception{


      /********restTemplate 请求方式*************/
      try {
         imgBase64 = imgBase64.replaceAll("data:image/jpeg;base64,", "");
         HttpHeaders headers = new HttpHeaders();
         headers.setContentType(MediaType.APPLICATION_JSON);
         headers.set("Authorization", "Bearer "+token);
         MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();

         JSONArray jsonArray = new JSONArray();
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("imageId",imageId);
         jsonObject.put("base64Data",imgBase64);
         jsonArray.add(jsonObject);
         map.add("detect", true);
         map.add("images", jsonArray);
         HttpEntity<Map<String, Object>> entity = new HttpEntity<>(map.toSingleValueMap(), headers);
         System.err.println(faceServer + qualityPath);
         String result = restTemplate.postForObject(faceServer + qualityPath, entity, String.class, "face-detection");


         JSONObject resultJson = JSON.parseObject(result);

         return resultJson.getJSONArray("result").getJSONObject(0);
      } catch (Exception e) {
         System.err.println("8888err");
         e.printStackTrace();
         throw e;
      }

   }


   public JSONObject hasface(String token, String imageId, String imgBase64)  {

      /********CURL 请求方式********/
      JSONObject json = new JSONObject();

      try {
         imgBase64 = imgBase64.replaceAll("data:image/jpeg;base64,", "");
         JSONObject res = this.getFaceExtraction(token, imageId, imgBase64);

         JSONObject obj = res.getJSONArray("faces").getJSONObject(0);

         if (!obj.isEmpty()) {
            json.put("status", 0);
            json.put("data", obj);
            return json;
         } else {
            json.put("status", 500);
            json.put("data", null);
            json.put("errMsg", "获取人脸失败");
            return json;
         }


      } catch (Exception e) {
         json.put("status", 500);
         json.put("data", null);
         json.put("errMsg", e.getMessage());
         return json;
      }


   }

   public JSONObject regCheckFace(String token, String imageId, String imgBase64)  {

      JSONObject json = new JSONObject();

      try {
         imgBase64 = imgBase64.replaceAll("data:image/jpeg;base64,", "");
         JSONObject res = this.getFaceCheck(token, imageId, imgBase64);

         Boolean passed = res.getBoolean("passed");

         if (!ObjectUtils.anyNotNull(passed)) {
            json.put("status", 500);
            json.put("data", null);
            json.put("errMsg", "所拍摄的照片重人脸不存在");
            return json;
         }

         if (!passed) {
            json.put("status", 500);
            json.put("data", res);
            double blur = res.getDouble("blur");
            double pose = res.getDouble("pose");
            double occ = res.getDouble("occ");
            double illum = res.getDouble("illum");

            String errMsg = "人脸检测失败，拍摄的照片无人脸或过于模糊，请重试";
            if (blur>pose) {
               errMsg = "人脸检测失败，拍摄的照片姿势存在问题";
            }
            if (pose>occ) {
               errMsg = "人脸检测失败，面部被遮挡，请不要戴口罩或墨镜等进行拍摄";
            }
            if (occ>illum) {
               errMsg = "人脸检测失败，光线太暗，请到明亮点的地方重新拍摄";
            }

            json.put("errMsg", errMsg);
            json.put("data", res);

         } else {
            json.put("status", 0);
            json.put("data", res);
            json.put("errMsg", "");
         }

         return json;

      } catch (Exception e) {
         e.printStackTrace();
         json.put("status", 500);
         json.put("data", null);
         json.put("errMsg", e.getMessage());
         return json;
      }


   }


   public JSONObject getFeatureByLocal(String getFaceImageName, String empId){
      JSONObject json = new JSONObject();
      String base64Image = "";
      if (!(null == getFaceImageName || "".equals(getFaceImageName.trim()))) {
         String filePath = imgPath + "/" + getFaceImageName.replaceFirst("\\?s=1", "");
         base64Image = ImageUtil.convertFileToBase64(filePath);
      } else {
         json.put("status", 500);
         json.put("errMsg", "imagePath不能为空");
         return json;
      }
      JSONObject faceRectangle = this.hasface("", empId, base64Image);
      int status = faceRectangle.getInteger("status");
      faceRectangle = faceRectangle.getJSONObject("data");
      if (status != 0) {
         json.put("status",status);
         json.put("errMsg"," 特征值提取失败，"+faceRectangle.getString("errMsg"));
         return json;
      }
      if (!ObjectUtils.anyNotNull(faceRectangle) || faceRectangle.getJSONObject("faceRectangle").isEmpty()) {
         json.put("status",504);
         json.put("errMsg"," 特征值提取失败，上传的头像未找到人脸！");
         return json;
      }

      JSONArray array = faceRectangle.getJSONArray("feature");
      json.put("status",0);
      json.put("errMsg","");
      json.put("feature",array.toJSONString());
      return json;
   }

}
