package com.unis.crk.basic.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;

import cn.hutool.core.util.StrUtil;
import com.unis.crk.basic.entity.Attaches;

import com.unis.crk.basic.service.IAttachesService;
import com.unis.crk.basic.service.ISysParamsService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.unis.crk.utils.ResultUtil;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.*;
import java.net.*;
import java.util.Date;
import java.util.List;
import java.util.Map;


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * <p>
 * 附件列表 前端控制器
 * </p>
 *
 * @author ghh
 * @since 2021-10-14
 */
@Api(value = "附件列表",tags = {"附件列表"})
@RestController
@RequestMapping("attaches")
@CrossOrigin
public class AttachesController {

    private final static Logger LOGGER = LoggerFactory.getLogger(AttachesController.class);


    @Autowired
    private IAttachesService attachesService;
    @Autowired
    private ISysParamsService sysParamsService;

    /**
     * 根据ID查询数据
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "查询", notes = "根据ID查询数据")
    @GetMapping("getOne/{id}")
    public ResultUtil getOne(@PathVariable("id") String id) {
        LOGGER.info("入参为:{}", id);
        ResultUtil<Attaches> data = new ResultUtil<>();
        if (StringUtils.isEmpty(id)) {
            data.failed("传入的主键为空");
            return data;
        }
        data.success(this.attachesService.getById(id));
        return data;
    }


    /**
     * 查询全部数据
     *
     * @return
     */
    @ApiOperation(value = "查询", notes = "查询全部数据")
    @GetMapping("getAll")
    public ResultUtil getAll() {
        ResultUtil<List<Attaches>> data = new ResultUtil<>();
        data.success(this.attachesService.list());
        return data;
    }

    /**
     * 根据单据ID查询附件信息
     *
     * @return
     */
    @ApiOperation(value = "根据单据ID查询附件信息", notes = "根据单据ID查询附件信息")
    @GetMapping("getAttachesByReferencesID")
    public ResultUtil getAttachesByReferencesID(@PathVariable("referencesID") String referencesID) {
        ResultUtil<List<Attaches>> data = new ResultUtil<>();
        if (StrUtil.isNotBlank(referencesID)) {
            return data.failed("请传入单价ID，或者数据ID");
        }
        List<Attaches> attachesList = this.attachesService.getAttachesByReferencesID(referencesID);
        return data.success(attachesList);
    }

    /**
     * 新增一条数据
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "新增", notes = "新增一条数据")
    @PostMapping("add")
    public ResultUtil add(@RequestBody Attaches param) {
        LOGGER.info("入参为:{}", param);
        ResultUtil<Boolean> data = new ResultUtil<>();
        if (ObjectUtils.isEmpty(param)) {
            data.failed("所接收对象为null");
            return data;
        }
        data.success(this.attachesService.save(param));
        return data;
    }


    /**
     * 修改一条数据
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "修改", notes = "修改一条数据")
    @PatchMapping("edit")
    public ResultUtil edit(@RequestBody Attaches param) {
        LOGGER.info("入参为:{}", param);
        ResultUtil<Boolean> data = new ResultUtil<>();
        if (ObjectUtils.isEmpty(param)) {
            data.failed("所接收对象为null");
            return data;
        }
        data.success(this.attachesService.updateById(param));
        return data;
    }


    /**
     * 根据ID删除数据
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "删除", notes = "根据ID删除数据")
    @DeleteMapping("delete/{id}")
    public ResultUtil delete(@PathVariable("id") String id) {
        LOGGER.info("入参为:{}", id);
        ResultUtil<Boolean> data = new ResultUtil<>();
        if (StringUtils.isEmpty(id)) {
            data.failed("所接收id为null");
            return data;
        }
        data.success(this.attachesService.removeById(id));
        return data;
    }

    /**
     * @param file
     * @param
     * @return
     */
    @ApiOperation(value = "文件上传", notes = "文件上传,attaches对象中必传单位ID(unitID)和业务单据referencesID")
    @PostMapping("fileUpload")
    public ResultUtil fileUpload(MultipartFile file) {
        ResultUtil<Attaches> data = new ResultUtil<>();
        //获取文件名
        String fileName = file.getOriginalFilename();
        if (file.isEmpty()) {
            return data.failed("文件为空");
        }
        String type = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String s = IdUtil.simpleUUID();
        //设置上传文件的保存路径
        Date date = DateUtil.date();
        //获得年的部分
        int year = DateUtil.year(date);
        //获得月份，从0开始计数
        int month = DateUtil.month(date)+1;
        String paramVal = sysParamsService.getById("upload.url").getParamVal();
        //String paramVal="http://101.36.160.210:9905//home//sysupuser//apache-tomcat-8.5.53//file";
        String filePath = paramVal + "//" + year + month;
        File uploadFile = new File(filePath);
        String url = filePath + "//" + s + type;
        //保存附件信息
        Attaches attaches = new Attaches();
        attaches.setUrl(url);
        attaches.setSelfID(s);
        attaches.setFileName(file.getOriginalFilename());
        attaches.setExtensionName(type);
        attaches.setUploadTime(date);
        if (!uploadFile.exists()) {
            uploadFile.mkdirs();
        }
        FileOutputStream fileOutputStream = null;
        try {
            InputStream inputStream = file.getInputStream();
            fileOutputStream = new FileOutputStream(new File(url));
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, len);
                fileOutputStream.flush();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println(e.toString());
            return data.failed("文件未找到异常");
        } catch (IOException e) {
            System.out.println(e.toString());
            e.printStackTrace();
            return data.failed("io异常");
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return data.success(attaches);
    }


    @ApiOperation(value = "删除已上传文件", notes = "删除已上传文件")
    @PostMapping("delFile")
    public ResultUtil delFile(@RequestBody Attaches param) {
        ResultUtil<Boolean> data = new ResultUtil<>();

        boolean msg = attachesService.delFile(param);

        if (msg) {
            return data.success("删除文件成功");
        } else {
            return data.failed("没有该文件，删除失败");
        }


    }


    @PostMapping(value = "/downloadFile")
    @ApiOperation(value = "文件下载")
    public void downloadFile(@RequestBody Attaches param, HttpServletResponse response, HttpServletRequest request) {
        ServletOutputStream out = null;
        FileInputStream ips = null;
        String fileName = param.getFileName();
        try {
            String url = param.getUrl(); //此处为业务需要 如果是测试可以指定路径
            //获取文件存放的路径


            String userAgent = request.getHeader("User-Agent");
            // 针对IE或者以IE为内核的浏览器：
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            } else {
                // 非IE浏览器的处理：
                fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");

                response.setHeader("Content-disposition",
                        String.format("attachment; filename=\"%s\"", fileName + param.getExtensionName()));
                response.setContentType("application/vnd.ms-excel;charset=utf-8");
                response.setCharacterEncoding("UTF-8");
                File file = new File(url);
                //获取到文字 数据库里对应的附件名字加上老的文件名字：filename 截取到后面的文件类型 例：txt 组成一个新的文件名字：newFileName

                if (!file.exists()) {
                    //如果文件不存在就跳出
                    return;
                }
                ips = new FileInputStream(file);
                out = response.getOutputStream();
                //读取文件流
                int len = 0;
                byte[] buffer = new byte[1024 * 10];
                while ((len = ips.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
                out.flush();
            }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                try {
                    out.close();
                    ips.close();
                } catch (IOException e) {
                    System.out.println("关闭流出现异常");
                    e.printStackTrace();
                }
            }
            return;
        }

    @GetMapping(value = "/download/{selfID}")
    @ApiOperation(value = "文件下载")
    public void download(@PathVariable("selfID") String selfID,HttpServletResponse response, HttpServletRequest request){
        ServletOutputStream out = null;
        FileInputStream ips = null;
        Attaches param = this.attachesService.getById(selfID);
        // path是指欲下载的文件的路径。
        String url = param.getUrl();
        File file = new File(url);
        //File file = new File(filePath);
        // 取得文件名。
        String fileName = param.getFileName();
        String fileType = param.getExtensionName();
        // 以流的形式下载文件。
        response.setHeader("content-type", "application/octet-stream");
        if(".pdf".equals(fileType)){
            response.setContentType("application/pdf;charset=GBK");
        }else if(".xls".equals(fileType) || "xlsx".equals(fileType)){
            response.setContentType("application/msexcel;charset=GBK");
        }else if(".doc".equals(fileType) || "docx".equals(fileType)){
            response.setContentType("application/msword;charset=GBK");
        }else if(".txt".equals(fileType)){
            response.setContentType("text/plain;charset=GBK");
        }else {
            response.setContentType("application/octet-stream");
        }
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" +
                    new String(fileName.getBytes("GB2312"), "ISO8859-1"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream(file));
            int i = bis.read(buff);
            while (i != -1) {
                os.write(buff, 0, buff.length);
                os.flush();
                i = bis.read(buff);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
