package com.lesingle.modules.oss.controller;

import com.lesingle.common.result.Result;
import com.lesingle.modules.oss.service.OssService;
import com.lesingle.modules.oss.util.OssUtils;
import com.lesingle.modules.oss.vo.OssTokenVo;
import com.lesingle.security.annotation.Public;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;
import java.util.Set;

@Tag(name = "文件上传")
@RestController
@RequestMapping("/upload")
@RequiredArgsConstructor
public class UploadController {

    private final OssService ossService;
    private final OssUtils ossUtils;

    /** 允许的文件扩展名白名单 */
    private static final Set<String> ALLOWED_EXTENSIONS = Set.of(
            ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".svg",
            ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",
            ".mp3", ".mp4", ".wav", ".avi", ".mov",
            ".zip", ".rar",
            ".txt", ".csv"
    );

    /** 最大文件大小：100MB */
    private static final long MAX_FILE_SIZE = 100 * 1024 * 1024;

    @Operation(summary = "服务端上传文件（向后兼容）")
    @PostMapping
    public Result<Map<String, Object>> upload(@RequestParam("file") MultipartFile file) {
        // 文件大小校验
        if (file.getSize() > MAX_FILE_SIZE) {
            return Result.error(400, "文件过大，最大允许 100MB");
        }

        // 文件类型校验
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || !isAllowedExtension(originalFilename)) {
            return Result.error(400, "不支持的文件类型，允许的类型：" + String.join(", ", ALLOWED_EXTENSIONS));
        }

        String url = ossService.uploadFile(file);
        return Result.success(Map.of(
                "url", url,
                "fileName", originalFilename,
                "size", file.getSize()
        ));
    }

    @Public
    @Operation(summary = "获取 OSS 直传 Token")
    @GetMapping("/oss/token")
    public Result<OssTokenVo> getOssToken(
            @RequestParam("fileName") String fileName,
            @RequestParam(value = "dir", required = false) String dir) {
        OssTokenVo token = ossUtils.generatePostObjectToken(fileName, dir);
        return Result.success(token);
    }

    /**
     * 检查文件扩展名是否在白名单中
     */
    private boolean isAllowedExtension(String filename) {
        int lastDot = filename.lastIndexOf(".");
        if (lastDot == -1) return false;
        String ext = filename.substring(lastDot).toLowerCase();
        return ALLOWED_EXTENSIONS.contains(ext);
    }
}
