package modules.upload;

import com.jfinal.aop.Before;
import com.jfinal.kit.StrKit;
import com.jfinal.upload.UploadFile;
import common.interceptor.LoginInterceptor;
import common.interceptor.role.RequiredRoleInterface;
import common.utils.http.MyController;
import common.utils.http.MyRet;
import modules.user.UserController;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

public class UploadController extends MyController {
    // 默认上传文件保存的基路径，可以从配置文件中读取
    private static final String DEFAULT_UPLOAD_BASE_PATH = System.getenv("UPLOAD_BASE_PATH");
    // 默认的URL访问基路径，可以从配置文件中读取
    private static final String DEFAULT_URL_BASE = System.getenv("URL_BASE") + "/uploads";

    /**
     * 上传一个文件的方法
     * 前端通过 multipart/form-data 方式，将文件字段命名为 "file" 上传
     */
    @Before(LoginInterceptor.class)
    @RequiredRoleInterface({UserController.ROLE_SUPER_ADMIN})
    public void uploadOneFile() {
        UploadFile uploadFile = getFile("file");

        if (uploadFile == null) {
            renderJson(MyRet.fail("请上传文件"));
            return;
        }

        File tempFile = uploadFile.getFile(); // 获取 JFinal 上传的临时文件
        // important: uploadFile instance is useful so we don't delete it directly.

        try {
            String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String extension = getFileExtension(uploadFile.getOriginalFileName());
            String uniqueFileName = UUID.randomUUID().toString().replace("-", "") + extension;

            File destDir = new File(DEFAULT_UPLOAD_BASE_PATH, today);
            if (!destDir.exists()) {
                if (!destDir.mkdirs()) {
                    throw new RuntimeException("创建目标目录失败: " + destDir.getAbsolutePath());
                }
            }
            File destFile = new File(destDir, uniqueFileName);

            // --- 核心修改部分 ---
            // 使用 Files.move() 进行移动操作
            // StandardCopyOption.REPLACE_EXISTING: 如果目标文件已存在，则替换掉它
            // StandardCopyOption.ATOMIC_MOVE: 尝试进行原子性移动，如果不支持原子性则回退到非原子性
            Files.move(tempFile.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            // --- 核心修改部分结束 ---

            String accessUrl = DEFAULT_URL_BASE + "/" + today + "/" + uniqueFileName;
            renderJson(MyRet.ok("上传成功").setData(accessUrl));

        } catch (IOException e) { // 捕获 IOException，Files.move 可能会抛出
            // 移动失败，打印详细错误信息
            e.printStackTrace();
            renderJson(MyRet.fail("文件移动失败，请检查服务器日志: " + e.getMessage()));
        } catch (Exception e) { // 其他异常
            e.printStackTrace();
            renderJson(MyRet.fail("上传失败: " + e.getMessage()));
        } finally {
            // 无论成功失败，确保临时文件被删除
            // 如果 Files.move 成功，tempFile 会被删除
            // 如果 Files.move 失败，tempFile 仍然存在，需要手动删除
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();
            }
        }
    }

    /**
     * 获取文件扩展名
     * @param fileName 文件名
     * @return 扩展名，包含"."，例如 ".jpg"
     */
    private String getFileExtension(String fileName) {
        if (StrKit.isBlank(fileName) || fileName.lastIndexOf('.') == -1) {
            return "";
        }
        return fileName.substring(fileName.lastIndexOf('.'));
    }
}
