package com.ruoyi.project.officeConvert;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;

import org.jodconverter.DocumentConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.ruoyi.project.officeConvert.PptPreview.pptToImage;
import static com.ruoyi.project.officeConvert.PptPreview.pptxToImage;


@Component
@RestController
@RequestMapping(value="/office",method = RequestMethod.POST)
public class OfficeConvertController {

    // 第一步：转换器直接注入
    @Resource
    DocumentConverter documentConverter;

    protected final Logger logger = LoggerFactory.getLogger(BaseController.class);

    private static  String successMsg="请求成功！请预览文件！";

    private static  String failMsg="暂不支持此格式类型文件预览，请下载后查看！";

    private static  String codeMiss="若csv文件预览结果有乱码，请重新上传编码格式另存为ANSI的csv文件！";

    private static  String fileMiss="您需要预览的文件不存在，可能已在本地删除，请重新上传即可！";


    /**
     office类型的文件
     先远程服务端获取文件
     然后转换
     然后读写缓冲区返回前台
     */
    @PostMapping("/toPdfFile")
    public AjaxResult toPdfFile(HttpServletRequest request, HttpServletResponse response,String filepath) {
        // 获取HttpServletResponse
        response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        String newFilePath=filepath.replace("/profile","");
        // 需要转换的文件路径
        File file = new File(RuoYiConfig.getProfile()+newFilePath);
        boolean  flag= file.exists();
        if(flag==false){
            return new AjaxResult(HttpStatus.SUCCESS,fileMiss,Constants.RESOURCE_PREFIX+ "/" + newFilePath);
        }
        String converterPdf ="";  //生成的文件名
        try {
            // 转换之后文件生成的本地地址
            File newFile = new File(RuoYiConfig.getProfile());
            if (!newFile.exists()) {
                newFile.mkdirs();
            }
            String name =file.getName();
            int t=name.lastIndexOf(".");
            String newName=name.substring(0,t);
            //根据文件类型判断转换方式
            if(newFilePath.endsWith(".docx")||newFilePath.endsWith(".doc")||newFilePath.endsWith(".xlsx")
                    ||newFilePath.endsWith(".xls")||newFilePath.endsWith(".csv")||newFilePath.endsWith(".txt")){
                converterPdf =  newName+".html";
            }else if(newFilePath.endsWith(".mp4")||newFilePath.endsWith("pdf")||newFilePath.endsWith(".gif")
                    ||newFilePath.endsWith("jpg")||newFilePath.endsWith("png")
                    ||newFilePath.endsWith(".jpeg")){
                //浏览器可以直接打开的直接返回图片和视频的文件路径
                return   new AjaxResult(HttpStatus.SUCCESS,successMsg,Constants.RESOURCE_PREFIX+ "/" + newFilePath) ;
            }else {
                //其他类型都不支持就返回错误消息
                return new AjaxResult(HttpStatus.SUCCESS,failMsg,Constants.RESOURCE_PREFIX+ "/" + newFilePath);
            }
            // 文件转化
            documentConverter.convert(file).to(new File(RuoYiConfig.getProfile() + File.separator +"temp" + File.separator +converterPdf)).execute();
            //office文件需要给有表格的加一个边框 以免 排版出现问题
            if(newFilePath.endsWith(".xlsx")){
                this.doActionConvertedFile(RuoYiConfig.getProfile() + File.separator +"temp" + File.separator +converterPdf);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //最后应该返回转换后的文件名称
        String pathFileName = Constants.RESOURCE_PREFIX+ File.separator +"temp" + File.separator + converterPdf;
        return  newFilePath.endsWith(".csv")? new AjaxResult(HttpStatus.SUCCESS,codeMiss,pathFileName): new AjaxResult(HttpStatus.SUCCESS,successMsg,pathFileName) ;
    }

    @PostMapping("/toBookFile")
    public AjaxResult toBookFile(HttpServletRequest request, HttpServletResponse response,String filepath) {
        // 获取HttpServletResponse
        response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        String newFilePath=filepath.replace("/profile","");
        // 需要转换的文件路径
        File file = new File(RuoYiConfig.getProfile()+newFilePath);
        boolean  flag= file.exists();
        if(flag==false){
            return new AjaxResult(HttpStatus.SUCCESS,fileMiss,Constants.RESOURCE_PREFIX+ "/" + newFilePath);
        }
        String converterPdf ="";  //生成的文件名
        try {
            // 转换之后文件生成的本地地址
            File newFile = new File(RuoYiConfig.getProfile());
            if (!newFile.exists()) {
                newFile.mkdirs();
            }
            String name =file.getName();
            int t=name.lastIndexOf(".");
            String newName=name.substring(0,t);
            //预约开票的word文档
                converterPdf =  newName+".pdf";
            // 文件转化
            documentConverter.convert(file).to(new File(RuoYiConfig.getProfile() + File.separator +"temp" + File.separator +converterPdf)).execute();
            //office文件需要给有表格的加一个边框 以免 排版出现问题
           // this.doActionConvertedFile(RuoYiConfig.getProfile() + File.separator +"temp" + File.separator +converterPdf);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //最后应该返回转换后的文件名称
        String pathFileName = Constants.RESOURCE_PREFIX+ File.separator +"temp" + File.separator + converterPdf;
        return   new AjaxResult(HttpStatus.SUCCESS,successMsg,pathFileName) ;
    }

    public String wordTransPdf(String filepath) {
        // 获取HttpServletResponse
        String newFilePath=filepath.replace("/profile","");
        // 需要转换的文件路径
        File file = new File(RuoYiConfig.getProfile()+newFilePath);
        boolean  flag= file.exists();
        if(flag==false){
           logger.error("文件不存在");
        }
        String converterPdf ="";  //生成的文件名
        try {
            // 转换之后文件生成的本地地址
            File newFile = new File(RuoYiConfig.getProfile());
            if (!newFile.exists()) {
                newFile.mkdirs();
            }
            String name =file.getName();
            int t=name.lastIndexOf(".");
            String newName=name.substring(0,t);
            //预约开票的word文档
            converterPdf =  newName+".pdf";
            // 文件转化
            documentConverter.convert(file).to(new File(RuoYiConfig.getProfile() + File.separator +"temp" + File.separator +converterPdf)).execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //最后应该返回转换后的文件名称
        String pathFileName = Constants.RESOURCE_PREFIX+ File.separator +"temp" + File.separator + converterPdf;
        return  pathFileName;
    }


    /**
    PPT文件需要根据不同格式类型区分一下
     */
    @PostMapping("/PPTransJPEG")
    public AjaxResult PPTransJPEG(HttpServletRequest request, HttpServletResponse response,String filepath) {
        Map<String, Object> resultMap = new HashMap<>();
        String newFilePath=filepath.replace("/profile","");
        // 需要转换的PPT文件路径
        File file = new File(RuoYiConfig.getProfile()+newFilePath);
        //判断ppt，pptx文件是否存在本地
        boolean  flag= file.exists();
        if(flag==false){
            return new AjaxResult(HttpStatus.SUCCESS,fileMiss,Constants.RESOURCE_PREFIX+ "/" + newFilePath);
        }
        File imageFile = new File(RuoYiConfig.getProfile() + File.separator + "temp");
        if (!imageFile.exists()){
            imageFile.mkdirs();
        } //判断生成文件路径是否已存在
        String name =file.getName();
        int t=name.lastIndexOf(".");
        String newName=name.substring(0,t); //将名字带到生成方法中以便于区分不同文件名的ppt
        List list =new ArrayList();
        if(newFilePath.endsWith("pptx")){
            list= pptToImage(file, imageFile,newName);
        }else {
            list= pptxToImage(file, imageFile,newName);
        }
        //将生成的图片传给前端
        resultMap.put("imagePathList", list);
        //  resultMap.put("reviewUrlPrefix",  Constants.RESOURCE_PREFIX+ "/" );
        return  new AjaxResult(HttpStatus.SUCCESS,successMsg,resultMap);
    }

    private static final String getPathFileName(String uploadDir, String fileName) throws IOException
    {
        int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
        String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
        String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
        return pathFileName;
    }

    /**
     * 对转换后的文件进行操作(改变编码方式)
     *
     * @param outFilePath 文件绝对路径
     */
    public void doActionConvertedFile(String outFilePath) {
        StringBuilder sb = new StringBuilder();
        try (InputStream inputStream = new FileInputStream(outFilePath);
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, System.getProperty("sun.jnu.encoding")))) {
            String line;
            while (null != (line = reader.readLine())) {
                if (line.contains("charset=gb2312")) {
                    line = line.replace("charset=gb2312", "charset=utf-8");
                }
                sb.append(line);
            }
            // 添加sheet控制头
            sb.append("<script src=\"js/jquery-3.0.0.min.js\" type=\"text/javascript\"></script>");
            sb.append("<script src=\"js/excel.header.js\" type=\"text/javascript\"></script>");
            sb.append("<link rel=\"stylesheet\" href=\"bootstrap/css/bootstrap.min.css\">");
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 重新写入文件
        try (FileOutputStream fos = new FileOutputStream(outFilePath);
             BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, StandardCharsets.UTF_8))) {
            writer.write(sb.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
