package com.ruoyi.ibs.dashboard.controller;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.OSSObject;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.ibs.dashboard.service.FileOptService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * @Author 吴凯程
 * @Date 2025/5/19
 **/
@Slf4j
@Api(tags = "文件上传下载")
@RestController
@RequestMapping("/file/opt")
public class FileOptController {

    @Resource
    private FileOptService fileOptService;


    /**
     * 通用上传请求（单个）
     */
    @Anonymous
    @ApiOperation("通用上传请求")
    @PostMapping("/upload")
    public AjaxResult uploadFile(MultipartFile file) throws Exception
    {
        try
        {
            return AjaxResult.success(fileOptService.saveFile(file));
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }


    /**
     * 本地资源通用下载
     */
    @Anonymous
    @ApiOperation("本地资源通用下载")
    @GetMapping("/download")
    public void fileDownload(String filePath, HttpServletResponse response)
            throws Exception
    {
        try
        {
            // 下载名称
            String downloadName = StringUtils.substringAfterLast(filePath, '/');
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
//            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, downloadName);
            FileUtils.writeBytes(filePath, response.getOutputStream());
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }

    @Anonymous
    @ApiOperation("OSS下載")
    @GetMapping("/ossDownload")
    public void  ossDownload(String endpoint,String accessKeyId, String accessKeySecret, String bucketName, String objectKey, HttpServletResponse response) throws Exception {



        OSS ossClient = null;
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            // 创建 OSSClient 实例
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 验证文件是否存在
            boolean doesObjectExist = ossClient.doesObjectExist(bucketName, objectKey);
            if (!doesObjectExist) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "文件不存在");
                return;
            }

            // 获取 OSS 对象
            OSSObject ossObject = ossClient.getObject(bucketName, objectKey);

            // 设置响应头
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");

            // 设置文件名编码，解决中文乱码问题
            String fileName = objectKey.substring(objectKey.lastIndexOf("/") + 1);
            String encodedFileName = URLEncoder.encode(fileName, String.valueOf(StandardCharsets.UTF_8)).replace("+", "%20");
            response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + encodedFileName);

            // 获取输入输出流
            bis = new BufferedInputStream(ossObject.getObjectContent());
            os = response.getOutputStream();

            // 缓冲区大小（8KB）
            byte[] buffer = new byte[8192];
            int bytesRead;

            // 输出到响应流
            while ((bytesRead = bis.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.flush();

        } catch (IOException e) {
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "下载文件时发生IO错误");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } catch (Exception e) {
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "下载文件时发生错误");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            // 关闭资源
            try {
                if (bis != null) bis.close();
                if (os != null) os.close();
                if (ossClient != null) ossClient.shutdown();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
