package cn.com.poc.common.utils;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author Roger Wu
 */
public class FileUtils {

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

    /**
     * 格式化文件大小
     */
    public static String formatFileSize(long bytes) {
        if (bytes < 1024) {
            return bytes + " B";
        } else if (bytes < 1024 * 1024) {
            return String.format("%.2f KB", bytes / 1024.0);
        } else if (bytes < 1024 * 1024 * 1024) {
            return String.format("%.2f MB", bytes / (1024.0 * 1024));
        } else {
            return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
        }
    }

    public static File multipartFileToFile(MultipartFile multiFile) {

        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        // 获取文件后缀
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        // 随机文件名
        fileName = fileName + RandomCodeUtils.generateString(8) + DateUtils.formatDate(new Date(), DateUtils.DATESTYLE);
        try {
            File file = File.createTempFile(fileName, prefix);
            org.apache.commons.io.FileUtils.writeByteArrayToFile(file, multiFile.getBytes());
            return file;
        } catch (IOException e) {
            throw new RuntimeException("multipart file convert to file error：" + e.getMessage());
        }
    }

    /**
     * 将字节流转换成文件
     *
     * @param data
     * @throws Exception
     */
    public static File createTempFile(byte[] data, String fileSuffix) throws IOException {
        if (data != null) {
            File file = File.createTempFile(UUID.randomUUID().toString(), fileSuffix);
            if (file.exists()) {
                file.delete();
            }
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data, 0, data.length);
            fos.flush();
            fos.close();
            return file;
        }
        return null;
    }

    /**
     * 判断文件是否为压缩文件
     *
     * @param file 文件
     * @return 是否为压缩文件
     */
    public static boolean isCompressedFile(File file) {
        String fileName = file.getName().toLowerCase();
        return isCompressedFile(fileName);
    }

    /**
     * 判断文件是否为压缩文件
     *
     * @param fileName 文件名
     * @return 是否为压缩文件
     */
    public static boolean isCompressedFile(String fileName) {
        fileName = fileName.toLowerCase();
        return fileName.endsWith(".zip") || fileName.endsWith(".tar") ||
                fileName.endsWith(".tar.gz") || fileName.endsWith(".tgz") ||
                fileName.endsWith(".rar") || fileName.endsWith(".7z");
    }


    /**
     * 解压文件
     *
     * @param gzipFile
     * @return
     * @throws IOException
     */
    public static List<File> unGzip(File gzipFile) throws IOException {
        // 目标解压目录
        String destDir = Files.createTempDirectory("gzip/temp/").toString();
        // 确保目标目录存在
        FileUtil.mkdir(destDir);
        File[] extractedFiles = ZipUtil.unzip(gzipFile, new File(destDir)).listFiles();
        return ListUtil.toList(extractedFiles);
    }

    /**
     * 验证并清理文件名，防止路径遍历攻击
     */
    public static String sanitizeFileName(String fileName) {
        if (fileName == null) {
            return "unknown";
        }
        // 移除路径分隔符，防止路径遍历
        fileName = fileName.replace("../", "").replace("..\\", "").replace("..", "");
        // 只保留文件名部分
        int lastSeparatorIndex = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
        if (lastSeparatorIndex >= 0) {
            fileName = fileName.substring(lastSeparatorIndex + 1);
        }
        return fileName.isEmpty() ? "unknown" : fileName;
    }
}
