import { default as fileDownload } from 'js-file-download';
function csvQuote(value) {
    if (!value)
        return '';
    return (value.indexOf(',') !== -1) ?
        `"${value.replace(/"/g, '""')}"` : value;
}
export class TableExportController {
    async create(options) {
        let tableSelector = 'gl-table' +
            ((options.tableId) ? `#${options.tableId}` : '');
        let table = (options.table) ? options.table :
            document.querySelector(tableSelector);
        let features = (options.features) ? options.features :
            await table.getSortedFeatures();
        let columns = (options.columns) ? 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);
    }
    async exportCsv(table, features, columns, options) {
        let csv = await this.createCsvDoc(table, features, columns);
        fileDownload(csv, this.getFilename(options), 'text/csv');
    }
    async exportPdf(table, features, columns, options) {
        pdfMake.createPdf(await this.createDocDef(table, features, columns, options)).download(this.getFilename(options));
    }
    getFilename(options) {
        if (options.filename)
            return options.filename;
        if (!options.pageTitle)
            return `table.${options.format}`;
        return `${options.pageTitle.toLowerCase()
            .replace(/[^a-z0-9]+/g, '_')}.${options.format}`;
    }
    zebraFill(i) {
        if (i === 0)
            return 'black';
        return (i % 2 === 0) ? '#ECEBEB' : null;
    }
    async createCsvDoc(table, features, columns) {
        let filteredColumns = columns.filter(col => col.visible);
        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);
        let header = filteredColumns.map((col) => {
            return { text: col.label, style: 'tableHeader' };
        });
        let featureRows = await Promise.all(features.map((feature) => this.getTableRow(table, feature, filteredColumns)));
        let docDef = {
            info: {},
            pageOrientation: options.pageOrientation,
            content: [
                {
                    table: {
                        headerRows: 1,
                        body: [header, ...featureRows]
                    },
                    style: 'table',
                    layout: {
                        fillColor: this.zebraFill
                    }
                },
            ],
            styles: {
                tableHeader: {
                    color: 'white'
                },
                header: {
                    fontSize: 15,
                    bold: true,
                    margin: [0, 0, 0, 5]
                },
                subHeader: {
                    margin: [0, 5, 0, 15]
                }
            },
        };
        if (options.pageSubtitle)
            docDef['content'].unshift({ text: options.pageSubtitle, style: 'subHeader', alignment: 'center' });
        if (options.pageTitle) {
            docDef['info']['title'] = options.pageTitle;
            docDef['content'].unshift({ text: options.pageTitle, style: 'header', alignment: 'center' });
        }
        if (options.author)
            docDef['info']['author'] = options.author;
        return docDef;
    }
    static get is() { return "gl-table-export-controller"; }
    static get properties() { return {
        "create": {
            "method": true
        }
    }; }
}
