package com.stdproject.utils;

import com.stdproject.common.BusinessException;
import com.stdproject.common.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 文件工具类
 *
 * @author StdProject
 */
@Component
@Slf4j
public class FileUtils {

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

    @Value("${file.upload.max-size:10485760}")
    private long maxFileSize; // 默认10MB

    /**
     * 允许的图片文件类型
     */
    private static final List<String> ALLOWED_IMAGE_TYPES = Arrays.asList(
            "jpg", "jpeg", "png", "gif", "bmp", "webp"
    );

    /**
     * 允许的文档文件类型
     */
    private static final List<String> ALLOWED_DOCUMENT_TYPES = Arrays.asList(
            "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt"
    );

    /**
     * 上传文件
     *
     * @param file 文件
     * @param subDir 子目录
     * @return 文件相对路径
     */
    public String uploadFile(MultipartFile file, String subDir) {
        if (file == null || file.isEmpty()) {
            throw new BusinessException("文件不能为空");
        }

        // 检查文件大小
        if (file.getSize() > maxFileSize) {
            throw new BusinessException( "文件大小不能超过" + (maxFileSize / 1024 / 1024) + "MB");
        }

        // 获取原始文件名和扩展名
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || originalFilename.trim().isEmpty()) {
            throw new BusinessException( "文件名不能为空");
        }

        String extension = getFileExtension(originalFilename);
        if (extension.isEmpty()) {
            throw new BusinessException( "文件必须有扩展名");
        }

        // 检查文件类型
        if (!isAllowedFileType(extension)) {
            throw new BusinessException( "不支持的文件类型: " + extension);
        }

        try {
            // 创建目录结构：uploadPath/subDir/yyyy/MM/dd/
            String dateDir = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
            String fullSubDir = subDir + "/" + dateDir;
            Path uploadDir = Paths.get(uploadPath, fullSubDir);
            
            if (!Files.exists(uploadDir)) {
                Files.createDirectories(uploadDir);
            }

            // 生成新文件名
            String newFileName = UUID.randomUUID().toString().replace("-", "") + "." + extension;
            Path filePath = uploadDir.resolve(newFileName);

            // 保存文件
            file.transferTo(filePath.toFile());

            // 返回相对路径
            return fullSubDir + "/" + newFileName;

        } catch (IOException e) {
            log.error("文件上传失败: {}", e.getMessage(), e);
            throw new BusinessException( "文件上传失败");
        }
    }

    /**
     * 删除文件
     *
     * @param filePath 文件相对路径
     * @return 是否删除成功
     */
    public boolean deleteFile(String filePath) {
        if (filePath == null || filePath.trim().isEmpty()) {
            return false;
        }

        try {
            Path fullPath = Paths.get(uploadPath, filePath);
            return Files.deleteIfExists(fullPath);
        } catch (IOException e) {
            log.error("删除文件失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 获取文件扩展名
     *
     * @param filename 文件名
     * @return 扩展名（小写）
     */
    public String getFileExtension(String filename) {
        if (filename == null || filename.trim().isEmpty()) {
            return "";
        }

        int lastDotIndex = filename.lastIndexOf('.');
        if (lastDotIndex == -1 || lastDotIndex == filename.length() - 1) {
            return "";
        }

        return filename.substring(lastDotIndex + 1).toLowerCase();
    }

    /**
     * 检查是否为允许的文件类型
     *
     * @param extension 文件扩展名
     * @return 是否允许
     */
    public boolean isAllowedFileType(String extension) {
        if (extension == null || extension.trim().isEmpty()) {
            return false;
        }

        String lowerExtension = extension.toLowerCase();
        return ALLOWED_IMAGE_TYPES.contains(lowerExtension) || 
               ALLOWED_DOCUMENT_TYPES.contains(lowerExtension);
    }

    /**
     * 检查是否为图片文件
     *
     * @param extension 文件扩展名
     * @return 是否为图片
     */
    public boolean isImageFile(String extension) {
        if (extension == null || extension.trim().isEmpty()) {
            return false;
        }
        return ALLOWED_IMAGE_TYPES.contains(extension.toLowerCase());
    }

    /**
     * 获取文件完整路径
     *
     * @param relativePath 相对路径
     * @return 完整路径
     */
    public String getFullPath(String relativePath) {
        if (relativePath == null || relativePath.trim().isEmpty()) {
            return "";
        }
        return Paths.get(uploadPath, relativePath).toString();
    }

    /**
     * 检查文件是否存在
     *
     * @param relativePath 相对路径
     * @return 是否存在
     */
    public boolean fileExists(String relativePath) {
        if (relativePath == null || relativePath.trim().isEmpty()) {
            return false;
        }
        return Files.exists(Paths.get(uploadPath, relativePath));
    }

    /**
     * 格式化文件大小
     *
     * @param size 文件大小（字节）
     * @return 格式化后的大小
     */
    public static String formatFileSize(long size) {
        if (size < 1024) {
            return size + " B";
        } else if (size < 1024 * 1024) {
            return String.format("%.1f KB", size / 1024.0);
        } else if (size < 1024 * 1024 * 1024) {
            return String.format("%.1f MB", size / (1024.0 * 1024.0));
        } else {
            return String.format("%.1f GB", size / (1024.0 * 1024.0 * 1024.0));
        }
    }
}