package com.hotent.util;


import com.hotent.baseInfo.vo.FileUploadResult;
import com.hotent.config.EipConfig;
import com.hotent.constant.BaseConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.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.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;


@Slf4j
public class FileUploadUtil {


    // 允许上传的文件类型
    private static final Set<String> ALLOWED_EXTENSIONS = new HashSet<>(Arrays.asList(
            // 文档格式
            "doc", "docx", "xls", "xlsx", "ppt", "pptx", "pdf", "txt",
            // 图片格式
            "jpg", "jpeg", "png", "gif", "bmp", "webp",
            // 压缩包格式
            "zip", "rar", "7z",
            // 其他常用格式
            "csv", "xml", "json"
    ));

    // 文件大小限制 (单位: 字节，默认100MB)
    private static long MAX_FILE_SIZE = 100 * 1024 * 1024;

    /**
     * 单文件上传
     * @param file 上传的文件
     * @param businessFolder 业务文件夹名称
     * @param baseUploadPath 基础上传路径
     * @return 文件上传结果
     */
    public static FileUploadResult uploadFile(MultipartFile file, String baseUploadPath) {
        return uploadFiles(Collections.singletonList(file), baseUploadPath).get(0);
    }

    /**
     * 多文件上传
     * @param files 上传的文件列表
     * @param  业务文件夹名称
     * @param baseUploadPath 基础上传路径
     * @return 文件上传结果列表
     */
    public static List<FileUploadResult> uploadFiles(List<MultipartFile> files, String baseUploadPath) {
        List<FileUploadResult> results = new ArrayList<>();

        for (MultipartFile file : files) {
            FileUploadResult result = new FileUploadResult();
            result.setOriginalFilename(file.getOriginalFilename());

            try {
                // 验证文件
                validateFile(file);

                // 生成文件保存路径
                String fileExtension = getFileExtension(file.getOriginalFilename());
                String fileName = generateFileName(file.getOriginalFilename());
                String savePath = generateSavePath(baseUploadPath, fileName, fileExtension);

                // 创建目录
                createDirectories(savePath);
                log.info(savePath);

                // 保存文件
                File destFile = new File(savePath);
                file.transferTo(destFile);

                // 设置成功结果
                result.setFileName(fileName);
                result.setFileExtension(fileExtension);
                result.setSavePath(getPathFileName(savePath,fileName));
                result.setFileSize(file.getSize());
                result.setMessage("上传成功");

            } catch (Exception e) {
                result.setMessage("上传失败: " + e.getMessage());
            }

            results.add(result);
        }

        return results;
    }


    public static final String getPathFileName(String uploadDir, String fileName)
    {
        int dirLastIndex = EipConfig.getProfile().length() + 1;
        String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
        return BaseConstant.RESOURCE_PREFIX + "/" + currentDir;
    }

    /**
     * 验证文件合法性
     * @param file 文件
     * @throws Exception 验证异常
     */
    private static void validateFile(MultipartFile file) throws Exception {
        // 检查文件是否为空
        if (file.isEmpty()) {
            throw new Exception("文件为空");
        }

        // 检查文件大小
        if (file.getSize() > MAX_FILE_SIZE) {
            throw new Exception("文件大小超过限制(" + MAX_FILE_SIZE / (1024 * 1024) + "MB)");
        }

        // 检查文件类型
        String extension = getFileExtension(file.getOriginalFilename());
        if (!ALLOWED_EXTENSIONS.contains(extension.toLowerCase())) {
            throw new Exception("不支持的文件类型: " + extension);
        }
    }

    public static String getFileType(String fileName)
    {
        int separatorIndex = fileName.lastIndexOf(".");
        if (separatorIndex < 0)
        {
            return "";
        }
        return fileName.substring(separatorIndex + 1).toLowerCase();
    }

    public static boolean checkAllowDownload(String resource)
    {
        // 禁止目录上跳级别
        if (StringUtils.contains(resource, ".."))
        {
            return false;
        }

        if (ALLOWED_EXTENSIONS.contains(resource)) {
            return true;
        }

        // 不在允许下载的文件规则
        return false;
    }

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

    /**
     * 生成文件名（避免重名）
     * @param originalFilename 原始文件名
     * @return 新文件名
     */
    public static String generateFileName(String originalFilename) {
        String extension = "";
        String name = originalFilename;

        if (originalFilename != null && originalFilename.lastIndexOf(".") != -1) {
            extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            name = originalFilename.substring(0, originalFilename.lastIndexOf("."));
        }

        // 使用时间戳+随机数避免重名
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String random = String.valueOf(new Random().nextInt(1000));
        return name + "_" + timestamp + "_" + random + extension;
    }

    /**
     * 生成文件保存路径
     * @param baseUploadPath 基础上传路径
     * @param  业务文件夹
     * @param fileName 文件名
     * @param fileExtension 文件扩展名
     * @return 完整保存路径
     */
    public static String generateSavePath(String baseUploadPath, String fileName, String fileExtension) {
        // 标准化路径分隔符
        String separator ="/";

        // 构建路径
        StringBuilder pathBuilder = new StringBuilder();
        pathBuilder.append(normalizePath(baseUploadPath)).append(separator);

        // 添加业务文件夹
//        if (businessFolder != null && !businessFolder.trim().isEmpty()) {
//            pathBuilder.append(normalizePath(businessFolder)).append(separator);
//        }

        // 添加日期文件夹（按年月日分类）
        String datePath = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        pathBuilder.append(datePath).append(separator);

        // 添加文件名
        pathBuilder.append(fileName);

        return pathBuilder.toString();
    }

    /**
     * 标准化路径（处理跨平台路径分隔符）
     * @param path 路径
     * @return 标准化后的路径
     */
    private static String normalizePath(String path) {
        if (path == null) {
            return null;
        }
        // 将所有反斜杠替换为正斜杠，然后根据系统转换
        return path.replace("\\", "/").replace("/", File.separator);
    }

    /**
     * 创建目录（支持跨平台）
     * @param filePath 文件路径
     * @throws IOException IO异常
     */
    private static void createDirectories(String filePath) throws IOException {
        Path path = Paths.get(filePath);
        Path parentDir = path.getParent();
        if (parentDir != null && !Files.exists(parentDir)) {
            Files.createDirectories(parentDir);
        }
    }

    /**
     * 设置允许的文件扩展名
     * @param extensions 扩展名列表
     */
    public static void setAllowedExtensions(Set<String> extensions) {
        ALLOWED_EXTENSIONS.clear();
        ALLOWED_EXTENSIONS.addAll(extensions);
    }

    /**
     * 设置最大文件大小
     * @param maxSize 最大大小（字节）
     */
    public static void setMaxFileSize(long maxSize) {
        MAX_FILE_SIZE = maxSize;
    }


}
