package com.heyu.api.controller.ocr;


import com.heyu.api.alibaba.LLMUtils;
import com.heyu.api.alibaba.bailian.AlibabaOCREnums;
import com.heyu.api.alibaba.request.common.text.AIOcrRequest;
import com.heyu.api.alibaba.resp.ModelResult;
import com.heyu.api.baidu.handle.common.BPaddleOcrHandle;
import com.heyu.api.baidu.handle.common.BPaddleOcrQueryHandle;
import com.heyu.api.baidu.handle.common.BTableHandle;
import com.heyu.api.baidu.request.common.ATableRequest;
import com.heyu.api.baidu.request.common.BPaddleOcrQueryRequest;
import com.heyu.api.baidu.request.common.BPaddleOcrRequest;
import com.heyu.api.baidu.response.common.ATableResp;
import com.heyu.api.baidu.response.common.BPaddleOcrQueryResp;
import com.heyu.api.baidu.response.common.BPaddleOcrResp;
import com.heyu.api.data.annotation.EbAuthentication;
import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.utils.ApiR;
import com.heyu.api.data.utils.R;
import com.heyu.api.data.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/ai/orc/")
public class AIOcrController {


    @Autowired
    private BTableHandle bTableHandle;

    @Autowired
    private BPaddleOcrHandle bPaddleOcrHandle;

    @Autowired
    private BPaddleOcrQueryHandle bPaddleOcrQueryHandle;


    //  http://localhost:8888/ai/precision/orc/recognize?imageBase64=3232
    // https://heyuoss.oss-cn-shanghai.aliyuncs.com/prd/testxxx.jpg

    // 1. advanced_recognition : 高精识别 ,
    /***
     *  仅qwen-vl-ocr-2025-08-28模型支持，具有以下特性：
     * 识别文本内容（提取文字）
     * 检测文本位置（定位文本行、获取坐标）
     */
    @EbAuthentication(tencent = ApiConstants.TENCENT_AUTH)
    @RequestMapping("/advanced/recognition")
    public R advanced_recognition(@RequestBody AIOcrRequest aiOcrRequest) throws Exception {
        ModelResult modelResult = LLMUtils.callOcr(aiOcrRequest.getImageUrl(), aiOcrRequest.getImageBase64(),
                AlibabaOCREnums.advanced_recognition);
        Map<String, Object> data = new HashMap<>();
        data.put("content", modelResult.getResult());
        return R.ok().setData(data);
    }


    //  http://localhost:8888/ai/precision/orc/recognize?imageBase64=3232
    // https://heyuoss.oss-cn-shanghai.aliyuncs.com/prd/testxxx.jpg
    //    2. info_draw: 信息抽取
    /***
     * 模型支持对票据、证件、表单中的信息进行抽取，并以带有JSON格式的文本返回。
     *
     * result_schema可以是任意形式的JSON结构，最多可嵌套3层JSON 对象。您只需要填写JSON对象的key，value保持为空即可。
     */
    @EbAuthentication(tencent = ApiConstants.TENCENT_AUTH)
    @RequestMapping("/info/draw")
    public R info_draw(@RequestBody AIOcrRequest aiOcrRequest) throws Exception {
        ModelResult modelResult = LLMUtils.callOcr(aiOcrRequest.getImageUrl(), aiOcrRequest.getImageBase64(),
                AlibabaOCREnums.key_information_extraction);
        Map<String, Object> data = new HashMap<>();
        data.put("content", modelResult.getResult());
        return R.ok().setData(data);
    }


    //  http://localhost:8888/ai/precision/orc/recognize?imageBase64=3232
    // https://heyuoss.oss-cn-shanghai.aliyuncs.com/prd/testxxx.jpg

    //    3. table_parsing: 表格解析（已从阿里大模型切换为百度表格识别API）
    /**
     * 使用百度表格识别API，将图片中的表格结构化输出，支持返回Excel和结构化JSON数据。
     * 请求参数：imageUrl / imageBase64（与阿里云百炼公用 AIOcrRequest）
     */
    @RequestMapping("/table/parsing")
    public R tableParsing(@RequestBody AIOcrRequest aiOcrRequest) {
        if (bTableHandle == null) {
            return R.error("表格识别服务暂不可用");
        }

        ATableRequest tableRequest = new ATableRequest();
        tableRequest.setImageBase64(aiOcrRequest.getImageBase64());
        tableRequest.setImageUrl(aiOcrRequest.getImageUrl());

        ApiR<ATableResp> apiR = bTableHandle.handle(tableRequest);
        if (apiR.isSuccess()) {
            return R.ok().setData(apiR.getData());
        }
        return R.error(apiR.getErrorMsg());
    }


    /**
     * 4. document_parsing : 文档解析（已从阿里大模型切换为百度 PaddleOCR-VL）
     *
     * 基于百度自研OCR大模型PaddleOCR-VL的文档解析能力。
     * 无 taskId 时提交文档解析任务；有 taskId 时查询解析结果。
     * 请求参数：imageUrl / imageBase64（提交时），或 taskId（查询时）
     */
    @RequestMapping("/document/parsing")
    public R documentParsing(@RequestBody AIOcrRequest aiOcrRequest) {
        // 有 taskId → 查询解析结果
        if (StringUtils.isNotBlank(aiOcrRequest.getTaskId())) {
            if (bPaddleOcrQueryHandle == null) {
                return R.error("文档解析查询服务暂不可用");
            }

            BPaddleOcrQueryRequest queryRequest = new BPaddleOcrQueryRequest();
            queryRequest.setTaskId(aiOcrRequest.getTaskId());
            ApiR<BPaddleOcrQueryResp> apiR = bPaddleOcrQueryHandle.handle(queryRequest);
            if (apiR.isSuccess()) {
                return R.ok().setData(apiR.getData());
            }
            return R.error(apiR.getErrorMsg());
        }

        // 无 taskId → 使用 PaddleOCR-VL 提交文档解析任务
        if (bPaddleOcrHandle == null) {
            return R.error("文档解析服务暂不可用");
        }

        BPaddleOcrRequest paddleRequest = new BPaddleOcrRequest();
        paddleRequest.setFileName(aiOcrRequest.getFileName());
        paddleRequest.setFileUrl(StringUtils.isNotBlank(aiOcrRequest.getFileUrl())
                ? aiOcrRequest.getFileUrl()
                : aiOcrRequest.getImageUrl());
        paddleRequest.setFileData(StringUtils.isNotBlank(aiOcrRequest.getFileData())
                ? aiOcrRequest.getFileData()
                : aiOcrRequest.getImageBase64());

        ApiR<BPaddleOcrResp> apiR = bPaddleOcrHandle.handle(paddleRequest);
        if (apiR.isSuccess()) {
            return R.ok().setData(apiR.getData());
        }
        return R.error(apiR.getErrorMsg());
    }


    //  http://localhost:8888/ai/orc/text/recognition?imageUrl=https://heyuoss.oss-cn-shanghai.aliyuncs.com/prd/testxxx.jpg
    // https://heyuoss.oss-cn-shanghai.aliyuncs.com/prd/testxxx.jpg

    /***
     *
     /    4. text_recognition : 通用文字识别
     /**
     * 模型支持解析以图像形式存储的扫描件或PDF文档，能识别文件中的标题、摘要、标签等，以带有LaTeX格式的文本返回识别结果。
     */
    @EbAuthentication(tencent = ApiConstants.TENCENT_AUTH)
    @RequestMapping("/text/recognition")
    public R text_recognition(@RequestBody AIOcrRequest aiOcrRequest) throws Exception {
        ModelResult modelResult = LLMUtils.callOcr(aiOcrRequest.getImageUrl(), aiOcrRequest.getImageBase64(),
                AlibabaOCREnums.text_recognition);
        Map<String, Object> data = new HashMap<>();
        data.put("content", modelResult.getResult());
        return R.ok().setData(data);
    }



    //  http://localhost:8888/ai/precision/orc/recognize?imageBase64=3232
    // https://heyuoss.oss-cn-shanghai.aliyuncs.com/prd/testxxx.jpg
     //   5. formula_recognition: 公式识别
     /**
     * 模型支持解析图像中的公式，以带有LaTeX格式的文本返回识别结果。
     */
    @EbAuthentication(tencent = ApiConstants.TENCENT_AUTH)
    @RequestMapping("/formula/recognition")
    public R formula_recognition(@RequestBody AIOcrRequest aiOcrRequest) throws Exception {
        ModelResult modelResult = LLMUtils.callOcr(aiOcrRequest.getImageUrl(), aiOcrRequest.getImageBase64(),
                AlibabaOCREnums.formula_recognition);
        Map<String, Object> data = new HashMap<>();
        data.put("content", modelResult.getResult());
        return R.ok().setData(data);
    }

    //  http://localhost:8888/ai/precision/orc/recognize?imageBase64=3232
    // https://heyuoss.oss-cn-shanghai.aliyuncs.com/prd/testxxx.jpg
    //    multi_lan_recognition : 多语言识别
    /**
     * 多语言识别适用于针对中英文之外的小语种场景，支持的小语种有：阿拉伯语、法语、德语、意大利语、日语、韩语、葡萄牙语、俄语、西班牙语、越南语，以纯文本格式返回识别结果。
     */
    @EbAuthentication(tencent = ApiConstants.TENCENT_AUTH)
    @RequestMapping("/multi/lan/recognition")
    public R recognize(@RequestBody AIOcrRequest aiOcrRequest) throws Exception {
        ModelResult modelResult = LLMUtils.callOcr(aiOcrRequest.getImageUrl(),
                aiOcrRequest.getImageBase64(), AlibabaOCREnums.multi_lan);
        Map<String, Object> data = new HashMap<>();
        data.put("content", modelResult.getResult());
        return R.ok().setData(data);
    }

}

