package com.dgtis.dorm.manager.admin.web;

import java.io.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.dgtis.dorm.manager.db.domain.Storage;
import com.dgtis.dorm.manager.db.service.AlumniRecordStorageService;
import com.dgtis.dorm.manager.db.service.FileSystemStorageService;
import com.dgtis.dorm.manager.db.service.StorageService;
import com.dgtis.dorm.manager.db.util.ResponseUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping("/admin/storage")
public class StorageController {
    @Autowired
    private StorageService storageService;
    @Autowired
    private AlumniRecordStorageService alumniRecordStorageService;

    /**
     *
     * 获取文件list
     *
     * @param key
     * @param oldName
     * @param startTime
     * @param endTime
     * @param page
     * @param limit
     *
     * @return
     */
    @GetMapping("/list")
    public Object list(String key,String oldName,String startTime,String endTime,
                       @RequestParam(value = "page", defaultValue = "1") Integer page,
                       @RequestParam(value = "limit", defaultValue = "10") Integer limit,
                       String sort, String order){

        Map<String,Object> storageList = alumniRecordStorageService.selectStorage(key,oldName,startTime,endTime,page,limit);

        return ResponseUtil.ok(storageList);
    }

    /**
     * 添加文件
     *
     * @param file
     * @return
     */
    @PostMapping("/create")
    public Object create(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
    	
    	String imgBelongs = request.getParameter("imgBelongs");
        Storage storageInfo = storageService.store(file , imgBelongs);

        return ResponseUtil.ok(storageInfo);
    }

    @PostMapping("/uploadPic")
    public Object uploadPic(@RequestParam("file") MultipartFile file) {
        Storage storageInfo = storageService.store(file);

        return ResponseUtil.ok(storageInfo);
    }


    /**
     * 删除文件
     *
     * @param id 文件id
     * @return
     */
    @PostMapping("/delete")
    public Object delete(String id) {
        storageService.deleteById(Integer.parseInt(id));
        return ResponseUtil.ok();
    }


    /**
     * 方法描述 文件下载
     *
     * @param fileId 文件ID
     * @author huanghaoqi
     * @date 2017年09月01日 13:02:22
     */
    @GetMapping("/download")
    public ResponseEntity<Resource> download(@RequestParam("fileId") String fileId) {
         Storage storage = alumniRecordStorageService.findByKey(fileId);
        String fileName = storage.getFilePath();
        Resource file = storageService.loadAsResource(fileName);
        String responseFileName=storage.getOldName();
        try {
            responseFileName = new String(responseFileName .getBytes(), "ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + responseFileName +
                "\"").contentType(MediaType.parseMediaType(storage.getType()))
                .body(file);
    }

    /**
     * 方法描述 压缩包文件下载
     *
     * @author huanghaoqi
     * @date 2017年09月01日 13:02:22
     */
    @GetMapping("/downloadZip")
    public ResponseEntity<Resource> downloadZip(String[] fileIds) {
        String responseFileName="二维码.zip";
        Resource file=storageService.downloadZip(Arrays.asList(fileIds),responseFileName);
        try {
            responseFileName = new String(responseFileName .getBytes(), "ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + responseFileName +
                "\"").contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(file);
    }

    /**
     *  压缩并导出文件
     * @param zipPath 压缩文件临时路径  路径最后不要有 /
     * @param zipName 压缩为文件名 **.zip
     * @param createFilesPath 需要压缩的文件列表
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    public boolean downloadZip(String zipPath, String zipName, List<String> createFilesPath, HttpServletRequest request, HttpServletResponse response) {



        //String tmpFileName = "report.zip";
        byte[] buffer = new byte[1024];
        // String strZipPath = COM_REPORT_PATH+"/"+user.getOid()+"/"+report.getOid()+"/"+tmpFileName;

        String strZipPath=zipPath+"/"+zipName;
        try {
            File tmpZip=new File(zipPath);
            if (!tmpZip.exists())
                tmpZip.mkdirs();
            File tmpZipFile = new File(strZipPath);
            if (!tmpZipFile.exists())
                tmpZipFile.createNewFile();

            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(strZipPath));
            // 需要同时下载的两个文件result.txt ，source.txt

            File[] file1 =new File[createFilesPath.size()] ;

            for(int i=0;i<createFilesPath.size();i++){
                file1[i]=new File(createFilesPath.get(i));
            }
            for (int i = 0; i < file1.length; i++) {
                FileInputStream fis = new FileInputStream(file1[i]);
                out.putNextEntry(new ZipEntry(file1[i].getName()));
                //设置压缩文件内的字符编码，不然会变成乱码
                int len;
                // 读入需要下载的文件的内容，打包到zip文件
                while ((len = fis.read(buffer)) > 0) {
                    out.write(buffer, 0, len);
                }
                out.closeEntry();
                fis.close();
            }
            out.close();
            this.downloadFile(zipPath,zipName,response);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }


    /**
     * 以压缩文件导出
     * @param fileName
     * @param filePath
     * @param response
     */
    public void downloadFile(String filePath, String fileName, HttpServletResponse response){
        response.setCharacterEncoding("utf-8");
        // response.setContentType("application/octet-stream");

        try {
            File file=new File(filePath,fileName);
            // 以流的形式下载文件。
            BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            toClient.write(buffer);
            toClient.flush();
            toClient.close();

        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
    }


    /**
     * 方法描述  创建Zip
     *
     * @author huanghaoqi
     * @date 2018年12月10日 11:04:29
     */
    public void generateZip(List<File> files,String zipFileName) {
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        try {

            fos = new FileOutputStream(zipFileName);
            zos = new ZipOutputStream(new BufferedOutputStream(fos));
            byte[] bufs = new byte[1024 * 10];
            for (int i = 0; i < files.size(); i++) {
                ZipEntry zipEntry = new ZipEntry(files.get(i).getName());
                zos.putNextEntry(zipEntry);
                fis = new FileInputStream(files.get(i));
                bis = new BufferedInputStream(fis, 1024 * 10);
                int read = 0;
                while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
                    zos.write(bufs, 0, read);
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        finally {
            try {
                if (null != bis)
                {
                    bis.close();
                }
                if (null != zos)
                {
                    zos.close();
                }
                if (null != fis)
                {
                    fis.close();
                }
                if (null != fos)
                {
                    fos.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
