package com.xiaoniu.subsystem.file.controller;

import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.xiaoniu.common.core.exception.ServiceException;
import com.xiaoniu.common.core.result.R;
import com.xiaoniu.common.core.utils.StringUtils;
import com.xiaoniu.common.core.utils.file.FileUtils;
import com.xiaoniu.subsystem.file.service.ISysFileService;
import com.xiaoniu.subsystem.system.utils.MysqlDataBackupUtil;
import com.xiaoniu.system.api.domain.SysFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Objects;

/**
 * 文件请求处理
 *
 * @author xiaoniu
 */
@Tag(name = "上传管理")
@RestController
@RequestMapping("/file")
public class SysFileController {
    private static final Logger log = LoggerFactory.getLogger(SysFileController.class);

    /**
     * 上传文件存储在本地的根路径
     */
    @Value("${file.path}")
    private String localFilePath;

    @Autowired
    private ISysFileService sysFileService;



    /**
     * 文件上传请求
     */
    @PostMapping("/upload")
    @ApiOperationSupport(order = 1)
    @Operation(summary = "文件上传请求", description = "传入file")
    public R<SysFile> upload(MultipartFile file) {
        try {
            // 上传并返回访问地址
            String url = sysFileService.uploadFile(convertToDocx(file));
            SysFile sysFile = new SysFile();
            sysFile.setName(FileUtils.getName(url));
            sysFile.setUrl(url);
            return R.data(sysFile);
        } catch (Exception e) {
            log.error("上传文件失败", e);
            return R.fail(e.getMessage());
        }
    }

    @GetMapping("/download")
    @ApiOperationSupport(order = 2)
    @Operation(summary = "文件下载", description = "传入fileUrl")
    public void downloadFile(HttpServletResponse response,
                             @Parameter(description = "文件地址", required = true) @RequestParam String fileUrl) {
        if (StringUtils.isBlank(fileUrl)){
            throw new ServiceException("请传入需要下载的文件地址");
        }
        sysFileService.downloadFile(response, fileUrl);
    }

    /**
     * 批量下载
     */
    @GetMapping("/downloadAndZip")
    @ApiOperationSupport(order = 3)
    @Operation(summary = "批量下载", description = "传入urls")
    public void downloadAndZip(HttpServletResponse response,
                               @Parameter(description = "文件地址集合", required = true) @RequestParam String urls) {
        if (StringUtils.isBlank(urls)){
            throw new ServiceException("请传入需要下载的文件地址");
        }
        sysFileService.downloadAndZip(response, Arrays.stream(urls.split(",")).toList());
    }

    public static MultipartFile convertToDocx(MultipartFile docFile) {
        try {
            // 确保输入的文件类型是DOC
            if (Objects.requireNonNull(docFile.getOriginalFilename()).toLowerCase().endsWith(".doc")) {
                File file = MysqlDataBackupUtil
                        .createFile(MysqlDataBackupUtil.MysqlPath, docFile.getOriginalFilename() + "x");
                Document document = new Document(docFile.getInputStream());
                OutputStream stream = new FileOutputStream(file);
                document.save(stream, SaveFormat.DOCX);
                stream.flush();
                stream.close();
                document.cleanup();
                MockMultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(),
                        "text/plain", new FileInputStream(file));
                MysqlDataBackupUtil
                        .deleteFiles(MysqlDataBackupUtil.MysqlPath + multipartFile.getOriginalFilename());
                return multipartFile;
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
        return docFile;
    }

}