import * as i1 from '@rxap/data-source';
import { RxapDataSourceError, BaseDataSource, RXAP_DATA_SOURCE_METADATA, RxapDataSource } from '@rxap/data-source';
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Optional, Inject } from '@angular/core';
import { IsRequiredPropertyDefined } from '@rxap/utilities';
import { tap, switchMap, startWith, map } from 'rxjs/operators';

const RXAP_PAGINATION_DATA_SOURCE = new InjectionToken('@rxap/data-source/pagination/source');
const RXAP_PAGINATION_DATA_SOURCE_PAGINATOR = new InjectionToken('@rxap/data-source/pagination/paginator');

class RxapPaginationDataSourceError extends RxapDataSourceError {
    constructor(message, code, className) {
        super(message, code, className);
        this.addSubPackageName('pagination');
    }
}

class AbstractPaginationDataSource extends BaseDataSource {
    constructor(paginator = null, metadata = null) {
        super(metadata);
        this._totalLength = 0;
        if (paginator) {
            this.paginator = paginator;
        }
    }
    get pageIndex() {
        return this.paginator?.pageIndex ?? 0;
    }
    get pageSize() {
        return this.paginator?.pageSize ?? this.totalLength;
    }
    get totalLength() {
        return this._totalLength;
    }
    updateTotalLength(totalLength) {
        if (this.paginator && this.paginator.length !== totalLength) {
            this.paginator.length = totalLength;
        }
        this._totalLength = totalLength;
    }
    assertPaginator() {
        if (!IsRequiredPropertyDefined(this, 'paginator')) {
            throw new RxapPaginationDataSourceError('The paginator instance is not defined!', '');
        }
    }
    applyPagination(data, pageSize, pageIndex) {
        return data.slice(pageSize * pageIndex, pageSize * pageIndex + pageSize);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AbstractPaginationDataSource, deps: [{ token: RXAP_PAGINATION_DATA_SOURCE_PAGINATOR, optional: true }, { token: RXAP_DATA_SOURCE_METADATA, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AbstractPaginationDataSource }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AbstractPaginationDataSource, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_PAGINATION_DATA_SOURCE_PAGINATOR]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_DATA_SOURCE_METADATA]
                }] }] });
function RxapAbstractPaginationDataSource(metadataOrId, className = 'AbstractPaginationDataSource', packageName = '@rxap/data-source/pagination') {
    return function (target) {
        RxapDataSource(metadataOrId, className, packageName)(target);
    };
}

class PaginationDataSource extends AbstractPaginationDataSource {
    constructor(dataSource, paginator = null, metadata = dataSource.metadata) {
        super(paginator, metadata);
        this.dataSource = dataSource;
    }
    refresh() {
        this.dataSource.refresh();
    }
    _connect(viewer) {
        this.assertPaginator();
        return [
            this.dataSource.connect(viewer).pipe(tap(data => this.updateTotalLength(data.length)), switchMap(data => {
                if (!Array.isArray(data)) {
                    throw new RxapPaginationDataSourceError('The source data source must be a collection data source', '');
                }
                this.assertPaginator();
                if (this.paginator && this.paginator.page) {
                    return this.paginator.page.pipe(startWith({
                        pageIndex: this.paginator.pageIndex,
                        pageSize: this.paginator.pageSize,
                        length: this.paginator.length,
                    }), map(page => this.applyPagination(data, page.pageSize, page.pageIndex)));
                }
                throw new Error('The paginator have not a defined page property!');
            })),
            () => this.dataSource.disconnect(viewer),
        ];
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: PaginationDataSource, deps: [{ token: RXAP_PAGINATION_DATA_SOURCE }, { token: RXAP_PAGINATION_DATA_SOURCE_PAGINATOR, optional: true }, { token: RXAP_DATA_SOURCE_METADATA, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: PaginationDataSource }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: PaginationDataSource, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.BaseDataSource, decorators: [{
                    type: Inject,
                    args: [RXAP_PAGINATION_DATA_SOURCE]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_PAGINATION_DATA_SOURCE_PAGINATOR]
                }] }, { type: undefined, decorators: [{
                    type: Optional
                }, {
                    type: Inject,
                    args: [RXAP_DATA_SOURCE_METADATA]
                }] }] });
function RxapPaginationDataSource(metadataOrId, className = 'PaginationDataSource', packageName = '@rxap/data-source/pagination') {
    return function (target) {
        RxapDataSource(metadataOrId, className, packageName)(target);
    };
}

// region 
// endregion

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

export { AbstractPaginationDataSource, PaginationDataSource, RXAP_PAGINATION_DATA_SOURCE, RXAP_PAGINATION_DATA_SOURCE_PAGINATOR, RxapAbstractPaginationDataSource, RxapPaginationDataSource, RxapPaginationDataSourceError };
//# sourceMappingURL=rxap-data-source-pagination.mjs.map
