import { makeRoomPageIntent } from "../../api/intents/room-page-intent";
import * as models from "../../api/models";
import * as mediaDataFetching from "../../foundation/media/data-fetching";
import { AbstractMediaApiPageBuilder } from "../builders/abstract-media-api-page-builder";
import * as pagination from "../builders/pagination";
import * as metricsHelpersLocation from "../metrics/helpers/location";
import * as metricsHelpersPage from "../metrics/helpers/page";
import { generateRoutes } from "../util/generate-routes";
import { defaultAttributesForRoomRequest } from "./room-request";
import { withAsyncValidationContext } from "../../foundation/util/validation-util";
import { defaultRoomShelfContentType, roomPageWithContent } from "./room-page";
export class RoomPageToken {
    constructor() {
        /// The store platform data profile to use.
        this.profile = "lockup";
        /// The maximum number of ids to fetch per load more request.
        this.maxPerPage = pagination.suggestedMaxPerPage;
    }
}
export class AbstractRoomBuilder extends AbstractMediaApiPageBuilder {
    //
    // Begin Region: Common
    //
    defaultAttributes(objectGraph) {
        return defaultAttributesForRoomRequest(objectGraph);
    }
    defaultPlatforms(objectGraph) {
        return mediaDataFetching.defaultAdditionalPlatformsForClient(objectGraph);
    }
    pageType() {
        return "page";
    }
    //
    // Begin Region: Load More
    //
    generatePaginationRequest(objectGraph, url, parameters, token) {
        const pageToken = token;
        const mediaApiRequest = new mediaDataFetching.Request(objectGraph, pageToken.remainingContent);
        return mediaApiRequest;
    }
    async renderPaginatedPage(objectGraph, data, token) {
        const pageToken = token;
        return await this.pageWithContent(objectGraph, data, pageToken);
    }
    //
    // Begin Region: Internal API
    //
    /**
     * Generates a room page given a list of lockups
     *
     * @param {DataContainer} roomContents
     * @param {RoomPageToken} token The token representing the content to load
     * @param {boolean} shouldUpdateRemainingContent Whether to update the remaining content in the token,
     * false when being handled outside of this method
     * @returns {GenericPage}
     */
    async pageWithContent(objectGraph, roomContents, token, shouldUpdateRemainingContent = true) {
        return await withAsyncValidationContext("pageWithContent", async () => {
            return roomPageWithContent(objectGraph, roomContents, token, shouldUpdateRemainingContent);
        });
    }
}
/**
 * Creates a page that can be used for side-packing see all pages into a room.
 *
 * @param objectGraph
 * @param {string} title The title of the destination page
 * @param {ShelfContentType} preferredShelfContentType The content type to use for the page
 * @returns {GenericPage} A GenericPage which will use the parentShelfItems from the see all to render the initial room
 */
export function seeAllPage(objectGraph, title, preferredShelfContentType) {
    const shelf = new models.Shelf(preferredShelfContentType || defaultRoomShelfContentType);
    shelf.isHorizontal = false;
    shelf.items = "parentShelfItems";
    const page = new models.GenericPage([shelf]);
    page.isIncomplete = true;
    page.title = title;
    if (platformPrefersLargeTitles(objectGraph)) {
        page.presentationOptions = ["prefersLargeTitle"];
    }
    return page;
}
export function platformPrefersLargeTitles(objectGraph) {
    return objectGraph.client.isWatch || objectGraph.client.isMac;
}
export class AbstractActionRoomBuilder extends AbstractRoomBuilder {
    async handlePage(objectGraph, url, parameters, matchedRuleIdentifier, referrerData, isIncomingURL) {
        return this.action();
    }
    generatePageRequest(objectGraph, url, parameters) {
        throw new Error(`generatePageRequest is not supported on: ${this.builderClass}`);
    }
    async renderPage(objectGraph, data, parameters, additionalPageRequirements) {
        throw new Error(`renderPage is not supported on: ${this.builderClass}`);
    }
}
export class AbstractFilteredRoom extends AbstractRoomBuilder {
    requestWithFilter(objectGraph, type, value) {
        const mediaApiRequest = new mediaDataFetching.Request(objectGraph)
            .forType("apps")
            .includingMacOSCompatibleIOSAppsWhenSupported(true)
            .withFilter(type, value);
        return mediaApiRequest;
    }
    async renderPage(objectGraph, data, parameters, additionalPageRequirements) {
        return await withAsyncValidationContext("renderPage", async () => {
            // Create the token
            const token = new RoomPageToken();
            token.url = this.paginationUrl;
            token.metricsPageInformation = this.pageInformation(objectGraph, data, parameters);
            token.shouldFilter = false;
            token.metricsLocationTracker = metricsHelpersLocation.newLocationTracker();
            const page = await this.pageWithContent(objectGraph, data, token);
            metricsHelpersPage.addMetricsEventsToPageWithInformation(objectGraph, page, token.metricsPageInformation);
            return page;
        });
    }
}
/// MARK: `RoomPageIntentController` Routing
const { routes: roomPageRoutesWithoutPlatform, makeCanonicalUrl: makeCanonicalRoomPageUrlWithoutPlatform } = generateRoutes(makeRoomPageIntent, "/room/{id}");
const { routes: roomPageRoutesWithPlatform, makeCanonicalUrl: makeCanonicalRoomPageUrlWithPlatform } = generateRoutes(makeRoomPageIntent, "/{platform}/room/{id}");
/**
 * Define the `RouteProvider` routes for the `RoomPageIntentController`
 */
export function roomPageRoutes(objectGraph) {
    return [...roomPageRoutesWithoutPlatform(objectGraph), ...roomPageRoutesWithPlatform(objectGraph)];
}
/**
 * Generate the URL used by the "web" client to route to a {@linkcode RoomPageIntent}
 */
export function makeCanonicalRoomPageUrl(objectGraph, intent) {
    if ("platform" in intent) {
        return makeCanonicalRoomPageUrlWithPlatform(objectGraph, intent);
    }
    else {
        return makeCanonicalRoomPageUrlWithoutPlatform(objectGraph, intent);
    }
}
//# sourceMappingURL=room-common.js.map