package com.lingyue.ai.service.impl;

import com.lingyue.ai.client.PythonNerClient;
import com.lingyue.ai.dto.ner.*;
import com.lingyue.ai.service.NerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * NER 服务实现
 * 
 * 负责调用 Python NER 服务进行实体提取和关系抽取。
 * 图数据库的保存操作由 graph-service 模块的 GraphNerService 负责。
 *
 * @author lingyue
 * @since 2026-01-19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class NerServiceImpl implements NerService {

    private final PythonNerClient pythonNerClient;

    @Override
    public NerResponse extractEntities(NerRequest request) {
        log.info("开始提取实体: documentId={}, textLength={}", 
                request.getDocumentId(), 
                request.getText() != null ? request.getText().length() : 0);
        
        long startTime = System.currentTimeMillis();
        
        try {
            // 验证请求
            if (request.getText() == null || request.getText().isEmpty()) {
                return NerResponse.error(request.getDocumentId(), "文本内容不能为空");
            }
            
            // 调用 Python NER 服务
            NerResponse response = pythonNerClient.extractEntities(request);
            
            long processingTime = System.currentTimeMillis() - startTime;
            log.info("实体提取完成: documentId={}, entityCount={}, relationCount={}, time={}ms",
                    request.getDocumentId(), 
                    response.getEntityCount(), 
                    response.getRelationCount(),
                    processingTime);
            
            return response;
            
        } catch (Exception e) {
            log.error("实体提取失败: documentId={}", request.getDocumentId(), e);
            return NerResponse.error(request.getDocumentId(), e.getMessage());
        }
    }

    @Override
    @Async
    public CompletableFuture<NerResponse> extractEntitiesAsync(NerRequest request) {
        return CompletableFuture.supplyAsync(() -> extractEntities(request));
    }

    @Override
    public RelationResponse extractRelations(RelationRequest request) {
        log.info("开始提取关系: documentId={}, entityCount={}", 
                request.getDocumentId(), 
                request.getEntities() != null ? request.getEntities().size() : 0);
        
        try {
            // 验证请求
            if (request.getEntities() == null || request.getEntities().size() < 2) {
                return RelationResponse.success(request.getDocumentId(), Collections.emptyList(), 0);
            }
            
            // 调用 Python NER 服务
            RelationResponse response = pythonNerClient.extractRelations(request);
            
            log.info("关系提取完成: documentId={}, relationCount={}", 
                    request.getDocumentId(), response.getRelationCount());
            
            return response;
            
        } catch (Exception e) {
            log.error("关系提取失败: documentId={}", request.getDocumentId(), e);
            return RelationResponse.error(request.getDocumentId(), e.getMessage());
        }
    }

    @Override
    public NerResponse extractAndSaveForDocument(String documentId, String userId) {
        // 此方法由 graph-service 的 GraphNerService 实现
        // ai-service 只提供基础的 NER 能力
        log.warn("extractAndSaveForDocument 应由 graph-service 的 GraphNerService 调用");
        return NerResponse.error(documentId, "请使用 GraphNerService 进行文档级 NER 处理");
    }

    @Override
    @Async
    public CompletableFuture<NerResponse> extractAndSaveForDocumentAsync(String documentId, String userId) {
        return CompletableFuture.supplyAsync(() -> extractAndSaveForDocument(documentId, userId));
    }

    @Override
    public List<List<EntityInfo>> batchExtractEntities(List<String> texts) {
        log.info("批量提取实体: count={}", texts.size());
        
        return texts.stream()
                .map(text -> {
                    try {
                        NerRequest request = NerRequest.builder()
                                .text(text)
                                .extractRelations(false)
                                .build();
                        NerResponse response = extractEntities(request);
                        return response.getEntities() != null ? response.getEntities() : Collections.<EntityInfo>emptyList();
                    } catch (Exception e) {
                        log.warn("批量提取实体失败: {}", e.getMessage());
                        return Collections.<EntityInfo>emptyList();
                    }
                })
                .collect(Collectors.toList());
    }
}
