package com.rj.service.impl;

import com.rj.entity.AudioManagement;
import com.rj.service.IFileUploadService;
import com.rj.service.IAudioManagementService;
import com.rj.service.MinIOService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 文件上传服务实现类
 * 
 * @author 李中华 ,spllzh
 * @since 2025-08-07
 */
@Slf4j
@Service
public class FileUploadServiceImpl implements IFileUploadService {

    @Autowired
    private IAudioManagementService audioManagementService;

    @Autowired
    private MinIOService minIOService;

    @Value("${app.audio.upload.path:uploads/audio}")
    private String uploadPath;

    @Value("${app.audio.access.url:/api/audio/}")
    private String accessUrl;

    @Value("${app.audio.max.size:10MB}")
    private String maxFileSize;

    // 支持的音频格式
    private static final String[] SUPPORTED_AUDIO_FORMATS = {
        "mp3", "wav", "m4a", "aac", "ogg", "flac", "wma"
    };

    @Override
    public Map<String, Object> uploadAudioFile(MultipartFile file, String audioId) throws IOException {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 验证文件
            if (file == null || file.isEmpty()) {
                result.put("success", false);
                result.put("message", "文件不能为空");
                return result;
            }

            // 验证文件大小
            long maxSize = parseFileSize(maxFileSize);
            if (file.getSize() > maxSize) {
                result.put("success", false);
                result.put("message", "文件大小超过限制，最大允许 " + maxFileSize);
                return result;
            }

            // 验证文件格式
            String originalFilename = file.getOriginalFilename();
            if (!isValidAudioFormat(originalFilename)) {
                result.put("success", false);
                result.put("message", "不支持的音频格式，支持的格式：" + String.join(", ", SUPPORTED_AUDIO_FORMATS));
                return result;
            }

            // 直接上传到MinIO，不保存到本地
            log.info("开始上传文件到MinIO...");
            String fileUrl = minIOService.uploadFile(file);
            log.info("文件上传成功，URL: {}", fileUrl);

            // 获取录音记录并更新
            AudioManagement audio = audioManagementService.getById(audioId);
            if (audio != null) {
                // 更新录音记录的文件信息
                String fileExtension = getFileExtension(originalFilename);
                
                audio.setAudioFileUrl(fileUrl);
                audio.setAudioFileSize(file.getSize());
                audio.setAudioFileOriginalName(originalFilename);
                audio.setAudioFileExtension(fileExtension);
                audio.setUploadTime(java.time.LocalDateTime.now());
                audio.setUpdateTime(java.time.LocalDateTime.now());
                
                // 保存更新
                audioManagementService.updateById(audio);
                
                log.info("录音记录更新成功：audioId={}", audioId);
            } else {
                log.warn("未找到对应的录音记录：audioId={}", audioId);
            }

            result.put("success", true);
            result.put("message", "文件上传成功");
            result.put("fileUrl", fileUrl);
            result.put("fileSize", file.getSize());
            result.put("originalName", originalFilename);

            log.info("音频文件上传成功：audioId={}, minioUrl={}, size={}", audioId, fileUrl, file.getSize());

        } catch (Exception e) {
            log.error("音频文件上传失败：audioId={}, error={}", audioId, e.getMessage(), e);
            result.put("success", false);
            result.put("message", "文件上传失败：" + e.getMessage());
        }

        return result;
    }

    @Override
    public Map<String, Object> uploadAudioFileAndUpdateRecord(MultipartFile file, String audioId) throws IOException {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 先上传文件
            Map<String, Object> uploadResult = uploadAudioFile(file, audioId);
            
            if (!(Boolean) uploadResult.get("success")) {
                return uploadResult;
            }

            // 获取录音记录
            AudioManagement audio = audioManagementService.getById(audioId);
            if (audio == null) {
                result.put("success", false);
                result.put("message", "录音记录不存在");
                return result;
            }

            // 更新录音记录的文件信息
            String fileName = (String) uploadResult.get("fileName");
            String fileUrl = (String) uploadResult.get("fileUrl");
            Long fileSize = (Long) uploadResult.get("fileSize");
            String originalName = (String) uploadResult.get("originalName");
            String fileExtension = getFileExtension(originalName);

            audio.setAudioFilePath(uploadPath + "/" + fileName);
            audio.setAudioFileUrl(fileUrl);
            audio.setAudioFileSize(fileSize);
            audio.setAudioFileOriginalName(originalName);
            audio.setAudioFileExtension(fileExtension);
            audio.setUploadTime(java.time.LocalDateTime.now());
            audio.setUpdateTime(java.time.LocalDateTime.now());

            // 保存更新
            boolean updated = audioManagementService.updateById(audio);
            
            if (updated) {
                result.put("success", true);
                result.put("message", "音频文件上传成功并更新录音记录");
                result.put("data", uploadResult);
                result.put("audioRecord", audio);
                
                log.info("音频文件上传并更新录音记录成功：audioId={}, fileName={}", audioId, fileName);
            } else {
                result.put("success", false);
                result.put("message", "文件上传成功但更新录音记录失败");
                result.put("data", uploadResult);
            }

        } catch (Exception e) {
            log.error("音频文件上传并更新录音记录失败：audioId={}, error={}", audioId, e.getMessage(), e);
            result.put("success", false);
            result.put("message", "文件上传并更新录音记录失败：" + e.getMessage());
        }

        return result;
    }

    @Override
    public String getAudioFileUrl(String audioId) {
        if (StringUtils.isEmpty(audioId)) {
            return null;
        }

        Path uploadDir = Paths.get(uploadPath);
        File dir = uploadDir.toFile();
        
        if (!dir.exists() || !dir.isDirectory()) {
            return null;
        }

        // 查找对应的音频文件
        File[] files = dir.listFiles((d, name) -> name.startsWith(audioId + "."));
        if (files != null && files.length > 0) {
            String fileName = files[0].getName();
            return accessUrl + fileName;
        }

        return null;
    }

    @Override
    public boolean deleteAudioFile(String audioId) {
        if (StringUtils.isEmpty(audioId)) {
            return false;
        }

        try {
            Path uploadDir = Paths.get(uploadPath);
            File dir = uploadDir.toFile();
            
            if (!dir.exists() || !dir.isDirectory()) {
                return false;
            }

            // 查找对应的音频文件
            File[] files = dir.listFiles((d, name) -> name.startsWith(audioId + "."));
            if (files != null && files.length > 0) {
                boolean deleted = files[0].delete();
                if (deleted) {
                    log.info("音频文件删除成功：audioId={}, fileName={}", audioId, files[0].getName());
                }
                return deleted;
            }

            return false;
        } catch (Exception e) {
            log.error("音频文件删除失败：audioId={}, error={}", audioId, e.getMessage(), e);
            return false;
        }
    }

    @Override
    public boolean audioFileExists(String audioId) {
        if (StringUtils.isEmpty(audioId)) {
            return false;
        }

        Path uploadDir = Paths.get(uploadPath);
        File dir = uploadDir.toFile();
        
        if (!dir.exists() || !dir.isDirectory()) {
            return false;
        }

        File[] files = dir.listFiles((d, name) -> name.startsWith(audioId + "."));
        return files != null && files.length > 0;
    }

    @Override
    public Map<String, Object> uploadAudioFileToMinIO(MultipartFile file, String audioId) throws IOException {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 验证文件
            if (file == null || file.isEmpty()) {
                result.put("success", false);
                result.put("message", "文件不能为空");
                return result;
            }

            // 验证文件大小
            long maxSize = parseFileSize(maxFileSize);
            if (file.getSize() > maxSize) {
                result.put("success", false);
                result.put("message", "文件大小超过限制，最大允许 " + maxFileSize);
                return result;
            }

            // 验证文件格式
            String originalFilename = file.getOriginalFilename();
            if (!isValidAudioFormat(originalFilename)) {
                result.put("success", false);
                result.put("message", "不支持的音频格式，支持的格式：" + String.join(", ", SUPPORTED_AUDIO_FORMATS));
                return result;
            }

            // 使用MinIO上传文件
            String minioUrl = minIOService.uploadFile(file);
            
            result.put("success", true);
            result.put("message", "文件上传到MinIO成功");
            result.put("fileUrl", minioUrl);
            result.put("fileSize", file.getSize());
            result.put("originalName", originalFilename);
            result.put("audioId", audioId);

            log.info("音频文件上传到MinIO成功：audioId={}, minioUrl={}, size={}", audioId, minioUrl, file.getSize());

        } catch (Exception e) {
            log.error("音频文件上传到MinIO失败：audioId={}, error={}", audioId, e.getMessage(), e);
            result.put("success", false);
            result.put("message", "文件上传到MinIO失败：" + e.getMessage());
        }

        return result;
    }

    /**
     * 验证音频文件格式
     */
    private boolean isValidAudioFormat(String filename) {
        if (StringUtils.isEmpty(filename)) {
            return false;
        }

        String extension = getFileExtension(filename).toLowerCase();
        for (String format : SUPPORTED_AUDIO_FORMATS) {
            if (format.equals(extension)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        if (StringUtils.isEmpty(filename)) {
            return "";
        }
        int lastDotIndex = filename.lastIndexOf('.');
        if (lastDotIndex > 0 && lastDotIndex < filename.length() - 1) {
            return filename.substring(lastDotIndex + 1);
        }
        return "";
    }

    /**
     * 解析文件大小字符串
     */
    private long parseFileSize(String sizeStr) {
        if (StringUtils.isEmpty(sizeStr)) {
            return 100 * 1024 * 1024; // 默认100MB
        }

        sizeStr = sizeStr.trim().toUpperCase();
        long multiplier = 1;

        if (sizeStr.endsWith("KB")) {
            multiplier = 1024;
            sizeStr = sizeStr.substring(0, sizeStr.length() - 2);
        } else if (sizeStr.endsWith("MB")) {
            multiplier = 1024 * 1024;
            sizeStr = sizeStr.substring(0, sizeStr.length() - 2);
        } else if (sizeStr.endsWith("GB")) {
            multiplier = 1024 * 1024 * 1024;
            sizeStr = sizeStr.substring(0, sizeStr.length() - 2);
        }

        try {
            return Long.parseLong(sizeStr) * multiplier;
        } catch (NumberFormatException e) {
            return 100 * 1024 * 1024; // 默认100MB
        }
    }
}
