package cn.meowrain.aioj.backend.aiservice.service.impl;

import cn.meowrain.aioj.backend.aiservice.client.AIServiceGrpcClient;
import cn.meowrain.aioj.backend.aiservice.dto.req.*;
import cn.meowrain.aioj.backend.aiservice.dto.resp.*;
import cn.meowrain.aioj.backend.aiservice.grpc.*;
import cn.meowrain.aioj.backend.aiservice.service.AIService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.stream.Collectors;

/**
 * AI 服务实现
 */
@Slf4j
@Service
public class AIServiceImpl implements AIService {

    private final AIServiceGrpcClient grpcClient;

    public AIServiceImpl(AIServiceGrpcClient grpcClient) {
        this.grpcClient = grpcClient;
    }

    @Override
    public AnalyzeCodeRespDTO analyzeCode(AnalyzeCodeReqDTO request) {
        log.info("Analyzing code for language: {}, questionId: {}", request.getLanguage(), request.getQuestionId());

        AnalyzeCodeResponse grpcResponse = grpcClient.analyzeCode(
                request.getCode(),
                request.getLanguage(),
                request.getQuestionId() != null ? request.getQuestionId() : "",
                request.getUserId() != null ? request.getUserId() : ""
        );

        CodeAnalysisRespDTO analysis = null;
        if (grpcResponse.getSuccess() && grpcResponse.hasAnalysis()) {
            CodeAnalysis grpcAnalysis = grpcResponse.getAnalysis();
            analysis = CodeAnalysisRespDTO.builder()
                    .issues(grpcAnalysis.getIssuesList())
                    .suggestions(grpcAnalysis.getSuggestionsList())
                    .complexityScore(grpcAnalysis.getComplexityScore())
                    .performanceScore(grpcAnalysis.getPerformanceScore())
                    .readabilityScore(grpcAnalysis.getReadabilityScore())
                    .timeComplexity(grpcAnalysis.getTimeComplexity())
                    .spaceComplexity(grpcAnalysis.getSpaceComplexity())
                    .bestPractices(grpcAnalysis.getBestPracticesList())
                    .build();
        }

        return AnalyzeCodeRespDTO.builder()
                .success(grpcResponse.getSuccess())
                .message(grpcResponse.getMessage())
                .analysis(analysis)
                .build();
    }

    @Override
    public OptimizeCodeRespDTO optimizeCode(OptimizeCodeReqDTO request) {
        log.info("Optimizing code for language: {}, type: {}", request.getLanguage(), request.getOptimizationType());

        OptimizeCodeResponse grpcResponse = grpcClient.optimizeCode(
                request.getCode(),
                request.getLanguage(),
                request.getOptimizationType() != null ? request.getOptimizationType() : "performance"
        );

        return OptimizeCodeRespDTO.builder()
                .success(grpcResponse.getSuccess())
                .message(grpcResponse.getMessage())
                .optimizedCode(grpcResponse.getOptimizedCode())
                .improvements(grpcResponse.getImprovementsList())
                .build();
    }

    @Override
    public GenerateTestCasesRespDTO generateTestCases(GenerateTestCasesReqDTO request) {
        log.info("Generating test cases for language: {}", request.getLanguage());

        GenerateTestCasesResponse grpcResponse = grpcClient.generateTestCases(
                request.getCode(),
                request.getLanguage(),
                request.getProblemDescription()
        );

        var testCases = grpcResponse.getTestCasesList().stream()
                .map(tc -> TestCaseDTO.builder()
                        .input(tc.getInput())
                        .expectedOutput(tc.getExpectedOutput())
                        .description(tc.getDescription())
                        .build())
                .collect(Collectors.toList());

        return GenerateTestCasesRespDTO.builder()
                .success(grpcResponse.getSuccess())
                .message(grpcResponse.getMessage())
                .testCases(testCases)
                .build();
    }

    @Override
    public ExplainCodeRespDTO explainCode(ExplainCodeReqDTO request) {
        log.info("Explaining code for language: {}, level: {}", request.getLanguage(), request.getDetailLevel());

        ExplainCodeResponse grpcResponse = grpcClient.explainCode(
                request.getCode(),
                request.getLanguage(),
                request.getDetailLevel() != null ? request.getDetailLevel() : "normal"
        );

        return ExplainCodeRespDTO.builder()
                .success(grpcResponse.getSuccess())
                .message(grpcResponse.getMessage())
                .explanation(grpcResponse.getExplanation())
                .keyPoints(grpcResponse.getKeyPointsList())
                .build();
    }
}
