import { isNothing } from "@jet/environment";
import * as models from "../../api/models";
import { FetchTimingMetricsBuilder } from "@jet/environment/metrics/fetch-timing-metrics-builder";
import { injectSEOData } from "../../api/models/web-renderable-page";
import { AbstractPageBuilder } from "../../common/builders/abstract-page-builder";
import * as search from "../../common/search/search";
import { makeCanonicalSearchResultsPageUrl, searchResultsPageRoutes } from "../../common/search/search-page-url";
import * as searchResultsFetching from "../../common/search/search-results-fetching";
import { injectWebNavigation } from "../../common/web-navigation/inject-web-navigation";
import { replacePlatformSelectorDestinationWithSearchResults } from "../../common/web-navigation/search-results-platform-selection";
import { withActiveIntent } from "../../foundation/dependencies/active-intent";
import { validateNeedsVisionRestriction } from "../../foundation/media/util";
/** Handles `SearchResultsIntent` to fetch the search results. This is for shelves v1. */
export class SearchResultsIntentController {
    constructor() {
        this.$intentKind = "SearchResultsIntent";
    }
    async perform(intent, objectGraph) {
        return await fetchSearchResults(objectGraph, intent.requestDescriptor);
    }
}
/** Handles `SearchResultsMoreIntent` to fetch more of the search results. This is for shelves v1. */
export class SearchResultsMoreIntentController {
    constructor() {
        this.$intentKind = "SearchResultsMoreIntent";
    }
    async perform(intent, objectGraph) {
        return await fetchMoreSearchResults(objectGraph, intent.pageToken);
    }
}
/** Handles `SegmentedSearchResultsPageIntent` to fetch the segmented search results. */
export class SegmentedSearchResultsPageIntentController {
    constructor() {
        this.$intentKind = "SegmentedSearchResultsPageIntent";
    }
    async perform(intent, objectGraph) {
        return await fetchSegmentedSearchResults(objectGraph, intent.requestDescriptor);
    }
}
/** Handles `SearchResultsPageIntent` to fetch the search results. This is for shelves 2.0. */
export class SearchResultsPageIntentController {
    constructor() {
        this.$intentKind = "SearchResultsPageIntent";
        this.routes = searchResultsPageRoutes;
    }
    async perform(intent, objectGraphWithoutActiveIntnet) {
        if (objectGraphWithoutActiveIntnet.client.isWeb && !intent.platform) {
            // Search on the "web" client requires a platform; if we don't have one from the `Intent`, we should
            // assume we want `iphone` results
            intent.platform = "iphone";
        }
        return await withActiveIntent(objectGraphWithoutActiveIntnet, intent, async (objectGraph) => {
            var _a;
            validateNeedsVisionRestriction(objectGraph);
            const searchResultsPage = await fetchSearchResultsPage(objectGraph, intent);
            if (isNothing(searchResultsPage.canonicalURL)) {
                searchResultsPage.canonicalURL = makeCanonicalSearchResultsPageUrl(objectGraph, intent);
            }
            if (objectGraph.client.isWeb) {
                const webNavigation = injectWebNavigation(objectGraph, searchResultsPage, intent.platform);
                webNavigation.searchAction.destination.term = intent.term;
                replacePlatformSelectorDestinationWithSearchResults(objectGraph, webNavigation, intent);
                injectSEOData(searchResultsPage, (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.getSEODataForSearchResultsPage(objectGraph, searchResultsPage, null));
            }
            return searchResultsPage;
        });
    }
    actionFor(intent, objectGraph) {
        const flowAction = new models.FlowAction("search");
        flowAction.destination = intent;
        flowAction.pageUrl = makeCanonicalSearchResultsPageUrl(objectGraph, intent);
        return flowAction;
    }
}
/** Handles `SearchResultsPageMoreIntent` to fetch more of the search results. This is for shelves 2.0. */
export class SearchResultsPageMoreIntentController {
    constructor() {
        this.$intentKind = "SearchResultsPageMoreIntent";
    }
    async perform(intent, objectGraph) {
        return await fetchMoreSearchResultsPage(objectGraph, intent.pageToken);
    }
}
/** Fetches search results for shelves v1. */
async function fetchSearchResults(objectGraph, requestDescriptor) {
    const fetchTimingMetricsBuilder = new FetchTimingMetricsBuilder();
    const modifiedObjectGraph = objectGraph.addingFetchTimingMetricsBuilder(fetchTimingMetricsBuilder);
    const combinedSearchData = await searchResultsFetching.fetchSequentialSearchResultsData(modifiedObjectGraph, requestDescriptor);
    if (combinedSearchData === null) {
        return search.emptyResults(modifiedObjectGraph, requestDescriptor.facets);
    }
    return await search.searchResultsFromResponse(modifiedObjectGraph, combinedSearchData);
}
/** Fetches search results for segmented search results on visionOS */
async function fetchSegmentedSearchResults(objectGraph, requestDescriptor) {
    const combinedSearchData = await searchResultsFetching.fetchSegmentedSearchResults(objectGraph, requestDescriptor);
    if (combinedSearchData === null) {
        return search.emptySegmentedResultsPage(objectGraph);
    }
    return await search.segmentedSearchResultsPageFromResponse(objectGraph, combinedSearchData);
}
/** Fetches more search results for shelves v1. */
async function fetchMoreSearchResults(objectGraph, token) {
    return await search.paginatedSearchResultsWithToken(objectGraph, token);
}
/** Fetches search results for shelves 2.0. */
async function fetchSearchResultsPage(objectGraph, requestDescriptor) {
    const fetchTimingMetricsBuilder = new FetchTimingMetricsBuilder();
    const modifiedObjectGraph = objectGraph.addingFetchTimingMetricsBuilder(fetchTimingMetricsBuilder);
    const combinedSearchData = await searchResultsFetching.fetchSequentialSearchResultsData(modifiedObjectGraph, requestDescriptor);
    if (combinedSearchData === null) {
        return search.emptyResultsPage(objectGraph, requestDescriptor.facets);
    }
    return await search.searchResultsPageFromResponse(modifiedObjectGraph, combinedSearchData);
}
/** Fetches more search results for shelves 2.0. */
async function fetchMoreSearchResultsPage(objectGraph, token) {
    return await search.paginatedSearchResultsPageWithToken(objectGraph, token);
}
export class SearchResultsBuilder extends AbstractPageBuilder {
    constructor(objectGraph, runtime) {
        super("SearchResultsBuilder");
        runtime.exportingService("SearchData", {
            /** Fetches search results for shelves v1. */
            async fetchResults(options) {
                return await fetchSearchResults(objectGraph, options);
            },
            /** Fetches more search results for shelves v1. */
            async fetchMoreResults(options) {
                return await fetchMoreSearchResults(objectGraph, options.pageToken);
            },
            /** Fetches search results for shelves 2.0. */
            async fetchSearchResultsPage(options) {
                return await fetchSearchResultsPage(objectGraph, options);
            },
            /** Fetches more search results for shelves 2.0. */
            async fetchMoreOfSearchResultsPage(options) {
                return await fetchMoreSearchResultsPage(objectGraph, options.pageToken);
            },
        });
    }
    async handlePage(objectGraph, url, parameters, matchedRuleIdentifier, referrerData, isIncomingURL) {
        throw new Error("No page routes specified");
    }
    pageRoute(objectGraph) {
        return [];
    }
    pageType() {
        return "unknown";
    }
}
//# sourceMappingURL=search-results-controller.js.map