import { fetchPdf } from "../utils";
import { default as fileDownload } from "js-file-download";
import * as pdfMake from "pdfmake/build/pdfmake";
// PDF Fonts
const pdfFonts = {
  // download default Roboto font from cdnjs.com
  Roboto: {
    normal: "https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/fonts/Roboto/Roboto-Regular.ttf",
    bold: "https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/fonts/Roboto/Roboto-Medium.ttf",
    italics: "https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/fonts/Roboto/Roboto-Italic.ttf",
    bolditalics: "https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/fonts/Roboto/Roboto-MediumItalic.ttf",
  },
};
function csvQuote(value) {
  if (value == undefined)
    return "";
  return value.indexOf(",") !== -1 ? `"${value.replace(/"/g, '""')}"` : value;
}
export class TableExportController {
  /**
   * Exports the table specified by options
   * @param options
   */
  async create(options) {
    let tableSelector = "gl-table" + (options.tableId != undefined ? `#${options.tableId}` : "");
    let table = options.table != undefined
      ? options.table
      : document.querySelector(tableSelector);
    let features = options.features != undefined
      ? options.features
      : await table.getSortedFeatures();
    let columns = options.columns != undefined
      ? options.columns
      : Array.from(table.querySelectorAll("gl-table-column"));
    if (options.format === "csv")
      this.exportCsv(table, features, columns, options);
    if (options.format === "pdf")
      this.exportPdf(table, features, columns, options);
  }
  /**
   * Exports the contents of the table as a Csv file
   * @param table
   * @param features
   * @param columns
   * @param options
   */
  async exportCsv(table, features, columns, options) {
    let csv = await this.createCsvDoc(table, features, columns);
    fileDownload(csv, this.getFilename(options), "text/csv");
  }
  /**
   * Exports the contents of the table as a Pdf file
   * @param table
   * @param features
   * @param columns
   * @param options
   */
  async exportPdf(table, features, columns, options) {
    let dd = await this.createDocDef(table, features, columns, options);
    if (options.url != undefined) {
      fetchPdf(options.url, options.filename, dd);
    }
    else {
      pdfMake
        .createPdf(dd, undefined, pdfFonts)
        .download(this.getFilename(options));
    }
  }
  getFilename(options) {
    if (options.filename != undefined)
      return options.filename;
    if (options.pageTitle == undefined)
      return `table.${options.format}`;
    return `${options.pageTitle.toLowerCase().replace(/[^a-z0-9]+/g, "_")}.${options.format}`;
  }
  async createCsvDoc(table, features, columns) {
    let filteredColumns = columns.filter((col) => col.visible && col.csv);
    let headerRow = filteredColumns.map((col) => csvQuote(col.label));
    let featureRows = (await Promise.all(features.map((feature) => this.getTableRow(table, feature, filteredColumns, "text")))).map((row) => row.map((cell) => csvQuote(cell)));
    return [headerRow, ...featureRows].map((row) => row.join(",")).join("\n");
  }
  getTableRow(table, feature, columns, type = "pdf") {
    return Promise.all(columns.map((column) => table.getCellContents(feature, column, type)));
  }
  async createDocDef(table, features, columns, options) {
    let filteredColumns = columns.filter((col) => col.visible && col.pdf);
    let header = filteredColumns.map((col) => {
      return { text: col.label, style: "th" };
    });
    let featureRows = await Promise.all(features.map((feature) => this.getTableRow(table, feature, filteredColumns)));
    let formattedRows = featureRows.map((row, i) => {
      return row.map((cell) => {
        return {
          text: cell,
          style: i % 2 == 0 ? "td-zebra" : "td",
        };
      });
    });
    let docDef = {
      info: {},
      pageOrientation: options.pageOrientation,
      content: [
        {
          table: {
            headerRows: 1,
            body: [header, ...formattedRows],
          },
        },
      ],
    };
    if (options.pageSubtitle != undefined)
      docDef["content"].unshift({
        text: options.pageSubtitle,
        style: "h2",
        alignment: "center",
      });
    if (options.pageTitle != undefined) {
      docDef["info"]["title"] = options.pageTitle;
      docDef["content"].unshift({
        text: options.pageTitle,
        style: "h1-title",
        alignment: "center",
      });
    }
    if (options.author != undefined)
      docDef["info"]["author"] = options.author;
    return docDef;
  }
  static get is() { return "gl-table-export-controller"; }
  static get methods() {
    return {
      "create": {
        "complexType": {
          "signature": "(options: TableExportOptions) => Promise<void>",
          "parameters": [{
              "tags": [{
                  "name": "param",
                  "text": "options"
                }],
              "text": ""
            }],
          "references": {
            "Promise": {
              "location": "global",
              "id": "global::Promise"
            },
            "TableExportOptions": {
              "location": "import",
              "path": "./interfaces",
              "id": "src/components/table-export-controller/interfaces.tsx::TableExportOptions"
            },
            "HTMLGlTableElement": {
              "location": "global",
              "id": "global::HTMLGlTableElement"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Exports the table specified by options",
          "tags": [{
              "name": "param",
              "text": "options"
            }]
        }
      }
    };
  }
}
//# sourceMappingURL=table-export-controller.js.map
