package com.xxfc.platform.universal.service.PictureParsing.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.xxfc.platform.universal.entity.IDCardInformation;
import com.xxfc.platform.universal.service.PictureParsing.UserPictureParsing;
import com.xxfc.platform.universal.utils.CertifHttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * 调用四川涪擎图片解析接口
 *
 * @author Administrator
 */
@Service
@Slf4j
public class XCFQPictureParsingImpl implements UserPictureParsing {

//    private String appcode = "acea1c8811f748b3a65815f11db357c4";
//    private String appcode2 = "ee7710ce92054cae9f6c040f6864e6a7";
    //天德
    private String appcode2 = "a5bc4fa1891444de908195e2af1eb687";

    /**
     * 认证相关的数据
     */
    private String host = "https://ocridcards.market.alicloudapi.com";
    private String path = "/idimages";

    private String method = "POST";

    private String dataNam = "result";


    /**
     * 照片解析
     *
     * @param frontImage 正面照片
     * @param backImage  反面照片
     * @return
     */
    @Override
    public IDCardInformation analysis(String frontImage, String backImage) {
        Map<String,String> front = judgeAccordingToAnalyticalData(frontImage, "front");
        if (MapUtils.isEmpty(front)) {
            log.error("正面解析失败,请重新上传");
            throw new BaseException("正面解析失败,请重新上传");
        }

        Map<String,String> back = judgeAccordingToAnalyticalData(backImage, "back");
        if (MapUtils.isEmpty(back)) {
            log.error("反面解析失败,请重新上传");
            throw new BaseException("反面解析失败,请重新上传");
        }

        return new IDCardInformation(
                front.get("address"),
                front.get("birthday"),
                front.get("name"),
                front.get("code"),
                front.get("sex"),
                front.get("nation"),
                back.get("issue"),
                back.get("issueDate"),
                back.get("expiryDate"));
    }

    private Map<String,String> judgeAccordingToAnalyticalData(String imageUrl, String type) {
        String json = imageParseBase64(imageUrl);
        log.info("json:" + json);

        if (StringUtils.isBlank(json)) {
            return null;
        }

        Map reuslt = (Map) JSONObject.parse(json);

        //判断是否调用图片解析的接口是否异常,若果两个次认证都没结果
        if ("front".equals(type)) {
            if (MapUtil.isEmpty(reuslt)
                    || !(reuslt.get("code").equals("1"))
            ) {
                return null;
            }
        }

        if ("back".equals(type)) {
            if (MapUtil.isEmpty(reuslt)
                    || !(reuslt.get("code").equals("2"))
            ) {
                return null;
            }
        }

        Map<String,String> map = (Map) reuslt.get(dataNam);
        log.info("map:" + map);
        if (MapUtils.isNotEmpty(map)) {
            return map;
        }
        return null;
    }


    //身份证照片解析
    private String imageParse(String imageUrl) {
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Authorization", "APPCODE " + appcode2);
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        bodys.put("image", imageUrl);
        try {
            return callExternalRequest(headers,querys,bodys,1);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    //身份证照片解析
    private String imageParseBase64(String imageUrl) {
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Authorization", "APPCODE " + appcode2);
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        String imgUrlToBase64 = getImgUrlToBase64(imageUrl);
        bodys.put("image", "data:image/png;base64,"+ imgUrlToBase64);
        try {
            return callExternalRequest(headers,querys,bodys,1);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }


    private  String callExternalRequest(Map<String, String> headers,
                                        Map<String, String> querys,
                                        Map<String, String> bodys,
                                        int type) throws Exception {

        HttpResponse response = CertifHttpUtils.doPost(host, path, method, headers, querys, bodys);
        log.info("response:"+response);
        StatusLine statusLine = response.getStatusLine();
        int statusCode = statusLine.getStatusCode();
        /**
         * 状态码: 200 正常；400 URL无效；401 appCode错误； 403 次数用完； 500 API网管错误
         */
        log.info("外部接口响应状态码:"+statusCode);
        //获取response的body

        if (statusCode == 200) {
            return EntityUtils.toString(response.getEntity());
        }

        if (403==statusCode){
                log.error("验证次数已用完");
        }

        return null;
    }

    /**
     * 将网络图片转换成Base64编码字符串
     *
     * @param imgUrl 网络图片Url
     * @return
     */
    public static String getImgUrlToBase64(String imgUrl) {
        InputStream inputStream = null;
        ByteArrayOutputStream outputStream = null;
        byte[] buffer = null;
        try {
            // 创建URL
            URL url = new URL(imgUrl);
            // 创建链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            inputStream = conn.getInputStream();
            outputStream = new ByteArrayOutputStream();
            // 将内容读取内存中
            buffer = new byte[1024];
            int len = -1;
            while ((len = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
            buffer = outputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    // 关闭inputStream流
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    // 关闭outputStream流
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        // 对字节数组Base64编码
        String str = new BASE64Encoder().encode(buffer);
        if(StrUtil.isNotBlank(str)) {
            str = str.replaceAll("\n","");
        }
        return str;
    }

    public static void main(String[] args) {
        String str = getImgUrlToBase64("http://xxtest.upyuns.com/image/app/2020-10-19/3.jpg");
        //str = str.replaceAll("\n","");
        System.out.println(str);
    }

}
