package com.inkasso.factoring.file.controller;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.util.StringUtil;
import com.inkasso.adapter.enums.FileBusinessInterface;
import com.inkasso.adapter.response.ResponseData;
import com.inkasso.factoring.common.util.onlineConverter.OfficeConverterUtil;
import com.inkasso.factoring.common.util.onlineConverter.TextConverterPdfUtil;
import com.inkasso.factoring.file.entity.FileStorage;
import com.inkasso.factoring.file.entity.FileStorageDO;
import com.inkasso.factoring.file.enums.FileTypeEnum;
import com.inkasso.factoring.file.service.FileService;
import com.inkasso.factoring.file.service.FileStorageService;
import com.inkasso.factoring.file.util.FileUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 *
 */
@Controller
@RequestMapping("system")
public class FilePreviewController {

    private Logger log = LogManager.getLogger(FilePreviewController.class);
    private static String PREFIX = "sys/fileStorage/";

    @Autowired
    private FileService fileService;

    @Autowired
    private FileStorageService fileStorageService;


    /**
     * 预览非图片的</br>
     * 文档预览，不使用流直接输出到页面上，因为浏览器不支持这样的格式。通常word、excel都是用流下载的</br>
     * 根据文件的类型，用不同的处理方式来预览文件
     */
    @RequestMapping("/fileStorage/preview")
    public String previewTest(Long fileId, Long resource, HttpServletResponse response, Model model) {
        //C端文件
        String fileType ;
        String fileName ;
        String sourceFilePath ;
        String path ;
        if(resource == 1){
            FileStorageDO fileStorageDO = fileService.getById(fileId);
            fileType = fileStorageDO.getType();
            fileName = fileStorageDO.getOriginalName().replace(",", "");
            sourceFilePath = fileStorageDO.getAbsolutePath();
            path = fileStorageDO.getPath();
        }else {
            FileStorage fileStorage = fileStorageService.getById(fileId);
            fileType = fileStorage.getFileType();
            fileName = fileStorage.getOriginalName().replace(",", "");
            sourceFilePath = fileStorage.getAbsolutePath();
            path = fileStorage.getPath();
        }
        if (StringUtils.isNotEmpty(fileType) && StringUtils.isNotEmpty(fileName) && StringUtils.isNotEmpty(fileName) && StringUtils.isNotEmpty(path)) {
            // 1、处理以及预览doc、docx、rtf文件。使用了openOffice转换成pdf
            if (fileType.equalsIgnoreCase(".doc") || fileType.equalsIgnoreCase(".docx")
                    || fileType.equalsIgnoreCase(".rtf") || fileType.equalsIgnoreCase(".wps")) {
                String destFile = FileUtil.getFileOnlinePreviewPath() + "/word.pdf";
                File newPDFile = OfficeConverterUtil.office2Pdf(sourceFilePath, destFile);
                previewPdf(response, newPDFile, fileName, null);
            } else if (fileType.equalsIgnoreCase(".txt")) {
                // 2、单独处理txt文件，转换成pdf。没有使用openOffice
                TextConverterPdfUtil p = TextConverterPdfUtil.getInstance();
                String pdf = FileUtil.getFileOnlinePreviewPath() + "/txt.pdf";
                p.text2Pdf(sourceFilePath, pdf);
                previewPdf(response, new File(pdf), fileName, null);
            } else if (fileType.equalsIgnoreCase(".xls") || fileType.equalsIgnoreCase(".xlsx")
                    || fileType.equalsIgnoreCase(".et") || fileType.equalsIgnoreCase(".csv")) {
                // 3、处理Excel、使用openOffice转换成HTML
                String destFile = FileUtil.getFileOnlinePreviewPath() + "/excel.html";
                File htmlFile = OfficeConverterUtil.office2Pdf(sourceFilePath, destFile);
                //2023.4.25 如果excel嵌套有图片，需要替换下文件的路径
                htmlFile = replaceImgSrc(htmlFile);
                previewHtmlFile(response, htmlFile);
            } else if (fileType.equalsIgnoreCase(".pdf")) {
                File pdfFile = new File(sourceFilePath);
                previewPdf(response, pdfFile, fileName, "original");
            } else if (fileType.equalsIgnoreCase(".zip") || fileType.equalsIgnoreCase(".rar")) {
                fileService.downloadFile(fileId);
            }
        }
        return null;
    }

    /**
     * 以流的方式在浏览器上查看pdf文件
     */
    private void previewPdf(HttpServletResponse response, File pdfFile, String fileName, String sourceType) {
        FileInputStream inputStream;
        try {
            if (StringUtil.isNotEmpty(fileName)) {
                int end = fileName.lastIndexOf(".");
                String newName = fileName.substring(0, end);
                if (StringUtil.isNotEmpty(newName)) {
                    response.setHeader("Content-disposition",
                            "filename=" + new String(newName.getBytes("gbk"), "iso8859-1") + ".pdf");
                }
            }
            response.setContentType("application/pdf;charset=gb2312");
            // 通过文件路径获得File对象
            inputStream = new FileInputStream(pdfFile);
            OutputStream os = response.getOutputStream();
            log.error(inputStream);
            int read;
            while ((read = inputStream.read()) != -1) {
                os.write(read);
            }
            os.flush();
            inputStream.close();
            os.close();
        } catch (Exception e) {

        }
        if (StringUtil.isEmpty(sourceType)) {
            if (pdfFile.exists()) {
                pdfFile.delete();
            }
        }
    }

    /**
     * 替换下文件中嵌套的图片的路径
     *
     * @param htmlFile
     * @return
     */
    private File replaceImgSrc(File htmlFile) {
        try {
            Document doc = Jsoup.parse(htmlFile, "gbk");
            Elements imgElements = doc.getElementsByTag("IMG");
            if (imgElements != null && !imgElements.isEmpty()) {
                for (Element img : imgElements) {
                    String src = img.attr("SRC");
                    if (src != null) {
                        // img.attr("SRC", "/excelImg/" + src);
                        File imgFile = new File(htmlFile.getParent(), src);
                        if (imgFile.exists()) {
                            String type = src.substring(src.lastIndexOf(".") + 1);
                            String head = "data:image/" + type + ";base64,";
                            img.attr("SRC", head + Base64.encode(imgFile));
                            imgFile.delete();
                        }
                    }
                }
                String html = doc.getElementsByTag("HTML").html();

                if (htmlFile.exists()) {
                    boolean delete = htmlFile.delete();
                    if (delete) {
                        File newFile = new File(htmlFile.getAbsolutePath());
                        cn.hutool.core.io.FileUtil.appendString(html, newFile, "gbk");
                        return newFile;
                    }
                }
            }
            return htmlFile;

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

    /**
     * 用流的方式在浏览器上查看html文件
     */
    private void previewHtmlFile(HttpServletResponse response, File xmlFile) {
        response.setContentType("text/html");
        FileInputStream inputStream;
        try {
            inputStream = new FileInputStream(xmlFile);
            log.error(inputStream);
            OutputStream os = response.getOutputStream();
            int read;
            while ((read = inputStream.read()) != -1) {
                os.write(read);
            }
            os.flush();
            inputStream.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("预览Excel文件出错：" + e.getMessage());
        }
        if (xmlFile.exists()) {
            xmlFile.delete();
        }
    }
}
