package com.backendsys.controller.Upload;

import com.backendsys.utils.CommonUtil;
import com.backendsys.utils.response.Result;
import com.backendsys.utils.response.ResultEnum;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 上传 (本地)
 */
@RestController
public class UploadLocalController {

    @Value("${file.upload.directory}") // 配置保存文件的目录
    private String uploadDirectory;

    @Value("${file.upload.url-prefix}") // 指定文件访问的 URL前缀
    private String uploadUrlPrefix;

    @Value("${file.upload.max-size}")
    private long maxSize;

    @PreAuthorize("@sr.hasPermission(1)")
    @PostMapping("/api/upload")
    public Result uploadLocal(@RequestParam("file") MultipartFile file) {

        // 检查上传的文件是否为空
        if (file.isEmpty()) {
            return Result.error(ResultEnum.INTERNAL_ERROR.getCode(), "文件不能为空");
        }
        // 判断文件大小是否超过
        if (file.getSize() > maxSize) {
            return Result.error(ResultEnum.INTERNAL_ERROR.getCode(), "文件不能超过 " + maxSize/1024/1024 + " MB，请使用大文件上传功能");
        }

        try {
            // 创建保存文件的目录，如果不存在
            File directory = new File(uploadDirectory);
            if (!directory.exists()) { directory.mkdirs(); }

            // 获取文件原始名
            String originalFileName = file.getOriginalFilename();

            // 生成后缀名
            String suffix = originalFileName.substring(originalFileName.lastIndexOf("."));

            // 生成新的文件名
            String newFileName = CommonUtil.generateFilename(suffix);
            String newFileNameThumb = newFileName.replaceAll(suffix, "-thumb" + suffix);

            // 按日期作为文件目录
            String pathDir = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String dateDir = pathDir + File.separator;

            File dateDirectory = new File(uploadDirectory + dateDir);
            if (!dateDirectory.exists()) { dateDirectory.mkdirs(); }

//            System.out.println("uploadDirectory = " + uploadDirectory);
//            System.out.println("dateDir = " + dateDir);
//            System.out.println("newFileName = " + newFileName);

            // 确定文件保存的路径
            String sourceFilePath = uploadDirectory + dateDir + newFileName;
            String sourceFilePathThumb = uploadDirectory + dateDir + newFileNameThumb;

            System.out.println(sourceFilePath);
            System.out.println(sourceFilePathThumb);

            File sourceFile = new File(sourceFilePath);
//            File sourceFileThumb = new File(sourceFilePathThumb);

            // 保存文件到本地
            file.transferTo(sourceFile);


            // 创建缩略图
            // .scale(0.5)  // 缩放
            // .outputFormat("png") // 类型
            // .sourceRegion(Positions.TOP_RIGHT, 1800, 1800) // 裁剪
            // .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("watermark.png")), 0.5f)  // 添加水印
            // .outputQuality(0.2) // 质量
            // 文件批量操作
            // Thumbnails.of(new File("/images/202401/").listFiles()).size(400, 400).toFiles(Rename.PREFIX_DOT_THUMBNAIL);
            Thumbnails.of(sourceFilePath).size(200, 200).toFile(sourceFilePathThumb);


            // 返回文件的路径 (绝对路径)
            String fileUrl = uploadUrlPrefix + pathDir + "/" + newFileName;
            String fileThumbUrl = uploadUrlPrefix + pathDir + "/" + newFileNameThumb;

            Map<String, Object> map = new LinkedHashMap<>();
            map.put("filename", newFileName);
            map.put("url", fileUrl);
            map.put("url_thumb", fileThumbUrl);
            map.put("type", suffix.replace(".", ""));
            map.put("size", sourceFile.length());

            // 返回响应
            return Result.success(map);

        } catch (IOException e) {
            e.printStackTrace();
            return Result.error(ResultEnum.INTERNAL_ERROR.getCode(), "上传失败");
        }
    }

}
