import { TFactoryConstructor } from "../../../types";
import {
    IResourceEntity,
    IResourceFactory,
    IResourcePagination
} from "../../../interfaces/api";
import { IRequestOptions } from "../../../interfaces/common";
import { CatalogElementCriteria } from "../../../interfaces/catalog";
import { ICatalogElement } from "../../models/CatalogElement";
import { CatalogElementFactory } from "../CatalogElementFactory";
import ResourcePagination from "../../ResourcePagination";


export interface IHasCatalogElementsFactory<T extends IResourceEntity<IResourceFactory<ICatalogElement>>> extends IResourceFactory<ICatalogElement> {
    elements(identity: number, criteria?: Partial<CatalogElementCriteria>, options?: IRequestOptions): Promise<IResourcePagination<ICatalogElement>>;
}

export function hasCatalogElements<T extends IResourceEntity<IResourceFactory<T>>>(Base: TFactoryConstructor<T>): TFactoryConstructor<T> {
    return class HasCatalogElements extends Base {
        async elements(identity: number, criteria?: CatalogElementCriteria, options?: IRequestOptions): Promise<IResourcePagination<ICatalogElement>> {
            const url = this.getUrl('/' + identity + '/elements');
            const request = this.getRequest();

            const factory = new CatalogElementFactory(request);

            const params = {
                url,
                criteria,
                options,
                factory: factory,
                embedded: factory.getEmbeddedKey()
            };
            const pagination = new ResourcePagination<ICatalogElement>(this.getRequest(), params);
            await pagination.fetch();


            return pagination;
        }
    };
}