package com.dxhy.core.controller;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dxhy.api.model.db.SysMessagecontrolEntity;
import com.dxhy.common.constant.CommonConstants;
import com.dxhy.common.controller.AbstractController;
import com.dxhy.common.util.StringHelper;
import com.dxhy.common.utils.R;
import com.dxhy.core.service.filedownload.IFileDownloadService;
import com.dxhy.jxpt.baseService.dao.SysMessagecontrolDao;
import com.dxhy.oss.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * ftp下载web接口
 *
 * @author user
 */

@RestController
@RequestMapping("ftp")
@Slf4j
@SuppressWarnings("AlibabaUndefineMagicConstant")
public class FtpDownloadController extends AbstractController {

    @Resource
    private FileService fileService;

    @Resource
    private IFileDownloadService fileownloadService;

    @Resource
    private SysMessagecontrolDao sysMessagecontrolDao;

    @Value("${ftp.connection.mouldFilePath}")
    private String mouldFilePath;

    /**
     * ftp文件下载
     *
     * @param serviceType
     *            业务类型
     * @param downloadId
     *            下载唯一标识
     * @return
     *
     */
    @PostMapping("/download")
    @ResponseBody
    public ResponseEntity<?> downLoadFtpFile(String serviceType, String downloadId, HttpServletResponse response) {
        // 入参统一在入口处理
        Map<String, String> pramsMap = new HashMap<>(16);
        pramsMap.put("userName", getUserName());
        pramsMap.put("dbName", getUserInfo().getDbName());

        if (!StringHelper.isBlank(serviceType)) {
            pramsMap.put("serviceType", serviceType);
        } else {
            return ResponseEntity.ok(R.error("业务类型不能为空！"));
        }

        if (!StringHelper.isBlank(downloadId)) {
            pramsMap.put("downloadId", downloadId);
        } else {
            return ResponseEntity.ok(R.error("下载唯一标识不能为空！"));
        }
        try {
            Map<String, String> fileMap = fileownloadService.downLoadFileFromFtp(pramsMap);
            if (fileMap.containsKey("errmsg")) {
                return ResponseEntity.ok(R.error(fileMap.get("errmsg")));
            } else {
                String fileName = fileMap.get("fileName");
                String filePath = fileMap.get("filePath");

                File downLoadFile = new File(filePath);

                // 获取文件的长度
                long fileLength = downLoadFile.length();

                BufferedInputStream bis = null;
                BufferedOutputStream bos = null;

                // 设置文件输出类型
                if ("1".equals(serviceType)) {
                    response.setContentType(this.getContentType(fileName));
                } else {
                    response.setContentType("application/octet-stream");
                }
                response.setHeader("Content-disposition",
                    "attachment; filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1"));
                // 设置输出长度
                response.setHeader("Content-Length", String.valueOf(fileLength));

                // 获取输入流
                bis = new BufferedInputStream(new FileInputStream(downLoadFile));
                // 输出流
                bos = new BufferedOutputStream(response.getOutputStream());
                byte[] buff = new byte[2048];
                int bytesRead;
                while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                    bos.write(buff, 0, bytesRead);
                }
                bos.flush();
                // 关闭流
                bis.close();
                bos.close();

                // 删除本地文件，防止服务器空间不足
                downLoadFile.delete();

                return null;
            }
        } catch (Exception e) {
           log.info("业务处理异常：{}", e);
            log.error("", e);
            return ResponseEntity.ok(R.error(CommonConstants.MSG_ERR_DEFAULT));
        }
    }


    @GetMapping("/getDownload")
    @ResponseBody
    public ResponseEntity<?> downLoadFtpFileGet(String serviceType, String downloadId, HttpServletResponse response) {
        // 入参统一在入口处理
        Map<String, String> pramsMap = new HashMap<>(16);
        pramsMap.put("userName", "system");
        pramsMap.put("dbName", "business");

        if (!StringHelper.isBlank(serviceType)) {
            pramsMap.put("serviceType", serviceType);
        } else {
            return ResponseEntity.ok(R.error("业务类型不能为空！"));
        }

        if (!StringHelper.isBlank(downloadId)) {
            pramsMap.put("downloadId", downloadId);
        } else {
            return ResponseEntity.ok(R.error("下载唯一标识不能为空！"));
        }
        try {
            Map<String, String> fileMap = fileownloadService.downLoadFileFromFtp(pramsMap);
            if (fileMap.containsKey("errmsg")) {
                return ResponseEntity.ok(R.error(fileMap.get("errmsg")));
            } else {
                //通过downloadId和serviceType拼接 来获取文件名
                String urlStr = "/ftp/download?serviceType="+serviceType+"&downloadId="+downloadId;
                SysMessagecontrolEntity sysMessagecontrolEntity = sysMessagecontrolDao.selectOne(new LambdaQueryWrapper<SysMessagecontrolEntity>().eq(SysMessagecontrolEntity::getUrl, urlStr));
                String fileName = fileMap.get("fileName");
                if(ObjectUtils.isNotEmpty(sysMessagecontrolEntity)){
                    fileName = sysMessagecontrolEntity.getTitle().replace("导出成功，可以下载", "")+"."+ FileUtil.getSuffix(fileName);
                }

                String filePath = fileMap.get("filePath");

                File downLoadFile = new File(filePath);

                // 获取文件的长度
                long fileLength = downLoadFile.length();

                BufferedInputStream bis = null;
                BufferedOutputStream bos = null;

                // 设置文件输出类型
                if ("1".equals(serviceType)) {
                    response.setContentType(this.getContentType(fileName));
                } else {
                    response.setContentType("application/octet-stream");
                }
                response.setHeader("Content-disposition",
                        "attachment; filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1"));
                // 设置输出长度
                response.setHeader("Content-Length", String.valueOf(fileLength));

                // 获取输入流
                bis = new BufferedInputStream(new FileInputStream(downLoadFile));
                // 输出流
                bos = new BufferedOutputStream(response.getOutputStream());
                byte[] buff = new byte[2048];
                int bytesRead;
                while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                    bos.write(buff, 0, bytesRead);
                }
                bos.flush();
                // 关闭流
                bis.close();
                bos.close();

                // 删除本地文件，防止服务器空间不足
                downLoadFile.delete();

                return null;
            }
        } catch (Exception e) {
            log.info("业务处理异常：{}", e);
            log.error("", e);
            return ResponseEntity.ok(R.error(CommonConstants.MSG_ERR_DEFAULT));
        }
    }


    /**
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/list/getImage", produces = MediaType.IMAGE_PNG_VALUE)
    @ResponseBody
    public BufferedImage getImage() throws IOException {
        return ImageIO.read(new FileInputStream(new File("/Users/peipei/Desktop/1.png")));
    }

    /**
     * 根据图片后缀，获取mime类型
     *
     * @param fileName
     * @return
     *
     */
    private String getContentType(String fileName) {
        String mime = "application/octet-stream";
        if (fileName.indexOf(".gif") > 0) {
            mime = "image/gif";
        } else if (fileName.indexOf(".jpg") > 0 || fileName.indexOf(".jpeg") > 0) {
            mime = "image/jpeg";
        } else if (fileName.indexOf(".png") > 0) {
            mime = "image/png";
        } else if (fileName.indexOf(".bmp") > 0) {
            mime = "image/bmp";
        } else if (fileName.indexOf(".svg") > 0) {
            mime = "image/svg";
        }
        return mime;
    }

    /**
     * ftp文件下载
     *
     * @param fileName
     *            业务类型
     * @param response
     *            HttpServletResponse
     * @return 返回
     *
     */
    @RequestMapping("/downLoadFtpFileMould")
    @ResponseBody
    public ResponseEntity<?> downLoadFtpFileMould(String fileName, HttpServletResponse response) {
        try {
            boolean validFileName = isValidFileName(fileName);
            if(!validFileName){
                return ResponseEntity.ok(R.error(CommonConstants.FILE_NAME_ERROR).put("code", "9999"));
            }
            File downLoadFile = new File(mouldFilePath + fileName);
            // 获取文件的长度
            long fileLength = downLoadFile.length();
            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;

            // 设置文件输出类型
            response.setContentType("application/octet-stream");
            response.setHeader("Content-disposition",
                "attachment; filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1"));
            // 设置输出长度
            response.setHeader("Content-Length", String.valueOf(fileLength));
            // 获取输入流
            bis = new BufferedInputStream(new FileInputStream(downLoadFile));
            // 输出流
            bos = new BufferedOutputStream(response.getOutputStream());
            byte[] buff = new byte[2048];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
            bos.flush();
            // 关闭流
            bis.close();
            bos.close();
            return null;
        } catch (Exception e) {
           log.info("业务处理异常：{}", e);
            log.error("", e);
            return ResponseEntity.ok(R.error(CommonConstants.MSG_ERR_DEFAULT));
        }
    }

    public static boolean isValidFileName(String fileName) {
        // 文件名合法性校验：只允许字母、数字、下划线、短横线和扩展名
        String regex = "^[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9]+)?$";
        return fileName != null && fileName.matches(regex);
    }

    public static void main(String[] args) {
        System.out.println(isValidFileName("importRzInvoice.xlsx"));
    }
}
