package net.northking.cctp.upperComputer.automation.utils;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import net.northking.cctp.upperComputer.config.HttpRequestPathConfig;
import net.northking.cctp.upperComputer.driver.ios.command.data.TapXYData;
import net.northking.cctp.upperComputer.exception.ExecuteException;
import net.northking.cctp.upperComputer.utils.HttpUtils;
import net.northking.cctp.upperComputer.utils.SpringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;

/**
 * @author : yineng.huang
 * @date : 2024/11/5 16:38
 */
public class CloudTestOcrHelper implements OcrHelper {

    private Logger logger = LoggerFactory.getLogger(CloudTestOcrHelper.class);

    private String ocrGetAllTextNum;

    private String ocrImgFindArea;

    private double matchingThreshold = 0.5;

    private String ocrGetVerificationCode;

    private String ocrGetSafeKeyBoardNum;

    private String ocrGetTextDirectionText;



    public CloudTestOcrHelper() {
        HttpRequestPathConfig config = SpringUtils.getBean(HttpRequestPathConfig.class);
        ocrGetAllTextNum = config.getOcrGetAllTextNum();
        ocrImgFindArea = config.getImgFindArea();
        matchingThreshold = config.getMatchingThreshold() == null ? 0.5 : Double.parseDouble(config.getMatchingThreshold());
        ocrGetVerificationCode = config.getOcrGetVerificationCode();
        ocrGetSafeKeyBoardNum = config.getGetSafeKeyBoardNum();
        ocrGetTextDirectionText = config.getOcrGetTextDirectionText();
    }

    @Override
    public TapXYData doFindTextByOcr(String base64Str, String ocrText, Integer diffussion, Integer index, Double x, Double y) {
        TapXYData result = null;
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        Map<String, Object> ocrParamMap = new HashMap<>();
        ocrParamMap.put("img_base64", base64Str);
        ocrParamMap.put("targets", ocrText);
        ocrParamMap.put("diffussion", diffussion != null ? diffussion : 1);
        HttpEntity<Map<String, Object>> ocrEntity = new HttpEntity<>(ocrParamMap, headers);
        List ocrResultList = null;
        try {
            ocrResultList = HttpUtils.doPost(ocrGetAllTextNum, ocrEntity, List.class);
            logger.info("得到的ocr结果：{}", ocrResultList);
        } catch (Exception e) {
            logger.error("ocr失败", e);
        }
        if (!CollectionUtils.isEmpty(ocrResultList)) {
            Object all = ocrResultList.get(0);
            JSONObject jsonObject = JSONObject.parseObject(JSONArray.toJSONString(all));
            //todo：如果传了;是多个文本一起找，暂时只考虑一个文本
            JSONArray pointData = jsonObject.getJSONArray(ocrText);   //所有坐标
            JSONObject pointMap = null;
            if (pointData != null && pointData.size() == 1) {   //只找到一个，直接返回
                pointMap = pointData.getJSONObject(0);
                logger.info("只找到一个，直接返回结果：{}", pointMap);
                result = new TapXYData();
                result.setX((x.intValue() + pointMap.getInteger("x") + pointMap.getInteger("w") / 2));
                result.setY((y.intValue() + pointMap.getInteger("y") + pointMap.getInteger("h") / 2));
            } else if (pointData != null && pointData.size() > 1) {   //找到多个，选择用户选择的第几个
                if (index > 0) {
                    if (index <= pointData.size()) {
                        JSONObject dataJSONObject = pointData.getJSONObject(index - 1);
                        result = new TapXYData();
                        result.setX((dataJSONObject.getInteger("x") + dataJSONObject.getInteger("w") / 2));
                        result.setY((dataJSONObject.getInteger("y") + dataJSONObject.getInteger("h") / 2));
                    } else {
                        logger.warn("实际找到{}个，选择第{}个", pointData.size(), index);
                        throw new ExecuteException(String.format("选择元素的位置大于找到元素的个数，找到元素%s个", pointData.size()));
                    }
                }
            }
        }
        return result;
    }

    @Override
    public TapXYData doImgFindImg(File sourceFile, String resolution_s, String resolution_l, String picName, String stepToken) {
        TapXYData result = null;
        logger.info("以图找图分辨率参数resolution_s:{}, resolution_l:{}", resolution_s, resolution_l);
        String serverAddress = SpringUtils.getProperties("nk.mobile-computer.serverAddr");  //图片下载地址
        String picDownloadAddress = SpringUtils.getProperties("nk.mobile-computer.publicDownloadFile");  //图片下载地址
        logger.info("图片下载地址{}", picDownloadAddress);
        String picDownloadUrl = serverAddress + picDownloadAddress.replace("{appUrl}", picName);
        HttpUtils.downloadFileToLocal(picDownloadUrl, System.getProperty("user.dir") + "/tempPic", picName);
        File file = new File(System.getProperty("user.dir") + "/tempPic/" + picName);
        String targetBase64 = Base64.encode(file);
        String sourceBase64 = Base64.encode(sourceFile);
        if (StringUtils.isNotBlank(targetBase64) && StringUtils.isNotBlank(sourceBase64)) {
            Map<String, BigDecimal> resultPoint = null;
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            Map<String, Object> param = new HashMap<>();
            param.put("sourceImage", sourceBase64);
            param.put("targetImage", targetBase64);
            param.put("matchingThreshold", matchingThreshold);
            param.put("resolution_s", StringUtils.isNotBlank(resolution_s) ? resolution_s.replace("*", "x") : "");
            param.put("resolution_l", resolution_l);
            HttpEntity<Map> httpEntity = new HttpEntity<>(param, headers);
            try {
                URI uri = new URI(ocrImgFindArea);
                Map body = HttpUtils.doPost(uri, httpEntity, Map.class);
                Map<String, Object> bodyMap = JSONObject.parseObject(JSON.toJSONString(body)).getInnerMap();
                if (Boolean.parseBoolean(String.valueOf(bodyMap.get("success")))) {
                    resultPoint = (Map<String, BigDecimal>) bodyMap.get("data");
                }
            } catch (URISyntaxException e) {
                logger.error("找图像地址有误,:{}", e);
            } catch (Exception e) {
                logger.error("请求图像解析服务失败,参数:{},错误:{}", JSON.toJSONString(param), e);
            }
            if (null != resultPoint) {
                logger.info("步骤【{}】找到区域位置为:{}", stepToken, JSON.toJSONString(resultPoint));
                int clickTrueX = new Double((resultPoint.get("x").doubleValue() + resultPoint.get("w").doubleValue() / 2)).intValue();
                int clickTrueY = new Double((resultPoint.get("y").doubleValue() + resultPoint.get("h").doubleValue() / 2)).intValue();
                result = new TapXYData();
                result.setX(clickTrueX);
                result.setY(clickTrueY);
            } else {
                logger.warn("步骤【{}】未找到对应的图像", stepToken);
            }
        } else {
            logger.warn("步骤【{}】下载的图像或者截图为空...............", stepToken);
        }
        return result;
    }

    @Override
    public String getTextValue(String targetBase64){
        String value = null;
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        Map<String, Object> ocrParamMap = new HashMap<>();
        ocrParamMap.put("img_base64", targetBase64);
        ocrParamMap.put("targets", "");
        HttpEntity<Map> ocrEntity = new HttpEntity<>(ocrParamMap, headers);
        List ocrResultList = null;
        try {
            logger.info("传参：{}", JSON.toJSONString(ocrParamMap));
            ocrResultList = HttpUtils.doPost(ocrGetAllTextNum, ocrEntity, List.class);
            logger.info("得到的ocr结果：{}", ocrResultList);
        } catch (Exception e) {
            logger.error("ocr失败", e);
        }
        StringJoiner dataList = new StringJoiner("");
        if (!CollectionUtils.isEmpty(ocrResultList)) {
            if (!CollectionUtils.isEmpty(ocrResultList)) {
                for (Object o : ocrResultList) {
                    dataList.add(((Map) o).get("text") + "");
                }
            }
            value = dataList.toString();
        }
        logger.info("识别的图片文字为：{}", value);
        return value;
    }

    @Override
    public String getVerificationCodeByBase64(String base64, Integer codeType) {
        String value = null;
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            Map<String, Object> ocrParamMap = new HashMap<>();
            ocrParamMap.put("img_base64", base64);
            ocrParamMap.put("type", codeType);
            HttpEntity<Map<String, Object>> ocrEntity = new HttpEntity<>(ocrParamMap, headers);
            value = HttpUtils.doPost(new URI(ocrGetVerificationCode), ocrEntity, String.class);
        }catch (URISyntaxException e) {
            logger.error("ocr地址有误！===>{}",ocrGetVerificationCode,e);
        } catch (Exception e) {
            logger.error("请求ocr接口失败，接口地址：{}",ocrGetVerificationCode,e);
        }
        logger.info("识别到的验证码为：{}", value);
        return value == null ? value : value.replace("\"", "");
    }

    public List getKeyBoardInfo(String ocrArea) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("Content-Type", "application/json");
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("img_base64", ocrArea);
        HttpEntity<Map> entity = new HttpEntity<>(paramMap, httpHeaders);
        logger.info("识别键盘地址为：{}", ocrGetSafeKeyBoardNum);
        List result = HttpUtils.doPost(ocrGetSafeKeyBoardNum, entity, List.class);
        return result;
    }

    public JSONObject getTextDirectionText(String imgBase64,String text,String direction,Integer index){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        Map<String, Object> ocrParamMap = new HashMap<>();
        ocrParamMap.put("image_base64", imgBase64);
        ocrParamMap.put("targets", text);
        ocrParamMap.put("direction", direction);
        ocrParamMap.put("n", index);
        HttpEntity<Map> ocrEntity = new HttpEntity<>(ocrParamMap, headers);
        JSONObject ocrResultMap = null;
        try {
            logger.info("传参：{}", JSON.toJSONString(ocrParamMap));
            ocrResultMap = HttpUtils.doPostForGetTextDirectionText(ocrGetTextDirectionText, ocrEntity, JSONObject.class);
            logger.info("得到的ocr结果：{}", ocrResultMap);
        } catch (Exception e) {
            logger.error("ocr失败", e);
            if (e != null && e.getMessage() != null && e.getMessage().contains("Target text not found in image")) {
                throw new ExecuteException("未找到指定文本");
            }
        }
        return ocrResultMap;
    }
}
