package com.engine.htsc.payment.util.pdf;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.ZipUtil;
import com.engine.htsc.payment.eusp.EUSPWsSoapClient;
import com.engine.htsc.payment.eusp.EUSPWsSoapClient2;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Encoder;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.interfaces.htsc.download.FileStream;

import java.io.*;

public class HtmlToPdfUtil {
  private static final BaseBean log = new BaseBean();
  private static final String logPre = " ===eusp=== ";

  // wkhtmltopdf在windows系统中的路径
  private static final String WKHTMLTOPDF_WINDOWS_URL =
          "D:\\ecology\\wkhtmltopdf\\windows\\bin\\wkhtmltopdf.exe";
  // wkhtmltopdf在linux系统中的路径
  private static final String WKHTMLTOPDF_LINUX_URL = "wkhtmltopdf";

  //临时解压文件存放路径
  private static final String TEMP_FILE_DIR = "/app/ecology/filesystem/temp/html2pdf";
  //静态文件访问路径
  private static final String STATIC_FILE_DIR = "/app/ecologystatic/htoa/interface/htsc/html2pdf";

  private static final String RENAME = "temp.html";

  /**
   * 根据流程编号,获取流程pdf件
   * @param title 流程标题
   * @return pdf文件地址
   */
  public static synchronized String get(String title) throws Exception {
    RecordSet rs = new RecordSet();
    rs.executeQuery(String.format("SELECT\n" +
        "\tt1.imageFileId,\n" +
        "\tt1.imageFileName,\n" +
        "\tt1.fileRealPath,\n" +
        "\tt1.isZip,\n" +
        "\tt1.filesize\n" +
        "FROM\n" +
        "\tImageFile t1\n" +
        "LEFT JOIN DocImageFile t2 ON\n" +
        "\tt1.imagefileid = t2.imagefileid\n" +
        "WHERE\n" +
        "\tt2.IMAGEFILENAME = '%s_offline_pdf.pdf' ORDER BY IMAGEFILEID DESC ", title));
    String fileRealPath = "";
    String imageFileName = "";
    if (rs.next()) {
      fileRealPath = Util.null2String(rs.getString("fileRealPath"));
      imageFileName = Util.null2String(rs.getString("imageFileName"));
    }
    Assert.notBlank(fileRealPath, "流程附件信息为空:fileRealPath title : " + title);
    Assert.notBlank(imageFileName, "流程附件信息为空:imageFileName title : " + title);
    //生成临时文件路径
    File dir = new File(TEMP_FILE_DIR);
    if (dir.exists()) {
      dir.delete();
    }
    dir.setWritable(true, false);
    dir.mkdirs();
    File file = new File(TEMP_FILE_DIR + File.separator + imageFileName); //zip文件
    Runtime.getRuntime().exec("chmod -R 777" + file);
    //系统解密解压
    FileStream fileStream;
    try {
      log.writeLog("执行第一次获取nas pdf文件");

      fileStream = new FileStream(fileRealPath, "1");
      try (OutputStream os = new FileOutputStream(file)) {
        fileStream.write(os);
        return file.getAbsolutePath();
      } catch (Exception e) {
        throw new Exception(e);
      }

    } catch (Exception e) {

      try {
        log.writeLog("执行第二次获取nas pdf文件");

        fileStream = new FileStream(fileRealPath, "1");
        try (OutputStream os = new FileOutputStream(file)) {
          fileStream.write(os);
          return file.getAbsolutePath();
        } catch (Exception e1) {
          throw new Exception(e1);
        }

      } catch (Exception ex) {
        throw new Exception("系统文件获取失败", ex);
      }

    }
  }

  /**
   * 根据流程编号,获取流程pdf件
   * @param title 流程标题
   * @return pdf文件地址
   */
  public static synchronized String getPdfPathByTitle(String title) throws Exception {
    RecordSet rs = new RecordSet();
    rs.executeQuery(String.format("SELECT\n" +
            "\tt1.imageFileId,\n" +
            "\tt1.imageFileName,\n" +
            "\tt1.fileRealPath,\n" +
            "\tt1.isZip,\n" +
            "\tt1.filesize\n" +
            "FROM\n" +
            "\tImageFile t1\n" +
            "LEFT JOIN DocImageFile t2 ON\n" +
            "\tt1.imagefileid = t2.imagefileid\n" +
            "WHERE\n" +
            "\tt2.IMAGEFILENAME = '%s_offline_pdf.pdf' ORDER BY IMAGEFILEID DESC ", title));
    String fileRealPath = "";
    String imageFileName = "";
    if (rs.next()) {
      fileRealPath = Util.null2String(rs.getString("fileRealPath"));
      imageFileName = Util.null2String(rs.getString("imageFileName"));
    }
    Assert.notBlank(fileRealPath, "流程附件信息为空:fileRealPath title : " + title);
    Assert.notBlank(imageFileName, "流程附件信息为空:imageFileName title : " + title);
    //生成临时文件路径
    File dir = new File(TEMP_FILE_DIR);
    if (dir.exists()) {
      dir.delete();
    }
    dir.setWritable(true, false);
    dir.mkdirs();
    File file = new File(TEMP_FILE_DIR + File.separator + imageFileName); //zip文件
    Runtime.getRuntime().exec("chmod -R 777" + file);
    //系统解密解压
    FileStream fileStream;
    try {
      log.writeLog("执行第一次获取nas pdf文件");

      fileStream = new FileStream(fileRealPath, "1");
      try (OutputStream os = new FileOutputStream(file)) {
        fileStream.write(os);
        return file.getAbsolutePath();
      } catch (Exception e) {
        throw new Exception(e);
      }

    } catch (Exception e) {

      try {
        log.writeLog("执行第二次获取nas pdf文件");

        fileStream = new FileStream(fileRealPath, "1");
        try (OutputStream os = new FileOutputStream(file)) {
          fileStream.write(os);
          return file.getAbsolutePath();
        } catch (Exception e1) {
          throw new Exception(e1);
        }

      } catch (Exception ex) {
        throw new Exception("系统文件获取失败", ex);
      }

    }
  }

  /**
   * 同步pdf附件到新意平台
   */
  public static void sendPdfToEusp(String requestMark, String fileStream) {
    EUSPWsSoapClient client = new EUSPWsSoapClient();

    client.sendOAFile(requestMark, "pdf", fileStream);

    EUSPWsSoapClient2 client2 = new EUSPWsSoapClient2();

    client2.sendOAFile(requestMark, "pdf", fileStream);
  }

  /**
   * 生成PDF文件
   *
   * @param destPath 保存pdf地址
   */
  public static boolean toPdf(String destPath, String cmd) throws IOException {
    File dir = new File(destPath);
    if (dir.exists()) {
      dir.delete();
    }
    dir.setWritable(true, false);
    dir.mkdirs();
    Runtime.getRuntime().exec("chmod -R 777" + dir);
    log.writeLog("转pdf命令行:" + cmd);
    boolean result = true;
    try {
      String response = RuntimeUtil.execForStr(cmd);
      log.writeLog(response);
    } catch (Exception e) {
      result = false;
      e.printStackTrace();
    }

    return result;
  }

  /**
   * 根据流程标题获取html文件路径
   *
   * @param title 流程标题
   */
  public static void getHtmlPathByTitle(String title) throws Exception {
    RecordSet rs = new RecordSet();
    rs.executeQuery(String.format("SELECT\n" +
            "\tt1.imageFileId,\n" +
            "\tt1.imageFileName,\n" +
            "\tt1.fileRealPath,\n" +
            "\tt1.isZip,\n" +
            "\tt1.filesize\n" +
            "FROM\n" +
            "\tImageFile t1\n" +
            "LEFT JOIN DocImageFile t2 ON\n" +
            "\tt1.imagefileid = t2.imagefileid\n" +
            "WHERE\n" +
            "\tt2.IMAGEFILENAME = '%s_offline_html.zip'", title));
    String fileRealPath = "";
    String imageFileName = "";
    if (rs.next()) {
      fileRealPath = Util.null2String(rs.getString("fileRealPath"));
      imageFileName = Util.null2String(rs.getString("imageFileName"));
    }
    //系统解密解压
    FileStream fileStream = new FileStream(fileRealPath, "1");
    File file = new File(TEMP_FILE_DIR + File.separator + imageFileName); //zip文件
    try (OutputStream os = new FileOutputStream(file)) {
      fileStream.write(os);
    }
    //zip文件解压到 /app/ecologystatic/htoa/interface/htsc/html2pdf/
    File dir = new File(STATIC_FILE_DIR);
    if (dir.exists()) {
      dir.delete();
    }
    dir.setWritable(true, false);
    dir.mkdirs();
    Runtime.getRuntime().exec("chmod -R 777" + dir);
    File unzipFolder = ZipUtil.unzip(file.getAbsolutePath(), STATIC_FILE_DIR);
    //html文件需要重命名
    File htmlFile = fileTypeUnderFolder(unzipFolder, ".html");
    renameFile(htmlFile);
    //完整访问路径 "http://eipsit.htsc.com.cn/htoa/interface/htsc/html2pdf/temp.html"
  }

  /**
   * 指定路径下的html文件,解压后文件只存在一个html文件
   *
   * @param file 指定文件夹
   * @return html文件绝对路径
   */
  private static File fileTypeUnderFolder(File file, String fileType) throws Exception {
    File[] fs = file.listFiles();
    Assert.notNull(fs, "html所在文件夹为空");
    for (File f : fs) {
      if (f.isDirectory())    //若是目录,跳过
        continue;
      if (f.isFile() && f.getAbsolutePath().contains(fileType)) { //若是文件,返回文件
        return f;
      }
    }
    return null;
  }

  /**
   * 文件重命名
   */
  private static void renameFile(File oldFile) throws Exception {
    File newFile = new File(oldFile.getParentFile() + File.separator + RENAME);
    //重命名文件不存在
    if (oldFile.exists()) {
      boolean flag = oldFile.renameTo(newFile);
      log.writeLog("文件重命名:" + flag);
    }
  }

  /**
   * 文件流转string
   */
  public static String read2String(String filePath) {
    String ioStr = "";
    FileInputStream is = null;
    try {
      is = new FileInputStream(filePath);
      byte[] in = new byte[is.available()];
      is.read(in, 0, in.length);
      return new BASE64Encoder().encode(in);
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (null != is) {
        try {
          is.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    return null;

  }


}
