import { definePlugin } from "../../utils/plugin-utils";
import { createPaginatedPluginMethod } from "../../utils/plugin-utils";
import { DEFAULT_PAGE_SIZE } from "../../constants";
import { ListAppsSchema } from "./schemas";
import { AppItemSchema } from "../../schemas/App";
import { extractCursor } from "../../utils/function-utils";
export const listAppsPlugin = definePlugin((sdk) => createPaginatedPluginMethod(sdk, {
    name: "listApps",
    categories: ["app"],
    type: "list",
    itemType: "App",
    inputSchema: ListAppsSchema,
    outputSchema: AppItemSchema,
    defaultPageSize: DEFAULT_PAGE_SIZE,
    handler: async ({ sdk, options }) => {
        const { api, resolveAppKeys } = sdk.context;
        const appKeys = options.apps ?? options.appKeys ?? [];
        const appLocators = await resolveAppKeys({ appKeys: [...appKeys] });
        const implementationNameToLocator = {};
        for (const locator of appLocators) {
            implementationNameToLocator[locator.implementationName] = [
                ...(implementationNameToLocator[locator.implementationName] ?? []),
                locator,
            ];
        }
        const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator)
            .filter((key) => implementationNameToLocator[key].length > 1)
            .map((key) => implementationNameToLocator[key])
            .flat()
            .map((locator) => locator.lookupAppKey);
        if (duplicatedLookupAppKeys.length > 0) {
            throw new Error(`Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`);
        }
        // Early return if user provided appKeys but they resolved to nothing
        // AND no search. Prevents the handler from returning all apps when
        // the user explicitly filtered. If search is provided, let the API
        // augment with search results.
        if (appKeys.length > 0 && appLocators.length === 0 && !options.search) {
            return {
                data: [],
                links: { next: null },
                meta: { count: 0, limit: 0, offset: 0 },
            };
        }
        const implementationIds = appLocators.map((locator) => {
            const version = locator.version || "latest";
            return `${locator.implementationName}@${version}`;
        });
        return api.get("/api/v0/apps", {
            searchParams: {
                app_keys: implementationIds.join(","),
                ...(options.search && { search: options.search }),
                ...(options.pageSize !== undefined && {
                    page_size: options.pageSize.toString(),
                }),
                ...(options.cursor && { offset: options.cursor }),
            },
        });
    },
    extractCursor: (response) => extractCursor(response.links),
}));
