package com.test.bijihoudaun.controller;


import com.test.bijihoudaun.common.response.R;
import com.test.bijihoudaun.entity.Image;
import com.test.bijihoudaun.service.ImageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

@Tag(name = "markdown接口")
@RestController
@RequestMapping("/api/images")
public class ImageController {

    @Value("${file.upload-dir}")
    private String rootPath;

    @Autowired
    private ImageService imageService;

    @Operation(summary = "上传图片")
    @PostMapping
    public R<Image> uploadImage(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "userId", required = false) Long userId,
            @RequestParam(value = "markdownId", required = false) Long markdownId) {

        try {
            Image image = imageService.uploadImage(file, userId, markdownId);
            return R.success(image);
        } catch (IOException e) {
            return R.fail();
        }
    }

    @Operation(summary = "根据id删除图片")
    @PostMapping("/{id}")
    public R<Void> deleteImage(@PathVariable Long id) {
        boolean result = imageService.deleteImage(id);
        if (result) {
            return R.success();
        } else {
            return R.fail();
        }
    }

    /**
     * 在线预览（图片、视频、音频、pdf 等浏览器可直接识别的类型）
     */
    @GetMapping("/preview/{url}")
    @Operation(summary = "在线预览", description = "浏览器直接打开文件流")
    public void preview(@PathVariable String url, HttpServletResponse resp) throws IOException {
        if (url == null) {
            resp.setStatus(404);
            R.fail("文件不存在");
        }
        File file = new File(rootPath + File.separator + url);
        if (!file.exists()) {
            resp.setStatus(404);
            R.fail("文件不存在");
        }
        String contentTypeFromFileExtension = getContentTypeFromFileExtension(url);
        // 设置正确的 MIME
        resp.setContentType(contentTypeFromFileExtension);
        // 设置文件长度，支持断点续传
        resp.setContentLengthLong(file.length());
        // 写出文件流
        try (FileInputStream in = new FileInputStream(file)) {
            StreamUtils.copy(in, resp.getOutputStream());
        }
    }


    @Operation(summary = "根据url删除图片")
    @PostMapping("/deleteByUrl")
    public R<Void> deleteImageByUrl(@RequestParam String url) {
        boolean result = imageService.deleteImageByUrl(url);
        if (result) {
            return R.success();
        } else {
            return R.fail();
        }
    }

    @Operation(summary = "根据url批量删除图片")
    @PostMapping("/batch")
    public R<Void> deleteImageByUrls(@RequestBody List<String> urls) {
        boolean result = imageService.deleteImageByUrls(urls);
        if (result) {
            return R.success();
        } else {
            return R.fail();
        }
    }


    /**
     * 根据文件扩展名获取内容类型
     * @param fileName 文件名
     * @return 对应的MIME类型
     */
    private String getContentTypeFromFileExtension(String fileName) {
        if (fileName == null || fileName.lastIndexOf('.') == -1) {
            return "application/octet-stream";
        }

        String extension = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
        switch (extension) {
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            case "png":
                return "image/png";
            case "gif":
                return "image/gif";
            case "bmp":
                return "image/bmp";
            case "webp":
                return "image/webp";
            case "svg":
                return "image/svg+xml";
            default:
                return "application/octet-stream";
        }
    }

}
