import { RxapHttpDataSourceError } from '@rxap/data-source/http';
import * as i0 from '@angular/core';
import { InjectionToken, Injectable, Inject, Optional, Pipe } from '@angular/core';
import { RXAP_DATA_SOURCE_METADATA } from '@rxap/data-source';
import { RxapHttpPaginationDataSourceError } from '@rxap/data-source/http/pagination';
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 { isPromise } from '@rxap/utilities';
import * as i1 from 'rxjs';
import { EMPTY, combineLatest, of, isObservable } from 'rxjs';
import { startWith, tap, filter, map, switchMap } from 'rxjs/operators';

class RxapHttpTableDataSourceError extends RxapHttpDataSourceError {
    constructor(message, code, className) {
        super(message, code, className);
        this.addSubPackageName('table');
    }
}

const RXAP_HTTP_TABLE_DATA_SOURCE_TO_OPTIONS_FUNCTION = new InjectionToken('rxap/data-source/http/table/to-options');

class HttpTableDataSource extends AbstractTableDataSource {
    constructor(dataSource, paginator = null, tableEventToHttpOptions = null, sort = null, filter = null, parameters = null, metadata = dataSource.metadata) {
        super(paginator, sort, filter, parameters, metadata);
        this.dataSource = dataSource;
        if (tableEventToHttpOptions) {
            this.tableEventToHttpOptions = tableEventToHttpOptions;
        }
    }
    tableEventToHttpOptions(event) {
        throw new RxapHttpTableDataSourceError('The TableEventToHttpOptionsFunction is not defined', '');
    }
    _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 RxapHttpTableDataSourceError('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]) => ({
            start: page ? page.pageSize * page.pageIndex : 0,
            end: page ? page.pageSize * page.pageIndex + page.pageSize : Number.MAX_SAFE_INTEGER,
            page,
            sort,
            filter,
        })), switchMap((event) => {
            const options = this.tableEventToHttpOptions(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 RxapHttpPaginationDataSourceError('The http data source does not return a PaginationData object. Value is not an object', '');
                }
                if (paginationData['total'] === undefined || paginationData['total'] === null) {
                    throw new RxapHttpPaginationDataSourceError('The http data source does not return a PaginationData object. Object has not the property total', '');
                }
                if (!paginationData['data'] &&
                    !Array.isArray(paginationData['data'])) {
                    throw new RxapHttpPaginationDataSourceError('The http 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.0.3", ngImport: i0, type: HttpTableDataSource, deps: [{ token: RXAP_TABLE_DATA_SOURCE }, { token: RXAP_TABLE_DATA_SOURCE_PAGINATOR, optional: true }, { token: RXAP_HTTP_TABLE_DATA_SOURCE_TO_OPTIONS_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.0.3", ngImport: i0, type: HttpTableDataSource }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: HttpTableDataSource, 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_HTTP_TABLE_DATA_SOURCE_TO_OPTIONS_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 RxapHttpTableDataSource(metadata, className = 'HttpTableDataSource', packageName = '@rxap/data-source/http/table') {
    return function (target) {
        RxapAbstractTableDataSource(metadata, className, packageName)(target);
    };
}

class ToHttpTableDataSourcePipe {
    transform(dataSource, paginator, tableEventToHttpOptions, sort, filter) {
        return new HttpTableDataSource(dataSource, paginator, tableEventToHttpOptions, sort, filter);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: ToHttpTableDataSourcePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: ToHttpTableDataSourcePipe, isStandalone: true, name: "toHttpTableDataSource" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: ToHttpTableDataSourcePipe, decorators: [{
            type: Pipe,
            args: [{
                    name: 'toHttpTableDataSource',
                    standalone: true,
                }]
        }] });

// region 
// endregion

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

export { HttpTableDataSource, RXAP_HTTP_TABLE_DATA_SOURCE_TO_OPTIONS_FUNCTION, RxapHttpTableDataSource, RxapHttpTableDataSourceError, ToHttpTableDataSourcePipe };
//# sourceMappingURL=rxap-data-source-http-table.mjs.map
