package com.rj.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rj.dto.VideoSynthesisRequestDto;
import com.rj.entity.VideoSynthesisLog;
import com.rj.mapper.VideoSynthesisLogMapper;
import com.rj.service.IVideoSynthesisService;
import com.rj.utils.MinIOUrlGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 视频合成服务实现类
 * 
 * @author rj
 * @date 2025-01-02
 */
@Slf4j
@Service
public class VideoSynthesisServiceImpl implements IVideoSynthesisService {

    @Autowired
    private VideoSynthesisLogMapper videoSynthesisLogMapper;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    MinIOUrlGenerator minIOUrlGenerator ;

    @Value("${dashscope.api.key}")
    private String apiKey;

    private static final String API_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis/";

    @Override
    public VideoSynthesisLog synthesizeVideoAndSave(VideoSynthesisRequestDto request) {
        LocalDateTime startTime = LocalDateTime.now();
        String requestId = UUID.randomUUID().toString();
        
        VideoSynthesisLog synthesisLog = new VideoSynthesisLog();
        synthesisLog.setRequestId(requestId);
        synthesisLog.setRequestTime(startTime);
        synthesisLog.setSuccess(false);

        // 使用BeanUtils复制相同名称的属性
        BeanUtils.copyProperties(request, synthesisLog);
        
        // 设置视频名称（如果请求中有提供）
        if (request.getVideoName() != null && !request.getVideoName().trim().isEmpty()) {
            synthesisLog.setVideoName(request.getVideoName());
            log.info("设置视频名称: {}", request.getVideoName());
        } else {
            // 如果没有提供视频名称，使用默认名称
            synthesisLog.setVideoName("视频合成_" + requestId.substring(0, 8));
            log.info("使用默认视频名称: {}", synthesisLog.getVideoName());
        }

        // 设置图像区域坐标（如果请求中有提供）
        if (request.getFaceBbox() != null && !request.getFaceBbox().trim().isEmpty()) {
            synthesisLog.setFaceBbox(request.getFaceBbox());
            log.info("设置图像区域坐标: {}", request.getFaceBbox());
        }

        // 设置动态区域坐标（如果请求中有提供）
        if (request.getExtBbox() != null && !request.getExtBbox().trim().isEmpty()) {
            synthesisLog.setExtBbox(request.getExtBbox());
            log.info("设置动态区域坐标: {}", request.getExtBbox());

        }


        try {
            log.info("开始视频合成，请求ID: {}, 图片URL: {}, 音频URL: {}", 
                    requestId, request.getImageUrl(), request.getAudioUrl());

            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("X-DashScope-Async", "enable");
            headers.set("Authorization", "Bearer " + apiKey);
            request.buildParam();
            // 构建请求体
            HttpEntity<VideoSynthesisRequestDto> entity = new HttpEntity<>(request, headers);
            log.info("开始视频合成，entity : {} ",entity);
            // 发送请求
            ResponseEntity<String> response = restTemplate.postForEntity(API_URL, entity, String.class);
            
            LocalDateTime endTime = LocalDateTime.now();
            synthesisLog.setResponseTime(endTime);
            synthesisLog.setProcessingTimeMs(java.time.Duration.between(startTime, endTime).toMillis());

            // 解析响应
            if (response.getStatusCode() == HttpStatus.OK) {
                // 直接解析JSON响应
                String responseBody = response.getBody();
                log.info("API响应: {}", responseBody);
                
                // 解析JSON响应
                if (responseBody != null && !responseBody.trim().isEmpty()) {
                    try {
                        // 使用fastjson解析JSON响应
                        JSONObject responseJson = JSON.parseObject(responseBody);
                        

                        // 提取task_id
                        if (responseJson.containsKey("output")) {
                            JSONObject output = responseJson.getJSONObject("output");
                            if (output != null && output.containsKey("task_id")) {
                                String taskId = output.getString("task_id");
                                synthesisLog.setTaskId(taskId);
                                log.info("提取到任务ID: {}", taskId);
                            }
                        }
                        // 设置基本状态
                        synthesisLog.setTaskStatus("PENDING");
                        synthesisLog.setSuccess(true);
                        
                        // 生成临时访问URL（7天有效期）
                        try {
                            log.info("即将用音频名称: {}， 生成临时访问URL", synthesisLog.getVideoName());
                            String tempUrl = generateTempVideoUrl(synthesisLog.getVideoName(), requestId);
                            synthesisLog.setVideoTempUrl(tempUrl);
                            log.info("生成临时访问URL: {}", tempUrl);
                        } catch (Exception e) {
                            log.warn("生成临时访问URL失败: {}", e.getMessage());
                            // 临时URL生成失败不影响主流程
                        }
                        
                    } catch (Exception e) {
                        log.error("解析API响应JSON失败: {}", e.getMessage(), e);
                        synthesisLog.setErrorMessage("解析API响应失败: " + e.getMessage());
                        synthesisLog.setSuccess(false);
                    }
                } else {
                    synthesisLog.setErrorMessage("API响应为空");
                    synthesisLog.setSuccess(false);
                }

                log.info("视频合成请求成功，任务ID: {}, 状态: {}", 
                        synthesisLog.getTaskId(), synthesisLog.getTaskStatus());
            } else {
                synthesisLog.setErrorMessage("HTTP请求失败，状态码: " + response.getStatusCode());
                log.error("视频合成请求失败，状态码: {}, 响应: {}", response.getStatusCode(), response.getBody());
            }

        } catch (Exception e) {
            LocalDateTime endTime = LocalDateTime.now();
            synthesisLog.setResponseTime(endTime);
            synthesisLog.setProcessingTimeMs(java.time.Duration.between(startTime, endTime).toMillis());
            synthesisLog.setErrorMessage("视频合成异常: " + e.getMessage());
            log.error("视频合成失败: {}", e.getMessage(), e);
        }

        // 保存日志
        saveVideoSynthesisLog(synthesisLog);
        return synthesisLog;
    }

    @Override
    public boolean saveVideoSynthesisLog(VideoSynthesisLog synthesisLog) {
        try {
            synthesisLog.setCreatedAt(LocalDateTime.now());
            synthesisLog.setUpdatedAt(LocalDateTime.now());
            
            int result = videoSynthesisLogMapper.insert(synthesisLog);
            log.info("视频合成日志保存{}: 请求ID={}, 任务ID={}, 成功={}", 
                    result > 0 ? "成功" : "失败", synthesisLog.getRequestId(), synthesisLog.getTaskId(), synthesisLog.getSuccess());
            return result > 0;
        } catch (Exception e) {
            log.error("保存视频合成日志失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public VideoSynthesisLog getVideoSynthesisLogByRequestId(String requestId) {
        try {
            return videoSynthesisLogMapper.selectOne(
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<VideoSynthesisLog>()
                    .eq("request_id", requestId)
            );
        } catch (Exception e) {
            log.error("根据请求ID查询视频合成日志失败: {}", e.getMessage(), e);
            return null;
        }
    }

    @Override
    public VideoSynthesisLog getVideoSynthesisLogByTaskId(String taskId) {
        try {
            return videoSynthesisLogMapper.selectOne(
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<VideoSynthesisLog>()
                    .eq("task_id", taskId)
            );
        } catch (Exception e) {
            log.error("根据任务ID查询视频合成日志失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 生成临时视频访问URL
     * 
     * @param videoName 视频名称
     * @param requestId 请求ID
     * @return 临时访问URL
     */
    private String generateTempVideoUrl(String videoName, String requestId) {
        try {

            return   minIOUrlGenerator.generateTempUrl(videoName, 7, TimeUnit.DAYS).getUrl();
            
        } catch (Exception e) {
            log.error("生成临时视频URL失败: {}", e.getMessage(), e);
            return null;
        }
    }
}
