package com.srs.web.controller.common;

import cn.hutool.core.date.DateUtil;
import com.srs.common.config.SrsConfig;
import com.srs.common.constant.Constants;
import com.srs.common.core.domain.AjaxResult;
import com.srs.common.utils.StringUtils;
import com.srs.common.utils.file.FileUploadUtils;
import com.srs.common.utils.file.FileUtils;
import com.srs.comprehensive.domain.AffixInfo;
import com.srs.comprehensive.domain.AffixItem;
import com.srs.comprehensive.service.ISrsAffixItemService;
import liquibase.util.file.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 附件上传
 *
 * @author srs
 */
@RestController
@RequestMapping("/affix")
public class AffixController {

    @Autowired
    private ISrsAffixItemService srsAffixItemService;
    //附件上传
    @PostMapping(value = "/upload")
    public AjaxResult upload(AffixInfo info) throws Exception {

        try {
            AffixItem affixItem = new AffixItem();
            this.uploadFileData(affixItem, info);
            affixItem.setCreateTime(new Date());
            //保存附件上传信息
            srsAffixItemService.save(affixItem);
            //文件上传成功信息
            AjaxResult ajax = AjaxResult.success();

            ajax.put("id", affixItem.getId());
            ajax.put("trueName", affixItem.getTrueName());
            ajax.put("savePath", affixItem.getSavePath());
            return ajax;
        } catch (IOException e) {
            //文件上传失败
            return AjaxResult.error(e.getMessage());
        }
    }
    //附件下载
    @PostMapping("/download")
    public void download(HttpServletRequest request, HttpServletResponse response, @RequestBody AffixItem affixItem) throws Exception {
        if (affixItem.getId() == null ) {
            return;
        }
        AffixItem queryResult  = this.srsAffixItemService.queryBy(affixItem.getId());
        if (queryResult == null) {
            return;
        }
         downloadFile(response,queryResult.getSavePath());
    }
    //文件下载
    public String downloadFile(HttpServletResponse response,
                                       String path) {
        String result = null;

        BufferedInputStream is = null;
        OutputStream os = null;
        try {
            response.setContentType("application/octet-stream");
            os = response.getOutputStream();
            // 本地资源路径
            String localPath = SrsConfig.getProfile();
            // 数据库资源地址
            String downloadPath = localPath + StringUtils.substringAfter(path, Constants.RESOURCE_PREFIX);
            FileUtils.writeBytes(downloadPath, os);
        } catch (Exception e) {
            result = "用户取消下载或其它IO异常" + e.getMessage();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ex) {
                    result = "关闭输入流异常：" + ex.getMessage();
                }
            }
            if (os != null) {
                try {
                    os.flush();
                } catch (IOException ex) {
                    result = "清空输出缓冲异常：" + ex.getMessage();
                }
                try {
                    os.close();
                } catch (IOException ex) {
                    result = "关闭输出流异常：" + ex.getMessage();
                }
            }
        }
        return result;
    }
    //删除附件
    @PostMapping(value = "/delete")
    public AjaxResult deleteItem(@RequestBody AffixItem affixItem) throws Exception {
        AffixItem queryResult = this.srsAffixItemService.queryBy(affixItem.getId());
        //删除文件

        // 本地资源路径
        String localPath = SrsConfig.getProfile();
        // 数据库资源地址
        String downloadPath = localPath + StringUtils.substringAfter(queryResult.getSavePath(), Constants.RESOURCE_PREFIX);
        FileUtils.deleteFile(downloadPath);
        //删除数据库附件内容
        this.srsAffixItemService.delete(affixItem.getId());
        AjaxResult ajax = AjaxResult.success();

        ajax.put("msg", "删除成功");
        ajax.put("tureName", affixItem.getTrueName());

        return ajax;
    }
    //查询附件
    @PostMapping(value = "/queryItems")
    public AjaxResult queryItems(@RequestBody AffixItem affixItem) throws Exception {
        AjaxResult ajax = AjaxResult.success();
        ajax.put("msg", "查询成功");
        ajax.put("tureName", affixItem.getTrueName());
        List<AffixItem> affixItems = this.srsAffixItemService.queryList(affixItem);
        ajax.put("data",affixItems);
        return ajax;
    }

    //文件上传
    private void uploadFileData(AffixItem affixItem, AffixInfo info) throws IOException {
        if (info.getFile() != null) {
            MultipartFile multipartFile = info.getFile();
            String trueName = multipartFile.getOriginalFilename(); // 文件保存的名称
            //String fileExtension = FilenameUtils.getExtension(trueName); //获取扩展名
            affixItem.setFileSize(new Long(multipartFile.getSize()).intValue()); //获取大小
            affixItem.setAffixId(info.getAffixId());
            affixItem.setTrueName(trueName);
            // 上传文件路径
            String filePath = SrsConfig.getUploadPath();
            // 上传并返回新文件名称
            String path = FileUploadUtils.upload(filePath, info.getFile());
            String saveName = FileUtils.getName(path);
            affixItem.setSaveName(saveName);
            affixItem.setSavePath(path);
        }
    }
    // 打包下载
    @PostMapping("/downloadAll")
    public void downloadAll(HttpServletResponse response,HttpServletRequest request ,@RequestBody AffixItem affixItem) throws Exception {
        if (affixItem.getAffixId() != null && !"".equals(affixItem.getAffixId()) && affixItem.getAffixId().indexOf(",") > 0) {
            affixItem.setAffixIds(affixItem.getAffixId().split(","));
            affixItem.setAffixId(null);
        }

        List<AffixItem> affixItemList = this.srsAffixItemService.queryList(affixItem);
        if (!affixItemList.isEmpty()) {
                List<String> fileSavePathList = new ArrayList<String>();
                List<String> fileNameList = new ArrayList<String>();
                for (AffixItem a : affixItemList) {
                    fileNameList.add(a.getTrueName());
                    fileSavePathList.add(a.getSavePath());
                }
                //附件打包下载
                downloadZip(response, fileNameList, fileSavePathList);
        }
    }
    //压缩包下载
    public static void downloadZip( HttpServletResponse response,List<String> fileNameList, List<String> fileSavePathList) throws IOException {


        //创建一个ZIP输出流
        ZipOutputStream out = new ZipOutputStream(response.getOutputStream());

        response.setContentType("application/octet-stream");

        Set<String> fileNameSet = new HashSet<String>();
        for (int i = 0; i < fileSavePathList.size(); i++) {
            String fileName = fileNameList.get(i);
            String fileSavePath = fileSavePathList.get(i);
            // 本地资源路径
            String localPath = SrsConfig.getProfile();
            // 数据库资源地址
            String downloadPath = localPath + StringUtils.substringAfter(fileSavePath, Constants.RESOURCE_PREFIX);
            System.out.println(downloadPath);
            int suffix = 1;
            while(!fileNameSet.add(fileName)) {
                fileName = fileNameList.get(i) + "_" + suffix;
                suffix++;
            }

            //读取文件的字节数组
            byte[] content= Files.readAllBytes(Paths.get(downloadPath));
            System.out.println(content.length);
            //创建文件（zip里面的文件）
            ZipEntry entry = new ZipEntry(fileName);
            //放入文件
            out.putNextEntry(entry);
            out.write(content, 0, content.length);
        }
        //设置返回信息
        response.setHeader("Content-Length", String.valueOf(out));
        out.closeEntry();
        out.close();
    }


}
