package com.bonus.oss.controller;

import com.aliyun.oss.model.OSSObject;
import com.bonus.common.core.domain.R;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.utils.file.FileUtils;
import com.bonus.oss.domain.OssInfo;
import com.bonus.oss.service.OssService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/oss")
public class OssController {
    @Resource
    private OssService ossService;

    /**
     * 文件上传
     *
     * @param file 文件流
     * @return 文件信息
     */
    @PostMapping("/uploadFile")
    public R<OssInfo> uploadFile(MultipartFile file) {
        return ossService.uploadFile(file);
    }


    /**
     * 文件上传
     *
     * @param files 文件流
     * @return 文件信息
     */
    @PostMapping("/uploadFiles")
    public R<List<OssInfo>> uploadFiles(MultipartFile[] files) {
        return ossService.uploadFiles(files);
    }

    /**
     * 文件下载
     *
     * @param objectKey oss文件存储地址
     */
    @GetMapping("/downloadFile")
    public void downloadFile(HttpServletResponse response, @RequestParam String objectKey) throws UnsupportedEncodingException {
        R<OSSObject> ossObjectR = ossService.downloadFile(objectKey);
        if (ossObjectR.getData() == null) {
            response.setStatus(HttpStatus.NOT_FOUND.value());
            return;
        }

        OSSObject ossObject = ossObjectR.getData();
        String safeFileName = FileUtils.getName(objectKey); // 假设这个方法进行了恰当的文件名清理和验证
        if (!StringUtils.hasText(safeFileName)) {
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            return;
        }

        String encodedFileName = URLEncoder.encode(safeFileName, StandardCharsets.UTF_8.toString());
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFileName + "\"");

        try (InputStream inputStream = ossObject.getObjectContent();
             OutputStream outputStream = response.getOutputStream()) {

            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
        } catch (IOException e) {
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        } catch (IllegalArgumentException e) {
            response.setStatus(HttpStatus.BAD_REQUEST.value());
        } catch (Exception e) {
            // 记录异常信息到日志
            log.error("文件下载过程中出现未知异常，原因是：", e);
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }


    /**
     * 文件删除
     *
     * @param objectKey 文件路径
     * @return 删除结果
     */
    @PostMapping("/deleteFile")
    public R<T> deleteFile(@RequestParam String objectKey) {
        return ossService.deleteFile(objectKey);
    }
}
