package com.bonus.file.controller;

import cn.hutool.core.util.ObjectUtil;
import com.bonus.common.core.constant.HttpStatus;
import com.bonus.common.core.utils.Base64Utils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.file.service.ISysFileService;
import com.bonus.system.api.domain.SysFile;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
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 javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;

/**
 * 文件请求处理
 *
 * @author bonus
 */
@RestController
@Api("服务文件存储")
public class SysFileController
{
    private static final Logger log = LoggerFactory.getLogger(SysFileController.class);

    private final ISysFileService sysFileService;

    @Autowired
    public SysFileController(ISysFileService fileService) {
        this.sysFileService = fileService;
    }

    /**
     * 单文件上传
     * @param file 单个文件
     * @return 文件信息，包括文件名和文件路径
     */
    @PostMapping("upload")
    @ApiOperation("上传本地文件到服务器")
    public AjaxResult upload(MultipartFile file)
    {
        try
        {
            // 上传并返回访问地址
            if (ObjectUtil.isEmpty(file)) { return AjaxResult.error("上传文件不能为空");}
            SysFile sysFile = sysFileService.uploadFile(file);
            return AjaxResult.success(sysFile);
        }
        catch (Exception e)
        {
            log.error("上传文件失败", e);
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 多文件上传
     * @param files 多个文件流
     * @return 文件信息
     */
    @PostMapping("/uploadFiles")
    public AjaxResult uploadFile(MultipartFile[] files) {
        try {
            if (ObjectUtil.isEmpty(files)) { return AjaxResult.error("上传文件不能为空");}
            return AjaxResult.success(sysFileService.uploadFiles(files));
        } catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 文件下载
     * @param response 请求响应
     * @param objectKey，除mongodb 存fileid之外，其他均存上传文件的网络路径
     */
    @GetMapping("/download")
    public void downloadFile(HttpServletResponse response, @RequestParam String objectKey) throws IOException {
        try {
         String fileUrl = Base64Utils.decodeUrl(URLDecoder.decode(objectKey));
         sysFileService.downloadFile(response, fileUrl);
        } catch (Exception e) {
            log.error("downloadFile error:{}", e.getMessage());
            response.setStatus(HttpStatus.ERROR);
            // 设置响应的 Content-Type 为文本
            response.setContentType("application/json;charset=UTF-8");
            // 将错误信息写入响应体
            PrintWriter writer = response.getWriter();
            writer.write("{\"error\": \"File download failed: " + e.getMessage() + "\"}");
            writer.flush();
            writer.close();
        }
    }

    @GetMapping("/getFullFileUrl")
    public String getFullFileUrl(@RequestParam String fileUrl) throws Exception {
        return sysFileService.getFullFileUrl(fileUrl);
    }

    /**
     * 文件删除
     * 从各个存储平台删除文件
     * @param objectKey * @param objectKey，除mongodb 存fileid之外，其他均存上传文件的网络路径
     */
    @PostMapping("/deleteFile")
    public AjaxResult deleteFile(@RequestParam("objectKey") String objectKey)  {
        try {
            String fileUrl = Base64Utils.decodeUrl(URLDecoder.decode(objectKey));
            sysFileService.deleteFile(fileUrl);
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
        return AjaxResult.success("删除文件成功");
    }

    /**
     * 单文件上传到指定文件夹
     * @param file 单个文件
     * @return 文件信息，包括文件名和文件路径
     */
    @PostMapping("uploadToFolder")
    @ApiOperation("上传本地文件到服务器")
    public AjaxResult upload(MultipartFile file, String folderName)
    {
        return AjaxResult.success("单文件上传成功");

    }

    /**
     * 创建文件夹
     * @param folderPath 文件夹路径（例如 "folder1/subfolder/"）
     * @return 文件夹网络路径
     */
    @PostMapping("/createFolder")
    @ApiOperation("创建文件夹")
    public AjaxResult createFolder(@RequestParam("folderName") String folderPath)
    {
        sysFileService.createFolder(folderPath);
        return AjaxResult.success("创建文件夹");
    }

    /**
     * list 指定目录下所有文件信息（文件名，文件大小，上传时间，是否目录），包括子文件夹
     * @param folderPath 要获取文件夹和文件的父文件夹路径（例如 "folder1/"）
     * @return 文件夹网络路径
     */
    @GetMapping("/listFiles")
    public AjaxResult listFiles(@RequestParam("folderName")  String folderPath) {
        return AjaxResult.success(sysFileService.getFilesAndSubfolders(folderPath));
    }


    /**
     * 文件夹删除
     * 从各个存储平台删除文件
     * @param folderPath 文件夹路径（例如 "folder1/subfolder/"）
     * @return 文件夹网络路径
     */
    @PostMapping("/deleteFolder")
    public AjaxResult deleteFolder(@RequestParam("folderName") String folderPath)  {
        sysFileService.deleteFolder(folderPath);
        return AjaxResult.success("文件夹删除成功");
    }

}