package com.rj.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rj.entity.FaceDetectLog;
import com.rj.mapper.FaceDetectLogMapper;
import com.rj.service.IFaceDetectLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 图像检测日志服务实现
 */
@Slf4j
@Service
public class FaceDetectLogServiceImpl extends ServiceImpl<FaceDetectLogMapper, FaceDetectLog> implements IFaceDetectLogService {

    private static final String API_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/face-detect";
    private static final String API_URL_AA = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/aa-detect";

    @Value("${dashscope.api.key:}")
    private String apiKey;
    
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;
    
    public FaceDetectLogServiceImpl() {
        this.restTemplate = new RestTemplate();
        this.objectMapper = new ObjectMapper();
    }

    @Override
    public boolean saveFaceDetectLog(FaceDetectLog faceDetectLog) {
        try {
            return save(faceDetectLog);
        } catch (Exception e) {
            log.error("保存图像检测日志失败: {}", e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 执行图像检测并保存日志
     */
    public FaceDetectLog detectFaceAndSave(String imageUrl) {
        return detectFaceAndSave(imageUrl, null, null, null);
    }
    
    /**
     * 执行图像检测并保存日志（带扩展信息）
     */
    public FaceDetectLog detectFaceAndSave(String imageUrl, String ownerName, String ownerPhone, String avatarName) {
        return detectFaceAndSave(imageUrl, ownerName, ownerPhone, avatarName, null);
    }
    
    /**
     * 执行图像检测并保存日志（带扩展信息和模型名）
     */
    public FaceDetectLog detectFaceAndSave(String imageUrl, String ownerName, String ownerPhone, String avatarName, String model) {
        if (apiKey == null || apiKey.trim().isEmpty()) {
            log.error("DASHSCOPE_API_KEY未配置");
            return createErrorLog(imageUrl, "DASHSCOPE_API_KEY未配置", ownerName, ownerPhone, avatarName);
        }
        
        // 创建日志记录
        FaceDetectLog faceDetectLog = new FaceDetectLog();
        String requestId = UUID.randomUUID().toString();
        LocalDateTime requestTime = LocalDateTime.now();
        
        faceDetectLog.setRequestId(requestId);
        // 设置模型名称，如果未提供则使用默认值
        String modelName = (model != null && !model.trim().isEmpty()) ? model : "liveportrait-detect";
        faceDetectLog.setModel(modelName);
        log.info("使用模型: {}", modelName);
        faceDetectLog.setImageUrl(imageUrl);
        faceDetectLog.setOwnerName(ownerName);
        faceDetectLog.setOwnerPhone(ownerPhone);
        faceDetectLog.setAvatarName(avatarName);
        faceDetectLog.setRequestTime(requestTime);
        
        long startTime = System.currentTimeMillis();
        
        try {
            // 创建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", modelName);

            if (modelName.equals("emo-detect-v1") ||  modelName.equals("emoji-detect-v1")){
                Map<String, Object> ratioo = new HashMap<>();
                ratioo.put("ratio", "1:1");
                requestBody.put("parameters", ratioo);
            }

            Map<String, String> input = new HashMap<>();
            input.put("image_url", imageUrl);
            requestBody.put("input", input);
            
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.setBearerAuth(apiKey);
            log.info("发送图像检测请求，requestBody : {}, 请求参数headers: {}", requestBody , headers);
            // 创建请求实体     parameters.ratio   希望检测确认的画幅，可选 "1:1"或"3:4"。默认值为"1:1"。
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
            ResponseEntity<String> response = null;
            if ( modelName.equals("animate-anyone-detect-gen2")){
                response = restTemplate.exchange(
                        API_URL_AA,
                        HttpMethod.POST,
                        requestEntity,
                        String.class
                );
            }else {
                response = restTemplate.exchange(
                        API_URL,
                        HttpMethod.POST,
                        requestEntity,
                        String.class
                );
            }

            // 发送请求
            log.info("发送图像检测请求，response {}, 图片URL: {}", response, imageUrl);

            // 计算处理时间
            long endTime = System.currentTimeMillis();
            long processingTime = endTime - startTime;
            
            // 更新日志记录
            faceDetectLog.setResponseTime(LocalDateTime.now());
            faceDetectLog.setStatusCode(response.getStatusCode().value());
            faceDetectLog.setProcessingTimeMs(processingTime);
            faceDetectLog.setResponseData(response.getBody());
            
            // 处理响应
            log.info("图像检测响应，response: {}, 处理时间: {}ms", response.toString(), processingTime);
            
            // 解析JSON响应
            if (response.getStatusCode() == HttpStatus.OK) {
                faceDetectLog.setSuccess( true);
                JsonNode jsonResponse = objectMapper.readTree(response.getBody());
                
                // 根据pass字段判断是否成功
                boolean isSuccess = false;
                if (jsonResponse.has("output") && jsonResponse.get("output").has("pass")) {
                    isSuccess = jsonResponse.get("output").get("pass").asBoolean();
                    faceDetectLog.setSuccess(isSuccess);
                    
                    log.info("图像检测结果 - 头像 pass: {}", isSuccess);
                }

                if (jsonResponse.has("output") && jsonResponse.get("output").has("check_pass")) {
                    isSuccess = jsonResponse.get("output").get("check_pass").asBoolean();
                    faceDetectLog.setSuccess(isSuccess);

                    log.info("图像检测结果 (animate-anyone-detect-gen2 舞动人像 )- check_pass: {}", isSuccess);
                }
                // 检查是否有检测到图像
                int faceCount = 0;
                if (jsonResponse.has("output")) {
                    JsonNode output = jsonResponse.get("output");
                    
                    // 根据pass字段判断是否检测到图像
                    if (output.has("pass")) {
                        boolean pass = output.get("pass").asBoolean(); 
                        faceDetectLog.setFaceCount(1);
                        
                        log.info("图像检测结果 - pass: {}, 检测到图像数量: {}", pass, faceDetectLog.getFaceCount());
                        
                        // 记录message信息
                        if (output.has("message")) {
                            String message = output.get("message").asText();
                            log.info("检测消息: {}", message);
                        }
                    }
                    
                    // 解析图像区域坐标（如果API返回中包含）
                    if (output.has("face_bbox")) {
                        JsonNode faceBbox = output.get("face_bbox");
                        if (faceBbox.isArray()) {
                            String faceBboxStr = faceBbox.toString();
                            faceDetectLog.setFaceBbox(faceBboxStr);
                            log.info("图像区域坐标: {}", faceBboxStr);
                        }
                    }
                    
                    // 解析动态区域坐标（如果API返回中包含）
                    if (output.has("ext_bbox")) {
                        JsonNode extBbox = output.get("ext_bbox");
                        if (extBbox.isArray()) {
                            String extBboxStr = extBbox.toString();
                            faceDetectLog.setExtBbox(extBboxStr);
                            log.info("动态区域坐标: {}", extBboxStr);
                        }
                    }
                }

                //emoji  开始
                if (jsonResponse.has("output") && jsonResponse.get("output").has("ext_bbox_face")) {
                    String ext_bbox = jsonResponse.get("output").get("ext_bbox_face").toString();
                    faceDetectLog.setExtBbox(ext_bbox);
                }
                if (jsonResponse.has("output") && jsonResponse.get("output").has("bbox_face")) {
                    String bboxFace = jsonResponse.get("output").get("bbox_face").toString();
                    faceDetectLog.setFaceBbox(bboxFace);
                }
                //emoji  结束
                
                // 记录请求ID
                if (jsonResponse.has("request_id")) {
                    String apiRequestId = jsonResponse.get("request_id").asText();
                    log.info("API请求ID: {}", apiRequestId);
                }
                
                // 记录使用情况
                if (jsonResponse.has("usage")) {
                    JsonNode usage = jsonResponse.get("usage");
                    if (usage.has("image_count")) {
                        int imageCount = usage.get("image_count").asInt();
                        log.info("处理的图片数量: {}", imageCount);
                        // 可以将image_count保存到数据库字段中，如果有的话
                        faceDetectLog.setFaceCount(imageCount);
                    }
                    
                    // 记录其他usage信息
                    log.info("使用情况: {}", usage.toString());
                }
            } else {
                // HTTP状态码不是200，直接标记为失败
                faceDetectLog.setSuccess(false);
            }
            
            // 保存到数据库
            boolean saved = saveFaceDetectLog(faceDetectLog);
            if (saved) {
                log.info("图像检测日志已保存，请求ID: {}", requestId);
            } else {
                log.error("保存图像检测日志失败，请求ID: {}", requestId);
            }
            
            return faceDetectLog;
            
        } catch (HttpClientErrorException e) {
            return handleError(faceDetectLog, e, "客户端错误 (4xx): " + e.getStatusCode(), startTime);
        } catch (HttpServerErrorException e) {
            return handleError(faceDetectLog, e, "服务器错误 (5xx): " + e.getStatusCode(), startTime);
        } catch (Exception e) {
            return handleError(faceDetectLog, e, "图像检测请求失败: " + e.getMessage(), startTime);
        }
    }
    
    /**
     * 处理错误并保存到数据库
     */
    private FaceDetectLog handleError(FaceDetectLog faceDetectLog, Exception e, String errorMessage, long startTime) {
        long endTime = System.currentTimeMillis();
        long processingTime = endTime - startTime;
        
        faceDetectLog.setResponseTime(LocalDateTime.now());
        faceDetectLog.setSuccess(false);
        faceDetectLog.setProcessingTimeMs(processingTime);
        faceDetectLog.setErrorMessage(errorMessage);
        
        if (e instanceof HttpClientErrorException) {
            faceDetectLog.setStatusCode(((HttpClientErrorException) e).getStatusCode().value());
            faceDetectLog.setResponseData(((HttpClientErrorException) e).getResponseBodyAsString());
        } else if (e instanceof HttpServerErrorException) {
            faceDetectLog.setStatusCode(((HttpServerErrorException) e).getStatusCode().value());
            faceDetectLog.setResponseData(((HttpServerErrorException) e).getResponseBodyAsString());
        }
        
        log.error("图像检测失败: {}", errorMessage);
        log.error("错误详情: {}", e.getMessage());
        
        // 保存错误日志到数据库
        try {
            saveFaceDetectLog(faceDetectLog);
            log.info("错误日志已保存，请求ID: {}", faceDetectLog.getRequestId());
        } catch (Exception saveException) {
            log.error("保存错误日志失败: {}", saveException.getMessage());
        }
        
        return faceDetectLog;
    }
    
    /**
     * 创建错误日志
     */
    private FaceDetectLog createErrorLog(String imageUrl, String errorMessage) {
        return createErrorLog(imageUrl, errorMessage, null, null, null);
    }
    
    /**
     * 创建错误日志（带扩展信息）
     */
    private FaceDetectLog createErrorLog(String imageUrl, String errorMessage, String ownerName, String ownerPhone, String avatarName) {
        FaceDetectLog faceDetectLog = new FaceDetectLog();
        faceDetectLog.setRequestId(UUID.randomUUID().toString());
        faceDetectLog.setModel("liveportrait-detect");
        faceDetectLog.setImageUrl(imageUrl);
        faceDetectLog.setOwnerName(ownerName);
        faceDetectLog.setOwnerPhone(ownerPhone);
        faceDetectLog.setAvatarName(avatarName);
        faceDetectLog.setRequestTime(LocalDateTime.now());
        faceDetectLog.setResponseTime(LocalDateTime.now());
        faceDetectLog.setSuccess(false);
        faceDetectLog.setErrorMessage(errorMessage);
        faceDetectLog.setFaceCount(0);
        
        try {
            saveFaceDetectLog(faceDetectLog);
        } catch (Exception e) {
            log.error("保存错误日志失败: {}", e.getMessage());
        }
        
        return faceDetectLog;
    }
    
    /**
     * 分页查询图像检测日志
     */
    @Override
    public com.baomidou.mybatisplus.extension.plugins.pagination.Page<FaceDetectLog> getPageList(
            Integer current, Integer size, Boolean success, String startTime, String endTime, 
            String ownerName, String ownerPhone, String avatarName) {
        
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<FaceDetectLog> page = 
            new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(current, size);
        
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<FaceDetectLog> queryWrapper = 
            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (success != null) {
            queryWrapper.eq(FaceDetectLog::getSuccess, success);
        }
        if (startTime != null && !startTime.trim().isEmpty()) {
            queryWrapper.ge(FaceDetectLog::getRequestTime, startTime);
        }
        if (endTime != null && !endTime.trim().isEmpty()) {
            queryWrapper.le(FaceDetectLog::getRequestTime, endTime);
        }
        if (ownerName != null && !ownerName.trim().isEmpty()) {
            queryWrapper.like(FaceDetectLog::getOwnerName, ownerName);
        }
        if (ownerPhone != null && !ownerPhone.trim().isEmpty()) {
            queryWrapper.like(FaceDetectLog::getOwnerPhone, ownerPhone);
        }
        if (avatarName != null && !avatarName.trim().isEmpty()) {
            queryWrapper.like(FaceDetectLog::getAvatarName, avatarName);
        }
        
        // 按请求时间倒序排列
        queryWrapper.orderByDesc(FaceDetectLog::getRequestTime);
        
        return page(page, queryWrapper);
    }
    
    /**
     * 获取统计信息
     */
    @Override
    public Map<String, Object> getStatistics(String startTime, String endTime) {
        Map<String, Object> statistics = new HashMap<>();
        
        // 构建查询条件
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<FaceDetectLog> queryWrapper = 
            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
        
        // 时间范围筛选
        if (startTime != null && !startTime.trim().isEmpty()) {
            queryWrapper.ge(FaceDetectLog::getRequestTime, startTime);
        }
        if (endTime != null && !endTime.trim().isEmpty()) {
            queryWrapper.le(FaceDetectLog::getRequestTime, endTime);
        }
        
        // 查询总数
        long totalCount = count(queryWrapper);
        
        // 查询成功数
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<FaceDetectLog> successWrapper = 
            new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
        
        // 时间范围筛选
        if (startTime != null && !startTime.trim().isEmpty()) {
            successWrapper.ge(FaceDetectLog::getRequestTime, startTime);
        }
        if (endTime != null && !endTime.trim().isEmpty()) {
            successWrapper.le(FaceDetectLog::getRequestTime, endTime);
        }
        successWrapper.eq(FaceDetectLog::getSuccess, true);
        long successCount = count(successWrapper);
        
        // 查询失败数
        long failureCount = totalCount - successCount;
        
        // 计算成功率
        double successRate = totalCount > 0 ? (double) successCount / totalCount * 100 : 0;
        
        // 查询平均处理时间
        java.util.List<FaceDetectLog> logs = list(queryWrapper);
        double avgProcessingTime = logs.stream()
            .filter(log -> log.getProcessingTimeMs() != null)
            .mapToLong(FaceDetectLog::getProcessingTimeMs)
            .average()
            .orElse(0.0);
        
        // 查询总图像数量
        int totalFaceCount = logs.stream()
            .filter(log -> log.getFaceCount() != null)
            .mapToInt(FaceDetectLog::getFaceCount)
            .sum();
        
        // 构建统计结果
        statistics.put("totalCount", totalCount);
        statistics.put("successCount", successCount);
        statistics.put("failureCount", failureCount);
        statistics.put("successRate", Math.round(successRate * 100.0) / 100.0);
        statistics.put("avgProcessingTimeMs", Math.round(avgProcessingTime));
        statistics.put("totalFaceCount", totalFaceCount);
        
        log.info("统计信息查询完成，总数: {}, 成功数: {}, 失败数: {}, 成功率: {}%", 
            totalCount, successCount, failureCount, successRate);
        
        return statistics;
    }
}