package com.gree.mall.miniapp.utils.ocr;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Map;

@Service
@Slf4j
public class OCRUtil {
//    阿里OCR手写识别
//    @Value("${ali.access.key.id}")
//    private String ACCESS_KEY_ID;
//    @Value("${ali.access.key.secert}")
//    private String ACCESS_KEY_SECERT;
//
//    public AsyncClient buildClient() {
//        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
//                .accessKeyId(ACCESS_KEY_ID)
//                .accessKeySecret(ACCESS_KEY_SECERT)
//                .build());
//        return AsyncClient.builder()
//                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
//                .credentialsProvider(provider)
//                //.serviceConfiguration(Configuration.create()) // Service-level configuration
//                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
//                .overrideConfiguration(
//                        ClientOverrideConfiguration.create()
//                                // Endpoint 请参考 https://api.aliyun.com/product/ocr-api
//                                // 服务地址 ocr-api.cn-hangzhou.aliyuncs.com
//                                // VPC地址 ocr-api-vpc.cn-hangzhou.aliyuncs.com
//                                .setEndpointOverride("ocr-api.cn-hangzhou.aliyuncs.com")
//                        //.setConnectTimeout(Duration.ofSeconds(30))
//                )
//                .build();
//    }
//
//    public String handwritingORC(ByteArrayInputStream byteArrayInputStream) {
//        AsyncClient client = buildClient();
//        // Parameter settings for API request
//        RecognizeHandwritingRequest recognizeHandwritingRequest = RecognizeHandwritingRequest.builder()
//                .body(byteArrayInputStream)
//                .needRotate(false)
//                .paragraph(true)
//                // Request-level configuration rewrite, can set Http request parameters, etc.
//                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
//                .build();
//        CompletableFuture<RecognizeHandwritingResponse> response = client.recognizeHandwriting(recognizeHandwritingRequest);
//        String content = "";
//        try {
//            final RecognizeHandwritingResponse resp = response.get();
//            final RecognizeHandwritingResponseBody body = resp.getBody();
//            final JSONObject data = JSONUtil.parseObj(body.getData());
//            log.info(body.getData());
//            content = StrUtil.replace(data.get("content", String.class), " ", "");
//        } catch (Exception e) {
//            throw new RemoteServiceException("OCR服务异常" + e.getMessage());
//        } finally {
//            client.close();
//        }
//
//        return content;
//    }

    private static final String API_KEY = "rQX5f1IdlpKGFHypnyLetH80";
    private static final String SECRET_KEY = "H38soq4UuIjUJ7eeZPPxv1ZR6e23jKDx";
    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();

    /**
     * 从用户的AK，SK生成鉴权签名（Access Token）
     *
     * @return 鉴权签名（Access Token）
     * @throws IOException IO异常
     */
    private static String getAccessToken() throws IOException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + API_KEY
                + "&client_secret=" + SECRET_KEY);
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        return new JSONObject(response.body().string()).getStr("access_token");
    }

    /**
     * 获取文件base64编码
     *
     * @param path      文件路径
     * @param urlEncode 如果Content-Type是application/x-www-form-urlencoded时,传true
     * @return base64编码信息，不带文件头
     * @throws IOException IO异常
     */
    private static String getFileContentAsBase64(String path, String imageBase64, boolean urlEncode) throws IOException {
        String base64 = imageBase64;
        if (StringUtils.isNotBlank(path)) {
            byte[] b = Files.readAllBytes(Paths.get(path));
            base64 = Base64.getEncoder().encodeToString(b);
        }

        if (urlEncode) {
            base64 = URLEncoder.encode(base64, "utf-8");
        }
        return base64;
    }

    public String handwritingORC(String imageBase64) throws IOException{
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        // image 可以通过 getFileContentAsBase64("C:\fakepath\1735789516918.png") 方法获取,如果Content-Type是application/x-www-form-urlencoded时,第二个参数传true
        RequestBody body = RequestBody.create(mediaType, "image=" + getFileContentAsBase64("", imageBase64,true) + "&detect_direction=true&probability=false&detect_alteration=false");
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/rest/2.0/ocr/v1/handwriting?access_token=" + getAccessToken())
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "application/json")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        final String result = response.body().string();
        log.info("百度OCR返回结果:" + result);
        final JSONObject jsonBody = new JSONObject(result);
        final JSONArray jsonArray = jsonBody.getJSONArray("words_result");
        if (jsonArray.size() <= 0) {
            return "";
        }
        final Object words = jsonArray.getBean(0, Map.class).get("words");
        return words.toString();
    }
}
