package com.zjsgfa.project.zjsgfa.util;


import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;



public class FileToMultipartFileConverter {
    /**
     * 将 File 转换为 MultipartFile（生产环境专用，JDK 1.8 兼容）
     * @param file 待转换的 File 对象（非空、存在且为文件）
     * @return 实现了 MultipartFile 接口的自定义对象
     * @throws IllegalArgumentException 文件无效时抛出
     * @throws IOException 文件读取异常时抛出
     */
    public static MultipartFile convert(File file) throws IOException {
        // 1. 严格校验文件有效性
        if (file == null) {
            throw new IllegalArgumentException("待转换文件不能为null");
        }
        if (!file.exists()) {
            throw new IllegalArgumentException("文件不存在：" + file.getAbsolutePath());
        }
        if (!file.isFile()) {
            throw new IllegalArgumentException("不是有效文件：" + file.getAbsolutePath());
        }

        // 2. 返回自定义 MultipartFile 实现
        return new CustomMultipartFile(file);
    }

    /**
     * 自定义 MultipartFile 实现类（核心，JDK 1.8 兼容）
     * 完全实现 MultipartFile 接口，无外部依赖
     */
    static class CustomMultipartFile implements MultipartFile {
        private final File file;
        private final String originalFilename;
        private final String contentType;

        /**
         * 构造方法：初始化文件信息
         * @param file 原始 File 对象
         */
        public CustomMultipartFile(File file) {
            this.file = file;
            this.originalFilename = file.getName();
            this.contentType = getContentTypeByFileName(file.getName());
        }

        /**
         * 获取表单字段名（可根据业务自定义，默认返回 "file"）
         */
        @Override
        public String getName() {
            return "file";
        }

        /**
         * 获取文件原始名称（如 test.xlsx）
         */
        @Override
        public String getOriginalFilename() {
            return originalFilename;
        }

        /**
         * 获取文件 MIME 类型（关键：保证文件解析兼容性）
         */
        @Override
        public String getContentType() {
            return contentType;
        }

        /**
         * 判断文件是否为空
         */
        @Override
        public boolean isEmpty() {
            return file.length() == 0;
        }

        /**
         * 获取文件大小（字节）
         */
        @Override
        public long getSize() {
            return file.length();
        }

        /**
         * 获取文件字节数组（适用于小文件）
         */
        @Override
        public byte[] getBytes() throws IOException {
            try (FileInputStream fis = new FileInputStream(file)) {
                byte[] bytes = new byte[(int) file.length()];
                int readLen = fis.read(bytes);
                // 校验读取的字节数是否完整
                if (readLen != file.length()) {
                    throw new IOException("文件读取不完整，预期读取" + file.length() + "字节，实际读取" + readLen + "字节");
                }
                return bytes;
            }
        }

        /**
         * 获取文件输入流（推荐：大文件优先使用流操作）
         */
        @Override
        public InputStream getInputStream() throws IOException {
            return new FileInputStream(file);
        }

        /**
         * 文件转存方法（核心：实现文件保存逻辑）
         * @param dest 目标文件
         */
        @Override
        public void transferTo(File dest) throws IOException, IllegalStateException {
            // 校验目标文件
            if (dest == null) {
                throw new IllegalArgumentException("目标文件不能为null");
            }
            // 如果目标文件已存在，先删除（避免覆盖异常）
            if (dest.exists() && !dest.delete()) {
                throw new IOException("无法删除已存在的目标文件：" + dest.getAbsolutePath());
            }
            // 确保目标文件目录存在
            File parentDir = dest.getParentFile();
            if (!parentDir.exists() && !parentDir.mkdirs()) {
                throw new IOException("无法创建目标文件目录：" + parentDir.getAbsolutePath());
            }
            // 流拷贝文件（高效、低内存占用）
            try (InputStream in = new FileInputStream(file);
                 OutputStream out = new FileOutputStream(dest)) {
                byte[] buffer = new byte[8192]; // 8K 缓冲区，平衡性能和内存
                int len;
                while ((len = in.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
                out.flush();
            }
        }

        /**
         * 根据文件名后缀获取 MIME 类型（JDK 1.8 兼容：替换 switch 表达式为 if-else）
         * @param fileName 文件名
         * @return MIME 类型字符串
         */
        private String getContentTypeByFileName(String fileName) {
            if (fileName == null || fileName.lastIndexOf(".") == -1) {
                return "application/octet-stream"; // 默认二进制流
            }
            String suffix = fileName.toLowerCase().substring(fileName.lastIndexOf("."));

            // JDK 1.8 支持的 if-else 分支（替换 switch 表达式）
            if (".xlsx".equals(suffix) || ".xls".equals(suffix)) {
                return "application/vnd.ms-excel";
            } else if (".jpg".equals(suffix) || ".jpeg".equals(suffix)) {
                return "image/jpeg";
            } else if (".png".equals(suffix)) {
                return "image/png";
            } else if (".pdf".equals(suffix)) {
                return "application/pdf";
            } else if (".doc".equals(suffix) || ".docx".equals(suffix)) {
                return "application/msword";
            } else if (".txt".equals(suffix)) {
                return "text/plain";
            } else if (".zip".equals(suffix)) {
                return "application/zip";
            } else if (".json".equals(suffix)) {
                return "application/json";
            } else {
                return "application/octet-stream";
            }
        }
    }

    // ------------------- 测试示例（JDK 1.8 验证） -------------------
    public static void main(String[] args) {
        try {
            // 替换为你的测试文件路径
            File testFile = new File("D:\\qianhe\\file\\钻井施工智能优选\\滨648-斜69岩性数据.xlsx");
            // 转换 File 为 MultipartFile
            MultipartFile multipartFile = FileToMultipartFileConverter.convert(testFile);

            // 验证转换结果
            System.out.println("转换成功！");
            System.out.println("文件名：" + multipartFile.getOriginalFilename());
            System.out.println("文件类型：" + multipartFile.getContentType());
            System.out.println("文件大小：" + multipartFile.getSize() + " 字节");
            System.out.println("文件是否为空：" + multipartFile.isEmpty());

            // 测试文件转存（可选）
            File destFile = new File("D:\\test_copy.xlsx");
            multipartFile.transferTo(destFile);
            System.out.println("文件转存成功：" + destFile.getAbsolutePath());

        } catch (Exception e) {
            System.err.println("转换失败：" + e.getMessage());
            e.printStackTrace();
        }
    }


}
