package com.zksy.web.controller.common;

import com.zksy.common.annotation.Log;
import com.zksy.common.core.domain.AjaxResult;
import com.zksy.common.enums.BusinessType;
import com.zksy.service.MinioFileStorageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * MinIO 文件存储接口
 * 支持上传任意类型文件（图片、文档、视频等）
 *
 * @author zksy
 */
@RestController
@RequestMapping("/minio")
@Api(tags = "MinIO 文件存储接口")
public class MinioController
{
    private static final Logger log = LoggerFactory.getLogger(MinioController.class);

    @Autowired
    private MinioFileStorageService minioFileStorageService;

    @Value("${minio.endpoint}")
    private String readPath;

    @Value("${minio.bucket}")
    private String bucket;

    /**
     * MinIO 单文件上传
     *
     * @param file 文件
     * @param dir  存储目录（可选，默认 upload）
     * @return 上传结果，包含文件访问 URL、文件名等信息
     */
    @PostMapping("/upload")
    @ApiOperation(value = "MinIO 单文件上传", notes = "支持上传任意类型文件，如图片、文档、视频等")
    @Log(title = "MinIO 文件上传", businessType = BusinessType.INSERT)
    public AjaxResult uploadFile(
            @ApiParam(value = "文件", required = true) @RequestParam("file") MultipartFile file,
            @ApiParam(value = "存储目录（可选，默认 upload）") @RequestParam(value = "dir", required = false, defaultValue = "upload") String dir)
    {
        try
        {
            if (file == null || file.isEmpty())
            {
                return AjaxResult.error("上传文件不能为空");
            }

            // 上传文件到 MinIO
            String relativePath = minioFileStorageService.uploadFile(file, dir);
            // 提取存储后的文件名
            String fileName = relativePath.substring(relativePath.lastIndexOf("/") + 1);
            // 构建完整 URL：endpoint/bucket/path/filename
            String fullUrl = buildFullUrl(relativePath);

            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", fullUrl);
            ajax.put("fileName", fileName);
            ajax.put("originalFilename", file.getOriginalFilename());
            ajax.put("contentType", file.getContentType());
            ajax.put("size", file.getSize());
            return ajax;
        }
        catch (Exception e)
        {
            log.error("MinIO 文件上传失败", e);
            return AjaxResult.error("文件上传失败：" + e.getMessage());
        }
    }

    /**
     * MinIO 多文件上传
     *
     * @param files 文件列表
     * @param dir   存储目录（可选，默认 upload）
     * @return 上传结果，包含每个文件的访问 URL、文件名等信息
     */
    @PostMapping("/uploads")
    @ApiOperation(value = "MinIO 多文件上传", notes = "支持批量上传任意类型文件，如图片、文档、视频等")
    @Log(title = "MinIO 多文件上传", businessType = BusinessType.INSERT)
    public AjaxResult uploadFiles(
            @ApiParam(value = "文件列表", required = true) @RequestParam("files") List<MultipartFile> files,
            @ApiParam(value = "存储目录（可选，默认 upload）") @RequestParam(value = "dir", required = false, defaultValue = "upload") String dir)
    {
        try
        {
            if (files == null || files.isEmpty())
            {
                return AjaxResult.error("上传文件不能为空");
            }

            List<Map<String, Object>> fileList = new ArrayList<>();
            for (MultipartFile file : files)
            {
                if (file.isEmpty())
                {
                    continue;
                }

                // 上传文件到 MinIO
                String relativePath = minioFileStorageService.uploadFile(file, dir);
                String fileName = relativePath.substring(relativePath.lastIndexOf("/") + 1);
                // 构建完整 URL
                String fullUrl = buildFullUrl(relativePath);

                Map<String, Object> fileInfo = new HashMap<>();
                fileInfo.put("url", fullUrl);
                fileInfo.put("fileName", fileName);
                fileInfo.put("originalFilename", file.getOriginalFilename());
                fileInfo.put("contentType", file.getContentType());
                fileInfo.put("size", file.getSize());
                fileList.add(fileInfo);
            }

            AjaxResult ajax = AjaxResult.success();
            ajax.put("files", fileList);
            ajax.put("count", fileList.size());
            return ajax;
        }
        catch (Exception e)
        {
            log.error("MinIO 多文件上传失败", e);
            return AjaxResult.error("文件上传失败：" + e.getMessage());
        }
    }

    /**
     * MinIO 文件删除
     *
     * @param filePath 文件路径（上传时返回的 url）
     * @return 删除结果
     */
    @DeleteMapping("/delete")
    @ApiOperation(value = "MinIO 文件删除", notes = "根据文件路径删除 MinIO 中的文件")
    @Log(title = "MinIO 文件删除", businessType = BusinessType.DELETE)
    public AjaxResult deleteFile(
            @ApiParam(value = "文件路径", required = true) @RequestParam("filePath") String filePath)
    {
        try
        {
            if (filePath == null || filePath.isEmpty())
            {
                return AjaxResult.error("文件路径不能为空");
            }

            minioFileStorageService.deleteFile(filePath);
            return AjaxResult.success("删除成功");
        }
        catch (Exception e)
        {
            log.error("MinIO 文件删除失败", e);
            return AjaxResult.error("文件删除失败：" + e.getMessage());
        }
    }

    /**
     * 构建完整的 MinIO 文件访问 URL
     * 
     * @param relativePath 相对路径（如 upload/2026/07/30/file.jpg）
     * @return 完整访问 URL（如 http://192.168.110.30:9000/bucket/upload/2026/07/30/file.jpg）
     */
    private String buildFullUrl(String relativePath) {
        // 确保 readPath 以 / 结尾，relativePath 不以 / 开头
        String baseUrl = readPath.endsWith("/") ? readPath : readPath + "/";
        // 格式：http://endpoint/bucket/path/filename
        if (relativePath.startsWith("/")) {
            relativePath = relativePath.substring(1);
        }
        return baseUrl + bucket + "/" + relativePath;
    }
}
