package com.xiaoniu.subsystem.file.service;

import com.xiaoniu.common.core.exception.ServiceException;
import com.xiaoniu.subsystem.file.utils.FileUploadUtils;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 本地文件存储
 *
 * @author xiaoniu
 */
@Service
public class LocalSysFileServiceImpl implements ISysFileService {
    /**
     * 资源映射路径 前缀
     */
    @Value("${file.prefix}")
    public String localFilePrefix;

    /**
     * 域名或本机访问地址
     */
    @Value("${file.domain}")
    public String domain;

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

    /**
     * 本地文件上传接口
     *
     * @param file 上传的文件
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        String name = FileUploadUtils.upload(localFilePath, file);
        // String url = domain + localFilePrefix + name;
        return localFilePrefix + name;
    }


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

            String name = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
            response.setCharacterEncoding("utf-8");
            response.setHeader("content-type", "application/octet-stream");
            response.setHeader("Content-disposition",
                    "attachment;filename=" + URLEncoder.encode(name, StandardCharsets.UTF_8));
            // new String(name.getBytes("gbk"), "iso8859-1"));
            String file = localFilePath + fileUrl.replaceAll(localFilePrefix, "");
            // 将文件转为文件输入流
            InputStream inStream = new FileInputStream(file);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            // 创建一个Buffer字符串
            byte[] buffer = new byte[4096];
            // 每次读取的字符串长度，如果为-1，代表全部读取完毕
            int len = 0;
            // 使用一个输入流从buffer里把数据读取出来
            while ((len = inStream.read(buffer)) != -1) {
                // 用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
                byteArrayOutputStream.write(buffer, 0, len);
            }
            // 把outStream里的数据写入内存
            // 输出数据
            OutputStream outStream = response.getOutputStream();
            // 写入数据
            outStream.write(byteArrayOutputStream.toByteArray());
            outStream.flush();
            // 关闭输入流
            inStream.close();
            // 关闭输出流
            outStream.close();
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    @Override
    public void downloadAndZip(HttpServletResponse response, List<String> urls) {
        try {
            String name = System.currentTimeMillis() + ".zip";
            // 创建zip输出流
            response.setCharacterEncoding("utf-8");
            response.setHeader("content-type", "application/octet-stream");
            // 设置浏览器响应头对应的Content-disposition
            response.setHeader("Content-disposition",
                    "attachment;filename=" + URLEncoder.encode(name, StandardCharsets.UTF_8));
            // new String(name.getBytes("gbk"), "iso8859-1"));
            // 创建zip输出流
            ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());
            for (String url : urls.stream().map(l ->
                    localFilePath + l.replaceAll("/statics", "")).toList()) {
                // 从URL下载文件
                String fileName = url.substring(url.lastIndexOf("/") + 1);
                // InputStream inputStream = new URL(url).openStream();
                InputStream inputStream = new FileInputStream(new File(url));
                // 将文件添加到zip输出流
                zipOut.putNextEntry(new ZipEntry(fileName));
                // 写入文件内容
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) > 0) {
                    zipOut.write(buffer, 0, length);
                }

                // 关闭当前文件流
                inputStream.close();
                zipOut.closeEntry();
            }
            // 关闭zip输出流
            zipOut.close();

        } catch (IOException e) {
            throw new ServiceException(e.getMessage());
        }
    }
}
