package com.esv.freight.file.module.ocr.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baidu.aip.ocr.AipOcr;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.esv.freight.file.common.component.AipOcrComponent;
import com.esv.freight.file.common.exception.EException;
import com.esv.freight.file.common.response.ECode;
import com.esv.freight.file.module.file.em.FileTypeEnum;
import com.esv.freight.file.module.file.form.FileForm;
import com.esv.freight.file.module.file.service.FileMetaService;
import com.esv.freight.file.module.file.vo.FileVO;
import com.esv.freight.file.module.ocr.dao.OcrHistoryDao;
import com.esv.freight.file.module.ocr.entity.OcrHistoryEntity;
import com.esv.freight.file.module.ocr.form.IdCardForm;
import com.esv.freight.file.module.ocr.service.OcrHistoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;

import java.util.Base64;
import java.util.HashMap;


@Service("ocrHistoryService")
@Slf4j
public class OcrHistoryServiceImpl extends ServiceImpl<OcrHistoryDao, OcrHistoryEntity> implements OcrHistoryService {

    private AipOcrComponent aipOcrComponent;

    private FileMetaService fileMetaService;

    public OcrHistoryServiceImpl(AipOcrComponent aipOcrComponent, FileMetaService fileMetaService) {
        this.aipOcrComponent = aipOcrComponent;
        this.fileMetaService = fileMetaService;
    }

    @Override
    public JSONObject OcrIdCard(IdCardForm idCardForm) throws EException {
        JSONObject resultJson = new JSONObject();
        byte[] data = Base64.getDecoder().decode(idCardForm.getImage());

        // 通过文件的MD5值判断是否有历史OCR结果
        String fileMD5 = DigestUtils.md5Hex(data);
        OcrHistoryEntity queryEntity = new OcrHistoryEntity();
        queryEntity.setFileMd5(fileMD5);
        QueryWrapper<OcrHistoryEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(queryEntity);
        OcrHistoryEntity ocrHistoryEntityDB = this.getOne(queryWrapper);
        String ocrInfo;
        if (null == ocrHistoryEntityDB) {
            /*************************************** 调用第三方OCR服务 *************************************/
            // 传入可选参数调用接口
            HashMap<String, String> options = new HashMap<>(2);
            // 是否检测图像朝向，默认不检测，即：false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:true：检测朝向；false：不检测朝向。
            options.put("detect_direction", "true");
            // 是否开启身份证风险类型(身份证复印件、临时身份证、身份证翻拍、修改过的身份证)功能，默认不开启，即：false。可选值:true-开启；false-不开启
            options.put("detect_risk", "false");
            // front：身份证含照片的一面；back：身份证带国徽的一面
            String idCardSide = "front";
            AipOcr client = aipOcrComponent.getClient();
            org.json.JSONObject ocrRes;
            try {
                ocrRes = client.idcard(data, idCardSide, options);
                log.info(ocrRes.toString());
            } catch (Exception e) {
                log.error("请求OCR服务时发生错误");
                log.error(e.getMessage(), e);
                throw new EException(ECode.THIRD_PARTY_ERROR.code(), "请求OCR服务时发生错误");
            }
            ocrInfo = ocrRes.toString();
            /*************************************** 调用第三方OCR服务 *************************************/

            // 保存OCR结果
            OcrHistoryEntity ocrHistoryEntity = new OcrHistoryEntity();
            ocrHistoryEntity.setFileMd5(fileMD5);
            ocrHistoryEntity.setOcrResult(ocrInfo);
            this.baseMapper.insert(ocrHistoryEntity);
        } else {
            ocrInfo = ocrHistoryEntityDB.getOcrResult();
        }
        JSONObject ocrInfoJson = getIdCardOcrInfo(ocrInfo);
        resultJson.put("ocrInfo", ocrInfoJson);

        // 判断是否需要存储文件
        if (idCardForm.isNeedFileInfo()) {
            FileForm fileForm = new FileForm();
            fileForm.setFileData(idCardForm.getImage());
            fileForm.setFileName(idCardForm.getFileName());
            fileForm.setFileType(FileTypeEnum.IMAGE.getFileType());
            FileVO fileVO = fileMetaService.uploadFile(fileForm);
            resultJson.put("fileInfo", fileVO);
        }

        return resultJson;
    }

    /**
     * description 获取OCR信息
     * param [ocrInfo]
     * return com.alibaba.fastjson.JSONObject
     * author Administrator
     * createTime 2020/04/15 11:04
     **/
    private JSONObject getIdCardOcrInfo(String ocrInfo) throws EException {
        JSONObject ocrInfoJson = new JSONObject();
        JSONObject jsonObject = JSONObject.parseObject(ocrInfo);
        if (!"normal".equals(jsonObject.getString("image_status"))) {
            throw new EException(1001, "OCR识别失败");
        }
        JSONObject wordsResult = jsonObject.getJSONObject("words_result");
        ocrInfoJson.put("name", wordsResult.getJSONObject("姓名").getString("words"));
        ocrInfoJson.put("id", wordsResult.getJSONObject("公民身份号码").getString("words"));
        ocrInfoJson.put("sex", wordsResult.getJSONObject("性别").getString("words"));
        ocrInfoJson.put("nation", wordsResult.getJSONObject("民族").getString("words"));
        ocrInfoJson.put("birthdate", wordsResult.getJSONObject("出生").getString("words"));
        return ocrInfoJson;
    }

}