package com.docus.server.service.impl;

import cn.hutool.core.util.StrUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.web.exception.ApiException;
import com.docus.infrastructure.web.exception.ExceptionCode;
import com.docus.server.service.IFileUploadService;
import com.docus.server.vo.scheduling.management.schcollectorversionfile.UploadFileVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class FileUploadServiceImpl implements IFileUploadService {

    @Value("${file.uploadFolder:D://docus/}")
    private String saveFilePath;

    private static final String COLLECTOR_PACKAGES = "collector_packages";

    private static DateTimeFormatter ymdDtf = DateTimeFormatter.ofPattern("yyyyMMdd");

    @Override
    public List<UploadFileVO> uploadFile(MultipartFile[] multipartFiles, String pathKey) throws Exception {

        if (Func.isBlank(pathKey)) {
            pathKey = COLLECTOR_PACKAGES;
        }

        List<UploadFileVO> uploadFileVOList = new ArrayList<>();

        for (MultipartFile multipartFile : multipartFiles) {

            valid(multipartFile);

            uploadFileVOList.add(actionUploadFile(multipartFile, pathKey));
        }
        return uploadFileVOList;

    }

    private UploadFileVO actionUploadFile(MultipartFile multipartFile, String pathKey) throws Exception {

        String todayFormat = ymdDtf.format(LocalDateTime.now());

        String path = pathKey + "/" + todayFormat + "/" + UUID.randomUUID().toString() + "/";
        File fileDir = new File(saveFilePath + path);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        String fileName = path + multipartFile.getOriginalFilename();

        File dest = new File(saveFilePath + fileName);

        multipartFile.transferTo(dest);


        UploadFileVO uploadFileVO = new UploadFileVO();
        uploadFileVO.setFileName(multipartFile.getOriginalFilename());
        uploadFileVO.setFileSize(multipartFile.getSize());
        uploadFileVO.setFileTitle(multipartFile.getName());
        uploadFileVO.setFileType(multipartFile.getContentType());
        uploadFileVO.setFilePath(fileName);

        return uploadFileVO;
    }

    @Override
    public void downloadFile(String path, HttpServletResponse response) {

        try {
            //获取要下载的文件
            File file = new File(saveFilePath + "/" + path);

            //设置响应的内容类型为二进制流，即文件类型
            response.setContentType("application/octet-stream");

            //设置文件名
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));

            //创建输入流
            FileInputStream inputStream = new FileInputStream(file);
            BufferedInputStream buffInputStream = new BufferedInputStream(inputStream);

            //创建输出流
            ServletOutputStream outputStream = response.getOutputStream();
            BufferedOutputStream buffOutputStream = new BufferedOutputStream(outputStream);

            //循环读取数据并写入到响应输出流中
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = buffInputStream.read(buffer)) != -1) {
                buffOutputStream.write(buffer, 0, len);
            }

            //关闭流
            buffOutputStream.flush();
            buffOutputStream.close();
            outputStream.flush();
            outputStream.close();
            buffInputStream.close();
            inputStream.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    private void valid(MultipartFile multipartFile) {
        if (multipartFile.isEmpty()) {
            throw new ApiException(ExceptionCode.ParamIllegal.getCode(), "上传失败，请选择文件！");
        }

        String originalFilename = multipartFile.getOriginalFilename();
        if (StrUtil.isBlank(originalFilename)) {
            throw new ApiException(ExceptionCode.ParamIllegal.getCode(), "未找到原文件文件名！");
        }
        if (!originalFilename.contains(".")) {
            throw new ApiException(ExceptionCode.ParamIllegal.getCode(), "原文件名未识别到后缀！");
        }
    }

}
