package com.test.musichouduan.service.impl;

import com.test.musichouduan.dto.Result;
import com.test.musichouduan.exception.BusinessException;
import com.test.musichouduan.service.FileService;
import com.mpatric.mp3agic.Mp3File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 文件服务实现类
 */
@Service
public class FileServiceImpl implements FileService {

    private static final Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);

    @Value("${file.upload-path}")
    private String uploadPath;

    @Value("${file.access-path}")
    private String accessPath;

    @Value("${file.allowed-types}")
    private String allowedTypes;

    @Override
    public String uploadImage(MultipartFile file) {
        // 检查文件是否为空
        if (file.isEmpty()) {
            throw new BusinessException("上传文件不能为空");
        }

        // 检查文件类型
        String originalFilename = file.getOriginalFilename();
        String extension = getFileExtension(originalFilename);
        List<String> imageTypes = Arrays.asList("jpg", "jpeg", "png", "gif");
        if (!imageTypes.contains(extension.toLowerCase())) {
            throw new BusinessException("只能上传jpg、jpeg、png、gif格式的图片");
        }

        // 上传文件
        return uploadFile(file, "images");
    }

    @Override
    public String uploadMusic(MultipartFile file) {
        // 检查文件是否为空
        if (file.isEmpty()) {
            throw new BusinessException("上传文件不能为空");
        }

        // 检查文件类型
        String originalFilename = file.getOriginalFilename();
        String extension = getFileExtension(originalFilename);
        List<String> musicTypes = Arrays.asList("mp3", "wav");
        if (!musicTypes.contains(extension.toLowerCase())) {
            throw new BusinessException("只能上传mp3、wav格式的音乐");
        }

        // 上传文件并返回物理路径
        return uploadFile(file, "musics");
    }

    @Override
    public int getMusicDuration(File musicFile) {
        if (musicFile == null || !musicFile.exists()) {
            return 0;
        }
        try {
            Mp3File mp3file = new Mp3File(musicFile);
            return (int) mp3file.getLengthInSeconds();
        } catch (Exception e) {
            logger.error("获取音乐 '{}' 时长失败 (使用 mp3agic)", musicFile.getName(), e);
            return 0;
        }
    }

    @Override
    public String uploadLyric(MultipartFile file) {
        // 检查文件是否为空
        if (file.isEmpty()) {
            throw new BusinessException("上传文件不能为空");
        }

        // 检查文件类型
        String originalFilename = file.getOriginalFilename();
        String extension = getFileExtension(originalFilename);
        List<String> lyricTypes = Arrays.asList("lrc", "txt");
        if (!lyricTypes.contains(extension.toLowerCase())) {
            throw new BusinessException("只能上传lrc、txt格式的歌词");
        }

        try {
            // 读取文件内容
            byte[] bytes = file.getBytes();
            String content = new String(bytes, StandardCharsets.UTF_8);
            return content;
        } catch (IOException e) {
            logger.error("读取歌词文件失败", e);
            throw new BusinessException("读取歌词文件失败");
        }
    }

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

        try {
            // 如果是完整URL，则只提取路径部分
            String filePath = url;
            if (url.startsWith("http")) {
                // 找到访问路径在URL中的位置
                int accessPathIndex = url.indexOf(accessPath);
                if (accessPathIndex != -1) {
                    filePath = url.substring(accessPathIndex);
                }
            } else {
                // 如果不是完整URL，确保使用正确的访问路径
                filePath = url.replace(accessPath, "");
            }

            // 确保filePath以accessPath开头
            if (!filePath.startsWith(accessPath)) {
                filePath = accessPath + filePath;
            }

            // 从URL中提取文件路径部分（去掉访问路径前缀）
            String fileRelativePath = filePath.replace(accessPath, "");
            Path path = Paths.get(uploadPath, fileRelativePath);

            // 删除文件
            return Files.deleteIfExists(path);
        } catch (Exception e) {
            logger.error("删除文件失败: " + url, e);
            return false;
        }
//
//        // 从URL中提取文件路径
//        String filePath = url.replace(accessPath, "");
//        Path path = Paths.get(uploadPath, filePath);
//
//        try {
//            // 删除文件
//            return Files.deleteIfExists(path);
//        } catch (IOException e) {
//            logger.error("删除文件失败", e);
//            return false;
//        }
    }

    /**
     * 上传文件
     *
     * @param file 文件
     * @param directory 目录
     * @return 文件URL
     */
    private String uploadFile(MultipartFile file, String directory) {
        // 生成文件名
        String originalFilename = file.getOriginalFilename();
        String extension = getFileExtension(originalFilename);
        String fileName = UUID.randomUUID().toString() + "." + extension;

        File root   = new File(uploadPath);  // /uploads
        File bizDir = new File(root, directory);                        // /uploads/bizType
        if (!bizDir.exists()) {
            boolean ok = bizDir.mkdirs();                             // 递归创建
            if (!ok) {
                // 抛出异常而不是返回Result
                throw new BusinessException("无法创建目录: " + bizDir.getAbsolutePath());
            }
        }

        File targetFile = new File(bizDir, fileName);

        // 保存文件
        try {
            file.transferTo(targetFile);
            // 返回文件的绝对物理路径
            return targetFile.getAbsolutePath();
        } catch (IOException e) {
            logger.error("上传文件失败", e);
            throw new BusinessException("上传文件失败");
        }
    }

    /**
     * 获取文件扩展名
     *
     * @param fileName 文件名
     * @return 扩展名
     */
    private String getFileExtension(String fileName) {
        if (fileName == null) {
            return "";
        }
        int dotIndex = fileName.lastIndexOf(".");
        if (dotIndex == -1) {
            return "";
        }
        return fileName.substring(dotIndex + 1);
    }
}
