package com.example.util.uploadLocalost;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Iterator;

/**
 * 本地文件
 *
 * @author yangzj
 * @date 2024/6/7 15:54
 */
@Slf4j
@Component
public class FileLocalUtils {

    @Value("${file.path}")
    private String filePath = "D:/";

    @Value("${environment}")
    private String environment = "dev";

    @Value("${fileDomain}")
    private String domain = "127.0.0.1:5555";

    @Autowired
    private MultipartFileToFileLocalUse multipartFileToFileLocalUse;


    /**
     * 上传文件(HttpServletRequest)
     *
     * @param request HttpServletRequest
     * @return 文件对象
     */
    public UploadResultDto uploadFile(HttpServletRequest request) throws Exception {
        UploadResultDto uploadResultDto = new UploadResultDto();
        File file = null;
        try {
            MultipartHttpServletRequest mreq = new StandardServletMultipartResolver().resolveMultipart(request);
            Iterator<String> fileNameIter = mreq.getFileNames();
            while (fileNameIter.hasNext()) {
                MultipartFile multipartFile = mreq.getFile(fileNameIter.next());
                if (multipartFile == null) {
                    throw new Exception("uploadFile: multipartFile == null");
                }
                file = multipartFileToFileLocalUse.multipartFileToFile(multipartFile);
                if (file == null) {
                    throw new Exception("uploadFile: file == null");
                }
                // 原始名字
                String originalName = file.getName();
                uploadResultDto.setOrigin_name(originalName);
                // 判断所要上传的图片是否是图片，图片可以预览，其他文件不提供通过URL预览
//                boolean isImage = ImageIO.read(file) != null;
                log.info("------本地文件上传开始--------" + originalName);
                String suffix = originalName.substring(originalName.lastIndexOf('.'));
                String fileName = IdUtil.fastSimpleUUID() + suffix;
                uploadResultDto.setName(fileName);
//                String date_path = DateUtil.dateToStringByFormat(DateUtil.FORMATTER_DATE_STR, new Date());
                // 设置图片路径和名称(文件服务器地址)
//                String serverPath="insurecore";;
//                //区分环境 配置不同的方位地址 todo
//                if (!isImage) {
//                    //文件
//                    serverPath = "insurecore/file";
//                } else {
//                    //图片
//                    serverPath = "insurecore/image";
//                }
//                if (!isImage) {
//                    //文件
//                    serverPath = "insurecore/file/" + date_path;
//                } else {
//                    //图片
//                    serverPath = "insurecore/image/" + date_path;
//                }
                String fileUrlName = FileConstants.FILE_URL_NAME;
                String serverUrl = fileUrlName + "/" + fileName; // 存储地址
                String fileUrl = filePath + fileUrlName; // 保存文件夹路径
                String url;  // 访问URL
                if ("dev".equals(environment)) {
                    url = getHttpAndPort(request) + "/" + serverUrl;
                } else {
                    url = domain + serverUrl;
                }
                uploadResultDto.setUrl(url);
                uploadResultDto.setServerUrl(serverUrl);
                log.info("------本地服务器文件上传配置路径filePath: {}", filePath);
                log.info("------本地服务器文件上传保存文件夹路径fileUrl: {}", fileUrl);
                log.info("------本地服务器文件上传存储地址serverUrl: {}", serverUrl);
                log.info("------本地服务器文件上传访问URL: {}", url);

                //
                File targetFile = new File(fileUrl);
                FileUtil.mkdir(targetFile);

                File saveFile = new File(targetFile, fileName);
                //可用 未使用
                //localFileToFile.localFileToFile(new FileInputStream(file), filePath + serverUrl);
                //可用  使用中
                multipartFile.transferTo(saveFile);
                log.info("------本地服务器文件上传成功--------" + file.getName());
            }
        } catch (Exception e) {
            log.error("本地服务器文件上传异常", e);
            throw new Exception("本地服务器文件上传异常");
        } finally {
            if (file != null) {
                // 删除保存在本地的临时图片
                file.delete();
            }
        }
        log.info("------本地服务器文件上传成功返回数据--------" + JsonUtil.toStr(uploadResultDto));
        return uploadResultDto;
    }

    /**
     * 上传文件（自定义后缀）
     *
     * @param bytes  文件字节流
     * @param suffix 文件后缀
     * @return 文件对象
     */
    public UploadResultDto uploadFile(byte[] bytes, String suffix) {
        UploadResultDto uploadResultDto = new UploadResultDto();
        try {
            log.info("------本地文件上传开始--------");
            String fileName = IdUtil.fastSimpleUUID() + suffix;
            uploadResultDto.setName(fileName);
            // 设置图片路径和名称(文件服务器地址)
            String fileUrlName = FileConstants.FILE_URL_NAME;
            String serverUrl = fileUrlName + "/" + fileName; // 存储地址
            String fileUrl = filePath + fileUrlName; // 保存文件夹路径
            String url;  // 访问URL
            if ("dev".equals(environment)) {
                url = "http://127.0.0.1:5555" + "/" + serverUrl;
            } else {
                url = domain + serverUrl;
            }

            uploadResultDto.setUrl(url);
            uploadResultDto.setServerUrl(serverUrl);
            log.info("------本地服务器文件上传配置路径filePath: {}", filePath);
            log.info("------本地服务器文件上传保存文件夹路径fileUrl: {}", fileUrl);
            log.info("------本地服务器文件上传存储地址serverUrl: {}", serverUrl);
            log.info("------本地服务器文件上传访问URL: {}", url);
            // 目标文件夹
            File targetFile = new File(fileUrl);
            FileUtil.mkdir(targetFile);

            File saveFile = new File(targetFile, fileName);
            // 将文件流写入文件
            try (FileOutputStream writer = new FileOutputStream(saveFile)) {
                writer.write(bytes);
            }
            log.info("------本地服务器文件上传成功--------" + saveFile.getName());

        } catch (Exception e) {
            log.error("本地服务器文件上传异常", e);
        }
        log.info("------本地服务器文件上传成功返回数据--------" + JsonUtil.toStr(uploadResultDto));
        return uploadResultDto;
    }

    /**
     * 上传pdf文件
     *
     * @param bytes pdf文件字节流
     * @return 文件对象
     */
    public UploadResultDto uploadFilePdf(byte[] bytes) throws Exception {
        return uploadFile(bytes, ".pdf");
    }

    /**
     * 上传图片文件
     *
     * @param bytes 图片文件字节流
     * @return 文件对象
     */
    public UploadResultDto uploadFileImg(byte[] bytes, String suffix) throws Exception {
        return uploadFile(bytes, suffix);
    }

    public static void main(String[] args) {
        //byte[] bytes = FileUtil.readBytes(new File("C:\\Users\\Administrator\\Desktop\\f5857ea3302f45519118a4c7d63e075f-电子保单1692507755377923628.pdf"));
//        byte[] bytes = FileUtil.readBytes(new File("D:\\Desktop\\f5857ea3302f45519118a4c7d63e075f-电子保单1692507755377923628.pdf"));
//        FileLocalUtils fileLocalUtils = new FileLocalUtils();
//        UploadResultDto uploadResultDto = fileLocalUtils.uploadFilePdf(bytes);
//        System.out.println(JSONUtil.toJsonStr(uploadResultDto));
        String name = "1a83e917a04a4848a94daccb68764307-51630CFE-A678-4A14-AAD7-33488A7E3C19.jpeg";
        String suffix = name.substring(name.lastIndexOf('.'));
        System.out.println(suffix);
    }

    /**
     * 获得当前项目访问的地址
     * 例http://127.0.0.1:8080
     *
     * @return 返回当前项目访问的地址
     */
    public static String getHttpAndPort(HttpServletRequest request) {
        return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
    }

}