package com.backendsys.modules.download.controller;

import cn.hutool.core.io.FileTypeUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Arrays;

/**
 * 下载本地文件
 */
@RestController
public class DownloadLocalController {

    @Value("${file.upload.directory}") // 配置保存文件的目录
    private String uploadDirectory;

//    // 判断文件是否为图片文件
//    private boolean isImageFile(File file) {
//        String extension = getExtension(file.getName());
//        return Arrays.asList("jpg", "jpeg", "png", "gif").contains(extension.toLowerCase());
//    }

    // 获取图片文件对应的MediaType
    private MediaType getImageMediaType(File file) {
        String extension = getExtension(file.getName());
        switch (extension.toLowerCase()) {
            case "jpg":
            case "jpeg": return MediaType.IMAGE_JPEG;
            case "png": return MediaType.IMAGE_PNG;
            case "gif": return MediaType.IMAGE_GIF;
            default: return MediaType.APPLICATION_OCTET_STREAM;
        }
    }

    public static String getExtension(String filename) {
        if (filename == null) { return ""; }
        int dotIndex = filename.lastIndexOf(".");
        if (dotIndex > 0 && dotIndex < filename.length() - 1) {
            return filename.substring(dotIndex + 1);
        }
        return "";
    }

    private BufferedImage resizeImage(File file, Integer width, Integer height) throws IOException {
        BufferedImage originalImage = ImageIO.read(file);
        int newWidth = width != null ? width : originalImage.getWidth();
        int newHeight = height != null ? height : originalImage.getHeight();
        BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = resizedImage.createGraphics();
        g.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
        g.dispose();
        return resizedImage;
    }

    private InputStream imageToInputStream(BufferedImage image, String format) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(image, format, os);
        return new ByteArrayInputStream(os.toByteArray());
    }

    /**
     * 静态文件访问地址
     * @param folder
     * @param filename
     * @param width     缩略图宽度 不大于 600
     * @param height    缩略图高度 不大于 600
     */
    @GetMapping("/uploads/{folder}/{filename:.+}")
    public ResponseEntity<Resource> serveFile(
        @PathVariable String folder,
        @PathVariable String filename,
        @RequestParam(value = "w", required = false) Integer width,
        @RequestParam(value = "h", required = false) Integer height
    ) throws IOException {

        Integer MAX_WIDTH = 600;
        Integer MAX_HEIGHT = 600;

        File file = new File(uploadDirectory + folder + "/" + filename);

        if (!file.exists()) {
            String message = "图片不存在";
            InputStream inputStream = new ByteArrayInputStream(message.getBytes(StandardCharsets.UTF_8));
            InputStreamResource resource = new InputStreamResource(inputStream);
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .contentType(MediaType.valueOf("text/plain; charset=UTF-8"))
                .body(resource);
        }

        HttpHeaders headers = new HttpHeaders();

        // 判断文件类型
        // - 如果是图片，则直接显示;
        // - 如果是文件，则是下载
        String mimeType = Files.probeContentType(file.toPath());
        boolean isImage = mimeType != null && mimeType.startsWith("image/");

        System.out.println("isImage = " + isImage);
        if (isImage) {

            // 如果是图片文件，设置Content-Type为对应的图片MIME类型
            headers.setContentType(getImageMediaType(file));

            // 如果请求了图片压缩
            if (width != null || height != null) {
                // 如果入参宽/高超出限制，则仍是返回文件下载
                if ((width != null && width > MAX_WIDTH) || (height != null && height > MAX_HEIGHT)) {
                    // 如果不是图片文件，设置 Content-Disposition 以附件形式下载
                    headers.setContentDisposition(ContentDisposition.attachment().filename(file.getName()).build());
                    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
                } else {
                    // 图片显示
                    BufferedImage resizedImage = resizeImage(file, width, height);
                    // 根据文件类型动态选择图片格式
                    String imageFormat = mimeType.split("/")[1]; // 提取图片格式，如 "png"、"jpeg" 等
                    return ResponseEntity.ok().headers(headers)
                        .contentLength(resizedImage.getWidth() * resizedImage.getHeight() * 3) // 假设是RGB
                        .body(new InputStreamResource(imageToInputStream(resizedImage, imageFormat)));
                }
            }

        } else {
            // 如果不是图片文件，设置 Content-Disposition 以附件形式下载
            headers.setContentDisposition(ContentDisposition.attachment().filename(file.getName()).build());
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        }

        InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
        return ResponseEntity.ok().headers(headers).contentLength(file.length()).body(resource);
    }

}
