import { RxapOpenApiDataSourceError } from '@rxap/open-api/data-source';
import { AbstractTableDataSource, RXAP_TABLE_DATA_SOURCE, RXAP_TABLE_DATA_SOURCE_PAGINATOR, RXAP_TABLE_DATA_SOURCE_SORT, RXAP_TABLE_DATA_SOURCE_FILTER, RXAP_TABLE_DATA_SOURCE_PARAMETERS, RxapAbstractTableDataSource } from '@rxap/data-source/table';
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Inject, Optional, Pipe, NgModule } from '@angular/core';
import { RXAP_DATA_SOURCE_METADATA } from '@rxap/data-source';
import * as i1 from 'rxjs';
import { EMPTY, combineLatest, of, isObservable } from 'rxjs';
import { startWith, tap, filter, map, switchMap } from 'rxjs/operators';
import { isPromise } from '@rxap/utilities';

class RxapOpenApiDataSourceTableError extends RxapOpenApiDataSourceError {
    constructor(message, code, scope) {
        super(message, code, scope);
        this.addSubPackageName('table');
    }
}

const RXAP_OPEN_API_TABLE_DATA_SOURCE_TO_PARAMETERS_FUNCTION = new InjectionToken('rxap/open-api/data-source/table/to-parameters-function');

class OpenApiTableDataSource extends AbstractTableDataSource {
    constructor(dataSource, paginator = null, tableEventToOpenApiParameters = null, sort = null, filter = null, parameters = null, metadata = dataSource.metadata) {
        super(paginator, sort, filter, parameters, metadata);
        this.dataSource = dataSource;
        if (tableEventToOpenApiParameters) {
            this.tableEventToOpenApiParameters = tableEventToOpenApiParameters;
        }
    }
    tableEventToOpenApiParameters(event) {
        return {
            page: event.page.pageIndex,
            size: event.page.pageSize,
            sortBy: event.sort?.active,
            direction: event.sort?.direction,
            filter: event.filter,
        };
    }
    _connect(viewer) {
        this.assertPaginator();
        if (viewer.viewChange && viewer.viewChange !== EMPTY) {
            console.warn('The viewChange property is readonly');
        }
        if (this.paginator === undefined || this.paginator.page === undefined) {
            throw new RxapOpenApiDataSourceTableError('The paginator instance has not a page property', '');
        }
        viewer.viewChange = combineLatest([
            this.paginator.page.pipe(startWith({
                pageIndex: this.paginator.pageIndex,
                pageSize: this.paginator.pageSize,
                length: this.paginator.length,
            }), tap((page) => {
                if (typeof page.pageSize !== 'number') {
                    console.warn('The page size is not defined!');
                }
            }), filter((page) => typeof page.pageSize === 'number')),
            this.sort?.sortChange?.pipe(startWith({
                active: this.sort?.active,
                direction: this.sort?.direction,
            })) ?? of(null),
            this.filter?.change ?? of(null),
        ]).pipe(map(([page, sort, filter]) => ({
            page,
            sort,
            filter,
        })), switchMap((event) => {
            const options = this.tableEventToOpenApiParameters(event);
            if (isPromise(options) || isObservable(options)) {
                return options;
            }
            return of(options);
        }));
        return [
            this.dataSource.connect(viewer).pipe(tap((paginationData) => {
                if (typeof paginationData !== 'object') {
                    throw new RxapOpenApiDataSourceTableError('The open api data source does not return a PaginationData object. Value is not an object', '');
                }
                if (!paginationData.hasOwnProperty('total')) {
                    throw new RxapOpenApiDataSourceTableError('The open api data source does not return a PaginationData object. Object has not the property total', '');
                }
                if (!paginationData.hasOwnProperty('data') &&
                    !Array.isArray(paginationData.data)) {
                    throw new RxapOpenApiDataSourceTableError('The open api data source does not return a PaginationData object. Object has not the property data' +
                        ' property of the value not an array', '');
                }
                if (paginationData.size !== undefined &&
                    paginationData.size !== this.paginator.pageSize) {
                    console.warn('The selected page size from the paginator is not equal to the page size from the PaginationData object');
                }
                if (paginationData.page !== undefined &&
                    paginationData.page !== this.paginator.pageIndex) {
                    console.warn('The selected page index from the paginator is not equal to the page index from the PaginationData object');
                }
            }), tap((paginationData) => this.updateTotalLength(paginationData.total)), map((paginationData) => paginationData.data)),
            () => this.dataSource.disconnect(viewer),
        ];
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: OpenApiTableDataSource, deps: [{ token: RXAP_TABLE_DATA_SOURCE }, { token: RXAP_TABLE_DATA_SOURCE_PAGINATOR, optional: true }, { token: RXAP_OPEN_API_TABLE_DATA_SOURCE_TO_PARAMETERS_FUNCTION, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_SORT, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_FILTER, optional: true }, { token: RXAP_TABLE_DATA_SOURCE_PARAMETERS, optional: true }, { token: RXAP_DATA_SOURCE_METADATA, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: OpenApiTableDataSource }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: OpenApiTableDataSource, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Inject,
                    args: [RXAP_TABLE_DATA_SOURCE]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_TABLE_DATA_SOURCE_PAGINATOR]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_OPEN_API_TABLE_DATA_SOURCE_TO_PARAMETERS_FUNCTION]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_TABLE_DATA_SOURCE_SORT]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_TABLE_DATA_SOURCE_FILTER]
                }] }, { type: i1.Observable, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_TABLE_DATA_SOURCE_PARAMETERS]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_DATA_SOURCE_METADATA]
                }] }] });
function RxapOpenApiTableDataSource(metadata, className = 'OpenApiTableDataSource', packageName = '@rxap/open-api/data-source/table') {
    return function (target) {
        RxapAbstractTableDataSource(metadata, className, packageName)(target);
    };
}

class ToOpenApiTableDataSourcePipe {
    transform(dataSource, paginator, tableEventToOpenApiParameters, sort, filter) {
        return new OpenApiTableDataSource(dataSource, paginator, tableEventToOpenApiParameters, sort, filter);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ToOpenApiTableDataSourcePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: ToOpenApiTableDataSourcePipe, isStandalone: false, name: "toOpenApiTableDataSource" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ToOpenApiTableDataSourcePipe, decorators: [{
            type: Pipe,
            args: [{
                    name: 'toOpenApiTableDataSource',
                    standalone: false
                }]
        }] });
class ToOpenApiTableDataSourcePipeModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ToOpenApiTableDataSourcePipeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: ToOpenApiTableDataSourcePipeModule, declarations: [ToOpenApiTableDataSourcePipe], exports: [ToOpenApiTableDataSourcePipe] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ToOpenApiTableDataSourcePipeModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ToOpenApiTableDataSourcePipeModule, decorators: [{
            type: NgModule,
            args: [{
                    exports: [ToOpenApiTableDataSourcePipe],
                    declarations: [ToOpenApiTableDataSourcePipe],
                }]
        }] });

// region 
// endregion

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

export { OpenApiTableDataSource, RXAP_OPEN_API_TABLE_DATA_SOURCE_TO_PARAMETERS_FUNCTION, RxapOpenApiDataSourceTableError, RxapOpenApiTableDataSource, ToOpenApiTableDataSourcePipe, ToOpenApiTableDataSourcePipeModule };
//# sourceMappingURL=rxap-open-api-data-source-table.mjs.map
