package com.zhpb.gdyd_zhpb_zgf.service;

import com.zhpb.gdyd_zhpb_zgf.entity.mysql.File;
import com.zhpb.gdyd_zhpb_zgf.entity.mysql.OcrResult;
import com.zhpb.gdyd_zhpb_zgf.repository.mysql.FileRepository;
import com.zhpb.gdyd_zhpb_zgf.repository.mysql.OcrResultRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * OCR服务
 * 负责管理PDF文件的OCR识别任务
 */
@Service
public class OcrService {

    private static final Logger logger = LoggerFactory.getLogger(OcrService.class);

    @Autowired
    private UmiOcrClient umiOcrClient;

    @Autowired
    private OcrResultRepository ocrResultRepository;

    @Autowired
    private FileRepository fileRepository;

    /**
     * 异步处理PDF文件的OCR识别
     */
    @Async
    public void processPdfOcrAsync(Long fileId, String filePath, String projectId, String supplierId) {
        logger.info("🚀 开始异步处理PDF OCR: fileId={}, filePath={}, projectId={}, supplierId={}",
                   fileId, filePath, projectId, supplierId);

        try {
            // 检查文件是否存在
            java.io.File file = new java.io.File(filePath);
            if (!file.exists()) {
                logger.error("❌ OCR文件不存在: {}", filePath);
                updateOcrResult(fileId, "failed", null, null, null, "文件不存在: " + filePath);
                return;
            }

            logger.info("📁 OCR文件存在，大小: {} bytes", file.length());
            // 检查是否已存在OCR结果
            Optional<OcrResult> existingResult = ocrResultRepository.findByFileId(fileId);
            if (existingResult.isPresent()) {
                logger.info("文件已存在OCR结果，跳过处理: fileId={}", fileId);
                return;
            }

            // 创建OCR结果记录
            OcrResult ocrResult = new OcrResult();
            ocrResult.setFileId(fileId);
            ocrResult.setProjectId(projectId);
            ocrResult.setSupplierId(supplierId);
            ocrResult.setStatus("processing");
            ocrResult.setStartTime(LocalDateTime.now());
            ocrResult = ocrResultRepository.save(ocrResult);

            // 执行OCR识别 - 使用简化的配置避免页数范围问题
            Map<String, Object> options = Map.of(
                "ocr.language", "models/config_chinese.txt"
                // 不设置页数范围，让OCR服务自动处理
            );

            List<String> downloadFileTypes = List.of("pdfLayered", "txtPlain");

            Map<String, Object> ocrResultData = umiOcrClient.runDocOcrSync(
                filePath, options, downloadFileTypes, 5);

            // 更新OCR结果
            ocrResult.setStatus("success");
            ocrResult.setOcrTaskId((String) ocrResultData.get("task_id"));
            ocrResult.setRecognizedText((String) ocrResultData.get("recognized_text"));
            ocrResult.setEndTime(LocalDateTime.now());
            ocrResult.setUpdateTime(LocalDateTime.now());

            @SuppressWarnings("unchecked")
            Map<String, String> downloadInfo = (Map<String, String>) ocrResultData.get("download_info");
            if (downloadInfo != null) {
                ocrResult.setDownloadUrl(downloadInfo.get("download_url"));
                ocrResult.setDownloadFileName(downloadInfo.get("file_name"));
            }

            // 解析页数信息（从响应中提取）
            // 这里可以根据实际需要添加更多字段

            ocrResultRepository.save(ocrResult);

            logger.info("✅ PDF OCR处理完成: fileId={}, taskId={}, 识别文本长度={}",
                       fileId, ocrResult.getOcrTaskId(),
                       ocrResult.getRecognizedText() != null ? ocrResult.getRecognizedText().length() : 0);

        } catch (Exception e) {
            logger.error("❌ PDF OCR处理失败: fileId={}, error={}", fileId, e.getMessage(), e);
            updateOcrResult(fileId, "failed", null, null, null, e.getMessage());
        }
    }

    /**
     * 根据文件ID获取OCR结果
     */
    public Optional<OcrResult> getOcrResultByFileId(Long fileId) {
        return ocrResultRepository.findByFileId(fileId);
    }

    /**
     * 根据项目ID获取OCR结果列表
     */
    public List<OcrResult> getOcrResultsByProject(String projectId) {
        return ocrResultRepository.findByProjectId(projectId);
    }

    /**
     * 根据项目和供应商获取OCR结果
     */
    public List<OcrResult> getOcrResultsByProjectAndSupplier(String projectId, String supplierId) {
        return ocrResultRepository.findByProjectIdAndSupplierId(projectId, supplierId);
    }

    /**
     * 获取失败的OCR任务（用于重试）
     */
    public List<OcrResult> getFailedOcrTasks() {
        return ocrResultRepository.findFailedOcrTasks();
    }

    /**
     * 重试失败的OCR任务
     */
    @Async
    public void retryFailedOcrTask(Long ocrResultId) {
        Optional<OcrResult> ocrResultOpt = ocrResultRepository.findById(ocrResultId);
        if (!ocrResultOpt.isPresent()) {
            logger.warn("OCR结果不存在: id={}", ocrResultId);
            return;
        }

        OcrResult ocrResult = ocrResultOpt.get();
        if (!"failed".equals(ocrResult.getStatus())) {
            logger.info("OCR任务状态不是失败状态，无需重试: id={}", ocrResultId);
            return;
        }

        // 获取对应的文件信息
        Optional<File> fileOpt = fileRepository.findById(ocrResult.getFileId());
        if (!fileOpt.isPresent()) {
            logger.warn("对应的文件不存在: fileId={}", ocrResult.getFileId());
            return;
        }

        File file = fileOpt.get();

        // 重新执行OCR
        logger.info("开始重试OCR任务: fileId={}, ocrResultId={}", file.getId(), ocrResultId);
        processPdfOcrAsync(file.getId(), file.getFilePath(), file.getProjectId(), file.getSupplierId());
    }

    /**
     * 获取项目OCR统计信息
     */
    public Map<String, Object> getProjectOcrStatistics(String projectId) {
        List<Object[]> stats = ocrResultRepository.getProjectOcrStatistics(projectId);

        Map<String, Object> result = Map.of(
            "totalPdfFiles", stats.get(0)[0] != null ? ((Number) stats.get(0)[0]).intValue() : 0,
            "successfulOcr", stats.get(0)[1] != null ? ((Number) stats.get(0)[1]).intValue() : 0,
            "failedOcr", stats.get(0)[2] != null ? ((Number) stats.get(0)[2]).intValue() : 0,
            "processingOcr", stats.get(0)[3] != null ? ((Number) stats.get(0)[3]).intValue() : 0
        );

        return result;
    }

    /**
     * 更新OCR结果状态的辅助方法
     */
    private void updateOcrResult(Long fileId, String status, String recognizedText,
                                String downloadUrl, String downloadFileName, String errorMessage) {
        try {
            Optional<OcrResult> resultOpt = ocrResultRepository.findByFileId(fileId);
            if (resultOpt.isPresent()) {
                OcrResult ocrResult = resultOpt.get();
                ocrResult.setStatus(status);
                if (recognizedText != null) ocrResult.setRecognizedText(recognizedText);
                if (downloadUrl != null) ocrResult.setDownloadUrl(downloadUrl);
                if (downloadFileName != null) ocrResult.setDownloadFileName(downloadFileName);
                if (errorMessage != null) ocrResult.setErrorMessage(errorMessage);
                ocrResult.setEndTime(LocalDateTime.now());
                ocrResult.setUpdateTime(LocalDateTime.now());
                ocrResultRepository.save(ocrResult);
                logger.info("✅ 更新OCR结果状态: fileId={}, status={}", fileId, status);
            } else {
                logger.warn("⚠️ 未找到OCR结果记录: fileId={}", fileId);
            }
        } catch (Exception e) {
            logger.error("❌ 更新OCR结果状态失败: fileId={}", fileId, e);
        }
    }
}
