package org.springblade.modules.app.manager;

import com.wn.common.exception.BusinessException;
import com.wn.common.validator.Validator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springblade.modules.app.constant.Constant;
import org.springblade.modules.app.constant.ErrorCode;
import org.springblade.modules.app.dto.*;
import org.springblade.modules.app.utils.HttpUtils;
import org.springblade.modules.app.utils.ImageHttpUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
@RefreshScope
public class ImageRecognitionManager {
    @Value("${aliyunocr.appcode}")
    private String appcode;

    public BusinessLicenseDTO getBusinessLicenseInfo(String url) {
        Validator.notEmpty(url, ErrorCode.PARAM_DATA_NULL);
        log.info("请求图片路径为:{}", url);
        String host = Constant.HOST_BUSINESS;
        String path = Constant.PATH_BUSINESS;
        String method = Constant.METHOD;
        Map<String, String> headers = constructHeaders();
        Map<String, String> querys = new HashMap<String, String>();
        String bodys = "{\"image\":\"" + url + "\"}";

        try {
            /**
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = ImageHttpUtils.doPost(host, path, method, headers, querys, bodys);
            log.info("请求结果为：{}", response.toString());
            String result = EntityUtils.toString(response.getEntity());
            log.info("返回数据为：{}", result);

            BusinessLicenseDTO businessLicenseDTO = new BusinessLicenseDTO();
            if(result != null) {
                JSONObject maps = JSON.parseObject(result);
                businessLicenseDTO.setEnterpriseName(maps.getString("name"));
                businessLicenseDTO.setEnterpriseType(maps.getString("type"));
                businessLicenseDTO.setAddress(maps.getString("address"));
                businessLicenseDTO.setLegalRepresentative(maps.getString("person"));
                businessLicenseDTO.setCapital(maps.getString("capital"));
                businessLicenseDTO.setBusiness(maps.getString("business"));
                businessLicenseDTO.setRegNum(maps.getString("reg_num"));
                DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
                businessLicenseDTO.setEstablishDate(dateFormat.parse((String) maps.get("establish_date")));
                businessLicenseDTO.setValidPeriod(dateFormat.parse((String) maps.get("valid_period")));
            }
            log.info("返回结果为：{}", businessLicenseDTO);
            return businessLicenseDTO;
        } catch (Exception e) {
            log.info("抛出异常: ", e);
        }
        return null;
    }

    public IdentityCardDTO getIDInfo(String url){
        Validator.notEmpty(url, ErrorCode.PARAM_DATA_NULL);
        log.info("请求图片路径为:{}", url);
        String host = Constant.HOST_ID;
        String path = Constant.PATH_ID;
        String method = Constant.METHOD;

        Map<String, String> headers = constructHeaders();
        Map<String, String> querys = new HashMap<String, String>();
        String bodys = constructRequestBody(url);

        try {
            String result = callAliyunOcrService(host, path, method, headers, querys, bodys);
            IdentityCardDTO identityCardDTO = new IdentityCardDTO();
            if(result != null) {
                JSONObject maps = JSON.parseObject(result);
                identityCardDTO.setName(maps.getString("name"));
                identityCardDTO.setAddress(maps.getString("address"));
                identityCardDTO.setIDNum(maps.getString("num"));
            }
            return identityCardDTO;
        } catch (Exception e) {
            log.info("抛出异常: ", e);
        }
        return null;
    }

    private String constructRequestBody(String url) {
        //configure配置
        JSONObject configObj = new JSONObject();
        configObj.put("side", "face");

        String config_str = configObj.toString();

        // 拼装请求body的json字符串
        JSONObject requestObj = new JSONObject();
        requestObj.put("image", url);
        if(configObj.size() > 0) {
            requestObj.put("configure", config_str);
        }
        return requestObj.toString();
    }

    private Map<String, String> constructHeaders() {
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求，定义相对应的Content-Type
        headers.put("Content-Type", "application/json; charset=UTF-8");
        return headers;
    }

    public DriverDTO getDriverInfo(String url) {
        Validator.notEmpty(url, ErrorCode.PARAM_DATA_NULL);
        log.info("请求图片路径为:{}", url);
        String host = Constant.HOST_DRIVER;
        String path = Constant.PATH_DRIVER;
        String method = Constant.METHOD;

        Map<String, String> headers = constructHeaders();
        Map<String, String> querys = new HashMap<String, String>();
        String bodys = constructRequestBody(url);

        try {
            String result = callAliyunOcrService(host, path, method, headers, querys, bodys);
            DriverDTO driverDTO = new DriverDTO();
            if(result != null) {
                JSONObject maps = JSON.parseObject(result);
                driverDTO.setNumber(maps.getString("num"));
                driverDTO.setVehicleType(maps.getString("vehicle_type"));
                driverDTO.setIssueOrganization(maps.getString("issue_organization"));
                DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
                driverDTO.setStartTime(dateFormat.parse(maps.getString("start_date")));
                driverDTO.setEndTime(dateFormat.parse(maps.getString("end_date")));
            }
            log.info("返回结果为：{}", driverDTO);
            return driverDTO;
        } catch (Exception e) {
            log.info("抛出异常: ", e);
        }
        return null;
    }

    private String callAliyunOcrService(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, String bodys) throws Exception {
        HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
        int stat = response.getStatusLine().getStatusCode();
        if (stat != 200) {
            log.info("Http code: " + stat);
            log.info("http header error msg: " + response.getFirstHeader("X-Ca-Error-Message"));
            log.info("Http body error msg:" + EntityUtils.toString(response.getEntity()));
            throw new BusinessException(ErrorCode.PARSE_FILE_ERROR);
        }
        String result = EntityUtils.toString(response.getEntity());
        log.info("返回数据为：{}", result);
        return result;
    }

    public DrivingDTO getDrivingInfo(String url) {
        Validator.notEmpty(url, ErrorCode.PARAM_DATA_NULL);
        log.info("请求图片路径为:{}", url);
        String host = Constant.HOST_DRIVING;
        String path = Constant.PATH_DRIVING;
        String method = Constant.METHOD;

        Map<String, String> headers = constructHeaders();
        Map<String, String> querys = new HashMap<String, String>();
        String bodys = constructRequestBody(url);

        try {
            String result = callAliyunOcrService(host, path, method, headers, querys, bodys);
            DrivingDTO drivingDTO = new DrivingDTO();
            if(result != null){
                JSONObject maps = JSON.parseObject(result);
                drivingDTO.setVIN(maps.getString("vin"));
            }
            log.info("返回结果为：{}", drivingDTO);
            return drivingDTO;
        } catch (Exception e) {
            log.info("抛出异常: ", e);
        }
        return null;
    }

    public String getCurrencyInfo(String url) {
        Validator.notEmpty(url, ErrorCode.PARAM_DATA_NULL);
        log.info("请求图片路径为:{}", url);
        String host = Constant.HOST_COMMON;
        String path = Constant.PATH_COMMON;
        String method = Constant.METHOD;
        Map<String, String> headers = constructHeaders();
        Map<String, String> querys = new HashMap<String, String>();
        String bodys = "{\"url\":\"" + url + "\",\"prob\":false,\"charInfo\":false,\"rotate\":false,\"table\":false}";

        try {
            return callAliyunOcrService(host, path, method, headers, querys, bodys);
        } catch (Exception e) {
            log.info("抛出异常:", e);
        }
        return null;
    }

    private static final Pattern p = Pattern.compile("(\\d{4})年(\\d{2})月(\\d{2})日止");

    public CommonDTO getCommonInfoWithResult(String url) {
        try {
            String result = getCurrencyInfo(url);
            JSONObject maps = JSON.parseObject(result);
            JSONArray jsonArray = maps.getJSONArray("prism_wordsInfo");
            log.info("jsonArray的数据为：{}", jsonArray);
            CommonDTO commonDTO = new CommonDTO();
            for (int i = 0; i < jsonArray.size(); i++){
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String str = jsonObject.getString("word");
                System.out.println(str);
                // 检验数组第二格有数据，否则取下一个循环的数据
                if (str.contains("代码编号：")){
                    String st;
                    if (str.equals("代码编号：")){
                        st = "";
                    }else {
                        st = str.split("代码编号：")[1];
                    }
                    commonDTO.setLivestockPreventionPassCode(st);
                }
                if (str.contains("定点屠宰代码：")){
                    String st;
                    if (str.equals("定点屠宰代码：")){
                        st = "";
                    }else {
                        st = str.split("定点屠宰代码：")[1];
                    }
                    commonDTO.setLivestockSlaughterPermitCode(st);
                }
                if (str.contains("证书编号：")){
                    String st;
                    if (str.equals("证书编号：")){
                        st = "";
                    }else {
                        st = str.split("证书编号：")[1];
                    }
                    commonDTO.setPollutantDischargePermitCode(st);
                }
                if (str.contains("行业类别：")){
                    String st;
                    if (str.equals("行业类别：")){
                        st = "";
                    }else {
                        st = str.split("行业类别：")[1];
                    }
                    commonDTO.setPollutantDischargePermitIndustry(st);
                }
                if (str.contains("有效期限：")){
                    String st;
                    if (str.equals("有效期限：")){
                        st = "";
                    }else {
                        st = str.split("有效期限：")[1];
                    }
                    commonDTO.setPollutantDischargePermitDate(st);
                }
                if (str.contains("代码编号:")){
                    String st;
                    if (str.equals("代码编号:")){
                        st = "";
                    }else {
                        st = str.split("代码编号:")[1];
                    }
                    commonDTO.setLivestockPreventionPassCode(st);
                }
                if (str.contains("定点屠宰代码:")){
                    String st;
                    if (str.equals("定点屠宰代码:")){
                        st = "";
                    }else {
                        st = str.split("定点屠宰代码:")[1];
                    }
                    commonDTO.setLivestockSlaughterPermitCode(st);
                }
                if (str.contains("证书编号:")){
                    String st;
                    if (str.equals("证书编号:")){
                        st = "";
                    }else {
                        st = str.split("证书编号:")[1];
                    }
                    commonDTO.setPollutantDischargePermitCode(st);
                }
                if (str.contains("行业类别:")){
                    String st;
                    if (str.equals("行业类别:")){
                        st = "";
                    }else {
                        st = str.split("行业类别:")[1];
                    }
                    commonDTO.setPollutantDischargePermitIndustry(st);
                }
                if (str.contains("有效期限:")){
                    String st;
                    if (str.equals("有效期限:")){
                        st = "";
                    }else {
                        st = str.split("有效期限:")[1];
                    }
                    commonDTO.setPollutantDischargePermitDate(st);
                }
                if (str.matches("^[0-9]{12}$")){
                    commonDTO.setTransportPermitCode(str);
                }
                if (str.contains("N:")){
                    String st;
                    if (str.equals("N:")){
                        st = "";
                    }else {
                        st = str.split("N:")[1];
                    }
                    commonDTO.setQuarantineCertificate(st);
                }
                if (str.contains("N：")){
                    String st;
                    if (str.equals("N：")){
                        st = "";
                    }else {
                        st = str.split("N：")[1];
                    }
                    commonDTO.setQuarantineCertificate(st);
                }
                if (str.contains("N9.")){
                    String st;
                    if (str.equals("N9.")){
                        st = "";
                    }else {
                        st = str.split("N9.")[1];
                    }
                    commonDTO.setQuarantineCertificate(st);
                }
                if (str.contains("No.")){
                    String st;
                    if (str.equals("No.")){
                        st = "";
                    }else {
                        st = str.split("No.")[1];
                    }
                    commonDTO.setQuarantineCertificate(st);
                }
                if (str.contains("数量及单位")){
                    String st;
                    if (str.equals("数量及单位")){
                        int j = i + 1;
                        st = jsonArray.getJSONObject(j).getString("word");
                    }else {
                        st = str.split("数量及单位")[1];
                    }
                    commonDTO.setTransportationQuantity(st);
                }
                if (str.contains("运载工具牌号")){
                    String st;
                    if (str.equals("运载工具牌号")){
                        int j = i + 1;
                        st = jsonArray.getJSONObject(j).getString("word");
                    }else {
                        st = str.split("运载工具牌号")[1];
                    }
                    commonDTO.setVehicleBrand(st);
                }
                if (str.contains("签发日期：")){
                    String st;
                    if (str.equals("签发日期：")){
                        st = "";
                    }else {
                        st = str.split("签发日期：")[1];
                    }
                    commonDTO.setIssueDate(st);
                }
                if (str.contains("签发日期:")){
                    String st;
                    if (str.equals("签发日期:")){
                        st = "";
                    }else {
                        st = str.split("签发日期:")[1];
                    }
                    commonDTO.setIssueDate(st);
                }
            }

            if (commonDTO.getPollutantDischargePermitDate() != null){
                Matcher m = p.matcher(commonDTO.getPollutantDischargePermitDate());
                String[] pattern = {"yyyy年MM月dd日止"};
                while(m.find()){
                    String str = m.group(0);
                    Date date = DateUtils.parseDate(str, pattern);
                    commonDTO.setPollutantDischargePermitDateTime(date);
                }
            }

            String str = "[\\S]{4}年[\\S]{1,2}月[\\S]{1,3}日(.*?)";
            if (commonDTO.getIssueDate() != null && commonDTO.getIssueDate().matches(str)){
                String string = commonDTO.getIssueDate();
                String[] year = string.split("年");
                String year1 = year[0];
                String[] month = year[1].split("月");
                String month1 = month[0];
                String day = month[1].split("日")[0];
                System.out.println(day);
                char[] cnArr = new char[]{'○','一','二','三','四','五','六','七','八','九','0','o','O','口'};
                char ten = '十';
                String year2 = "";

                for (int i = 0; i < year1.length(); i++){
                    for (int j = 0; j < cnArr.length; j++){
                        if (year1.charAt(i) == cnArr[j]){
                            int k = j;
                            if (k > 9){
                                k = 0;
                            }
                            year2 = year2 + k;
                        }
                    }
                }

                if (month1.length() == 1){
                    for (int i = 0; i < cnArr.length; i++){
                        if (month1.charAt(0) == ten){
                            year2 = year2 + "10";
                            break;
                        }
                        if (month1.charAt(0) == cnArr[i]){
                            year2 = year2 + "0" + i;
                        }
                    }
                }else if (month1.length() == 2){
                    for (int i = 0; i < cnArr.length; i++){
                        if (month1.charAt(1) == cnArr[i]){
                            year2 = year2 + "1" + i;
                        }
                    }
                }

                if (day.length() == 1){
                    for (int i = 0; i < cnArr.length; i++){
                        if (day.charAt(0) == ten){
                            year2 = year2 + "10";
                            break;
                        }
                        if (day.charAt(0) == cnArr[i]){
                            year2 = year2 + "0" + i;
                        }
                    }
                }else if (day.length() == 2){
                    if (day.charAt(0) == ten){
                        for (int i = 0; i < cnArr.length; i++){
                            if (day.charAt(1) == cnArr[i]){
                                year2 = year2 + "1" + i;
                            }
                        }
                    }
                    if (day.charAt(0) == cnArr[2]){
                        year2 = year2 + "20";
                    }
                    if (day.charAt(0) == cnArr[3]){
                        year2 = year2 + "30";
                    }
                }else if (day.length() == 3){
                    if (day.charAt(0) == cnArr[2]){
                        for (int i = 0; i < cnArr.length; i++){
                            if (day.charAt(2) == cnArr[i]){
                                year2 = year2 + "2" + i;
                            }
                        }
                    }
                    if (day.charAt(0) == cnArr[3]){
                        for (int i = 0; i < cnArr.length; i++){
                            if (day.charAt(2) == cnArr[i]){
                                year2 = year2 + "3" + i;
                            }
                        }
                    }
                }
                System.out.println(year2);
                String[] pattern = {"yyyyMMdd"};
                Date date = DateUtils.parseDate(year2, pattern);
                commonDTO.setIssueDateTime(date);
            }

            if (commonDTO.getTransportationQuantity() != null){
                String string = commonDTO.getTransportationQuantity();
                String chineseNumber = "";
                if (string.contains("头")){
                    chineseNumber = string.split("头")[0];
                }
                if (string.contains("公斤")){
                    chineseNumber = string.split("公斤")[0];
                }
                if (string.contains("只")){
                    chineseNumber = string.split("只")[0];
                }
                if (string.contains("(头)")){
                    chineseNumber = string.split("\\(头\\)")[0];
                }
                if (string.contains("(公斤)")){
                    chineseNumber = string.split("\\(公斤\\)")[0];
                }
                if (string.contains("(只)")){
                    chineseNumber = string.split("\\(只\\)")[0];
                }
                System.out.println(chineseNumber);
                int result01 = 0;
                int temp = 1;
                int count = 0;
                char[] cnArr = new char[]{'壹','贰','叁','肆','伍','陆','柒','捌','玖'};
                char[] chArr = new char[]{'拾','佰','仟','万'};
                for (int i = 0; i < chineseNumber.length(); i++) {
                    boolean b = true;
                    char c = chineseNumber.charAt(i);
                    for (int j = 0; j < cnArr.length; j++) {
                        if (c == cnArr[j]) {
                            if(0 != count){
                                result01 += temp;
                                temp = 1;
                                count = 0;
                            }
                            // 下标+1，就是对应的值
                            temp = j + 1;
                            b = false;
                            break;
                        }
                    }
                    //单位{'拾','佰','仟','万'}
                    if(b){
                        for (int j = 0; j < chArr.length; j++) {
                            if (c == chArr[j]) {
                                switch (j) {
                                    case 0:
                                        temp *= 10;
                                        break;
                                    case 1:
                                        temp *= 100;
                                        break;
                                    case 2:
                                        temp *= 1000;
                                        break;
                                    case 3:
                                        temp *= 10000;
                                        break;
                                    default:
                                        break;
                                }
                                count++;
                            }
                        }
                    }
                    if (i == chineseNumber.length() - 1) {
                        result01 += temp;
                    }
                }
                System.out.println(result01);
                commonDTO.setTransportationQuantityNum((long) result01);
            }

            log.info("请求结果为：{}", commonDTO);
            return commonDTO;
        } catch (Exception e) {
            log.info("抛出异常: ", e);
        }
        return null;
    }
}

