import * as i0 from '@angular/core';
import { Injectable, NgModule, Optional } from '@angular/core';
import * as i1 from '@angular-ru/cdk/webworker';
import { WebWorkerThreadService } from '@angular-ru/cdk/webworker';
import { __awaiter } from 'tslib';
import { copyHtml, isNotNil } from '@angular-ru/cdk/utils';
import { of, firstValueFrom } from 'rxjs';
import * as i3 from '@ngx-translate/core';

class PlainTableComposerService {
    constructor(webWorker) {
        this.webWorker = webWorker;
    }
    composeSingle(entry, keyRules) {
        return __awaiter(this, void 0, void 0, function* () {
            const [composed] = yield this.compose([entry], keyRules);
            return composed !== null && composed !== void 0 ? composed : {};
        });
    }
    // eslint-disable-next-line max-lines-per-function
    compose(tableEntries, keyRules) {
        return (this.webWorker
            // eslint-disable-next-line max-lines-per-function,sonarjs/cognitive-complexity
            .run(
        // eslint-disable-next-line sonarjs/cognitive-complexity,max-lines-per-function
        (input) => {
            class PlainComposer {
                constructor(rules) {
                    this.rules = rules;
                    this.keySet = new Set();
                }
                static isObject(value) {
                    return typeof value === 'object' && value !== null;
                }
                toPlain(rawEntries) {
                    var _a, _b;
                    this.keySet.clear();
                    const flatEntries = rawEntries.map((entry) => this.flattenAndClean(entry));
                    const keys = (_b = (_a = this.rules) === null || _a === void 0 ? void 0 : _a.includeKeys) !== null && _b !== void 0 ? _b : Array.from(this.keySet);
                    return flatEntries.map((entry) => this.pickKeys(entry, keys));
                }
                flattenAndClean(objectRef, keyPrefix = '') {
                    const depthGraph = {};
                    const keys = Object.keys(objectRef);
                    for (const key of keys) {
                        const path = keyPrefix ? `${keyPrefix}.${key}` : key;
                        if (this.passesBlacklist(path)) {
                            if (PlainComposer.isObject(objectRef[key])) {
                                const childKeys = this.flattenAndClean(objectRef[key], path);
                                Object.assign(depthGraph, childKeys);
                            }
                            else {
                                this.keySet.add(path);
                                depthGraph[path] = objectRef[key];
                            }
                        }
                    }
                    return depthGraph;
                }
                pickKeys(source, keys) {
                    return keys.reduce((collected, key) => {
                        collected[key] = source[key];
                        return collected;
                    }, {});
                }
                passesBlacklist(key) {
                    var _a;
                    if ((_a = this.rules) === null || _a === void 0 ? void 0 : _a.excludeKeys) {
                        return !this.rules.excludeKeys.includes(key);
                    }
                    else {
                        return true;
                    }
                }
            }
            return new PlainComposer(input.rules).toPlain(input.entries);
        }, { rules: keyRules, entries: tableEntries }));
    }
}
/** @nocollapse */ PlainTableComposerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PlainTableComposerService, deps: [{ token: i1.WebWorkerThreadService }], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ PlainTableComposerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PlainTableComposerService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PlainTableComposerService, decorators: [{
            type: Injectable
        }], ctorParameters: function () { return [{ type: i1.WebWorkerThreadService }]; } });

class PlainTableComposerModule {
    static forRoot() {
        return {
            ngModule: PlainTableComposerModule,
            providers: [PlainTableComposerService]
        };
    }
}
/** @nocollapse */ PlainTableComposerModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PlainTableComposerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
/** @nocollapse */ PlainTableComposerModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PlainTableComposerModule });
/** @nocollapse */ PlainTableComposerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PlainTableComposerModule, providers: [WebWorkerThreadService] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: PlainTableComposerModule, decorators: [{
            type: NgModule,
            args: [{
                    providers: [WebWorkerThreadService]
                }]
        }] });

class TableClipboardService {
    constructor(plainTableComposer, webWorker, translate) {
        this.plainTableComposer = plainTableComposer;
        this.webWorker = webWorker;
        this.translate = translate;
    }
    // eslint-disable-next-line max-lines-per-function
    generateTableAndCopy(request) {
        var _a;
        return __awaiter(this, void 0, void 0, function* () {
            const preparedRequest = Object.assign(Object.assign({}, request), { entries: yield this.plainTableComposer.compose(request.entries, request.rules), translationMap: (_a = request.translationMap) !== null && _a !== void 0 ? _a : (yield this.getTranslationMap()) });
            return (this.webWorker
                // eslint-disable-next-line max-lines-per-function
                .run((input) => {
                function isEmptyValue(value) {
                    const nextValue = typeof value === 'string' ? value.trim() : value;
                    return [undefined, null, NaN, '', Infinity].includes(nextValue);
                }
                function isFilledString(value) {
                    return typeof value === 'string' && value.length > 0;
                }
                class PlainTableBuilder {
                    constructor(translationMap, translationPrefix, stub = '-') {
                        this.translationMap = translationMap;
                        this.translationPrefix = translationPrefix;
                        this.stub = stub;
                    }
                    generateTable(entities) {
                        const firstEntry = entities[0];
                        if (firstEntry) {
                            const keys = Object.keys(firstEntry);
                            const htmlHeader = this.generateHeaderRow(keys);
                            const htmlBody = entities
                                .map((object) => this.generateBodyRow(object, keys))
                                .join('');
                            return `<html><body><table border="1" cellspacing="0"><tbody>${htmlHeader}${htmlBody}</tbody></table></body></html>`;
                        }
                        else {
                            return '';
                        }
                    }
                    generateHeaderRow(keys) {
                        const htmlCells = keys.map((key) => this.generateHeaderCell(key));
                        return `<tr>${htmlCells.join('')}</tr>`;
                    }
                    generateBodyRow(entity, keys) {
                        const htmlCells = keys.map((key) => this.generateBodyCell(entity[key]));
                        return `<tr>${htmlCells.join('')}</tr>`;
                    }
                    generateHeaderCell(key) {
                        const cellValue = this.getTranslatedTitle(key);
                        return `<th>${cellValue}</th>`;
                    }
                    generateBodyCell(value) {
                        const cellValue = isEmptyValue(value) ? this.stub : value;
                        return `<td>${cellValue}</td>`;
                    }
                    getTranslatedTitle(key) {
                        var _a, _b;
                        const translatePath = isFilledString(this.translationPrefix)
                            ? `${this.translationPrefix}.${key}`
                            : key;
                        return (_b = (_a = this.translationMap) === null || _a === void 0 ? void 0 : _a[translatePath]) !== null && _b !== void 0 ? _b : key;
                    }
                }
                const { translationMap, translationPrefix, entries } = input;
                return new PlainTableBuilder(translationMap, translationPrefix).generateTable(entries);
            }, preparedRequest)
                .then(copyHtml));
        });
    }
    getTranslationMap() {
        var _a;
        return __awaiter(this, void 0, void 0, function* () {
            const lang = (_a = this.translate.currentLang) !== null && _a !== void 0 ? _a : this.translate.defaultLang;
            const translationMap$ = isNotNil(lang) ? this.translate.getTranslation(lang) : of({});
            return firstValueFrom(translationMap$).then((map) => this.plainTableComposer.composeSingle(map));
        });
    }
}
/** @nocollapse */ TableClipboardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: TableClipboardService, deps: [{ token: PlainTableComposerService }, { token: i1.WebWorkerThreadService }, { token: i3.TranslateService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ TableClipboardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: TableClipboardService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: TableClipboardService, decorators: [{
            type: Injectable
        }], ctorParameters: function () {
        return [{ type: PlainTableComposerService }, { type: i1.WebWorkerThreadService }, { type: i3.TranslateService, decorators: [{
                        type: Optional
                    }] }];
    } });

class TableClipboardModule {
}
/** @nocollapse */ TableClipboardModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: TableClipboardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
/** @nocollapse */ TableClipboardModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: TableClipboardModule, imports: [PlainTableComposerModule] });
/** @nocollapse */ TableClipboardModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: TableClipboardModule, providers: [WebWorkerThreadService, TableClipboardService], imports: [[PlainTableComposerModule.forRoot()]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: TableClipboardModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [PlainTableComposerModule.forRoot()],
                    providers: [WebWorkerThreadService, TableClipboardService]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { PlainTableComposerModule, PlainTableComposerService, TableClipboardModule, TableClipboardService };
//# sourceMappingURL=angular-ru-cdk-table-utils.mjs.map
