package com.inkasso.factoring.file.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.inkasso.adapter.exception.BusinessException;
import com.inkasso.adapter.util.CodeUtil;
import com.inkasso.factoring.common.dict.impl.FileModuleDict;
import com.inkasso.factoring.common.util.DateUtil;
import com.inkasso.factoring.file.dao.FileStorageMapper;
import com.inkasso.factoring.file.entity.FileStorage;
import com.inkasso.factoring.file.service.FileStorageService;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


@Service
public class FileStorageServiceImpl extends ServiceImpl<FileStorageMapper, FileStorage> implements FileStorageService {


    @Override
    public void renameFileStorageList(List<FileStorage> fileStorageList) {
        //根据文件原名进行去重
        Map<String, Integer> nameCounts = new HashMap<>();
        for (FileStorage file : fileStorageList) {
            nameCounts.put(file.getOriginalName(), nameCounts.getOrDefault(file.getOriginalName(), 0) + 1);
        }
        Set<String> duplicates = new HashSet<>();
        for (Map.Entry<String, Integer> entry : nameCounts.entrySet()) {
            if (entry.getValue() > 1) {
                duplicates.add(entry.getKey());
            }
        }
        Map<String, Integer> renameCounts = new HashMap<>();
        for (int i = 0; i < fileStorageList.size(); i++) {
            FileStorage fileStorage = fileStorageList.get(i);
            if (duplicates.contains(fileStorage.getOriginalName())) {
                int count = renameCounts.getOrDefault(fileStorage.getOriginalName(), 0) + 1;
                int index = fileStorage.getOriginalName().lastIndexOf(".");
                String newName = fileStorage.getOriginalName().substring(0, index) + DateUtil.dateToString(new Date(), "yyyyMMdd") + "-" + count + fileStorage.getFileType();
                renameCounts.put(fileStorage.getOriginalName(), count);
                fileStorage.setOriginalName(newName);
                fileStorageList.set(i, fileStorage);
            }
        }
    }


    @Override
    public void downloadZipFile(List<FileStorage> fileStorageList, String name, HttpServletResponse response) {
        downloadZip(fileStorageList, name, response);
    }


    /**
     * 打包zip文件
     *
     * @param fileStorageList 文件
     * @param name            文件名称
     */
    public void downloadZip(List<FileStorage> fileStorageList, String name, HttpServletResponse response) {
        try {
            name = URLEncoder.encode(name, "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + name + ".zip");
            response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
            OutputStream out = response.getOutputStream();

            FileInputStream zipSource = null;
            BufferedInputStream bufferStream = null;
            // 构造最终压缩包的输出流
            ZipOutputStream zipStream = new ZipOutputStream(out);
            for (FileStorage fileStorage : fileStorageList) {
                String path = fileStorage.getAbsolutePath();
                File file = new File(path);
                // 将需要压缩的文件格式化为输入流
                zipSource = new FileInputStream(file);
                // 压缩条目不是具体独立的文件，而是压缩包文件列表中的列表项，称为条目，就像索引一样
                ZipEntry zipEntry = new ZipEntry(fileStorage.getOriginalName());
                // 定位该压缩条目位置，开始写入文件到压缩包中
                zipStream.putNextEntry(zipEntry);
                // 输入缓冲流
                bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
                int read = 0;
                // 创建读写缓冲区
                byte[] buf = new byte[1024 * 10];
                while ((read = bufferStream.read(buf, 0, 1024 * 10)) != -1) {
                    zipStream.write(buf, 0, read);
                }
                zipStream.flush();
            }
            zipStream.close();
            out.flush();
            out.close();

        } catch (UnsupportedEncodingException e1) {
            throw new BusinessException(CodeUtil.FAIL, "下载附件转码失败：" + e1.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
        }

//    File zipFile = new File("");
//    if (!zipFile.getParentFile().exists()) {
//      zipFile.getParentFile().mkdirs();
//    }
//    ZipOutputStream zipStream = null;
//
//    try {
//
//
//    } catch (Exception e) {
//      e.printStackTrace();
//    } finally {
//      // 关闭流
//      try {
//        if (null != bufferStream) {
//          bufferStream.close();
//        }
//        if (null != zipStream) {
//          zipStream.close();
//        }
//        if (null != zipSource) {
//          zipSource.close();
//        }
//      } catch (IOException e) {
//        e.printStackTrace();
//      }
//    }
//    return zipFile;
    }


    /**
     * 下载文件夹
     *
     * @param res
     * @param file
     */
    public void doDownloadZip(HttpServletResponse res, File file) {
        try {
            if (file.exists()) {
                String fileName = file.getName();
                fileName = new String(fileName.getBytes("UTF-8"));
                String basePath = file.getAbsolutePath();
                InputStream in = new FileInputStream(new File(basePath));
                fileName = URLEncoder.encode(fileName, "UTF-8");
//                res.setHeader("content-disposition", "attachment;filename=" + fileName);
//                res.setHeader("Content-Type", "application/vnd.ms-exce");
                res.setHeader("Content-Disposition", "attachment;filename=" + fileName);
                res.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
                OutputStream out = res.getOutputStream();
                byte[] b = new byte[1024];
                int len = -1;
                while ((len = in.read(b)) != -1) {
                    out.write(b, 0, len);
                    out.flush();
                }
                // 关闭
                in.close();
                out.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


//  public static String getAbsolutePath(String fileName, String suffix, FileModuleDict.ChildEnum moduleType) {
//    return getAbsoluteDir() + getFilePath(fileName, suffix, moduleType);
//  }
//
//  /**
//   * 获取资源绝对存储目录
//   */
//  public static String getAbsoluteDir() {
//    if (StringUtil.isEmpty(ABSOLUTE_PATH)) {
//      File file = new File(DISK);
//      if (!file.exists()) {
//        file.mkdirs();
//      }
//      ABSOLUTE_PATH = file.getAbsolutePath();
//    }
//    return ABSOLUTE_PATH;
//  }

}
