import { definePlugin } from "../../utils/plugin-utils";
import { createPaginatedPluginMethod } from "../../utils/plugin-utils";
import { ListActionInputFieldsInputSchema } from "./schemas";
import { ZapierConfigurationError } from "../../types/errors";
import { DEFAULT_PAGE_SIZE } from "../../constants";
import { appKeyResolver, actionTypeResolver, actionKeyResolver, connectionIdResolver, inputsAllOptionalResolver, } from "../../resolvers";
import { RootFieldItemSchema } from "../../schemas/Field";
import { toTitleCase } from "../../utils/string-utils";
import { fetchImplementationNeeds } from "../../services/implementations";
import { resolveConnectionId } from "../../utils/domain-utils";
import { setMethodMetadata } from "../../utils/telemetry-context";
// Enums for input field transformation
var InputFieldType;
(function (InputFieldType) {
    InputFieldType["STRING"] = "STRING";
    InputFieldType["NUMBER"] = "NUMBER";
    InputFieldType["INTEGER"] = "INTEGER";
    InputFieldType["BOOLEAN"] = "BOOLEAN";
    InputFieldType["OBJECT"] = "OBJECT";
    InputFieldType["ARRAY"] = "ARRAY";
})(InputFieldType || (InputFieldType = {}));
var InputFieldFormat;
(function (InputFieldFormat) {
    InputFieldFormat["DATETIME"] = "DATETIME";
    InputFieldFormat["SELECT"] = "SELECT";
    InputFieldFormat["MULTILINE"] = "MULTILINE";
    InputFieldFormat["FILE"] = "FILE";
    InputFieldFormat["PASSWORD"] = "PASSWORD";
    InputFieldFormat["CODE"] = "CODE";
})(InputFieldFormat || (InputFieldFormat = {}));
var ItemsType;
(function (ItemsType) {
    ItemsType["STRING"] = "STRING";
    ItemsType["NUMBER"] = "NUMBER";
    ItemsType["INTEGER"] = "INTEGER";
    ItemsType["BOOLEAN"] = "BOOLEAN";
    ItemsType["OBJECT"] = "OBJECT";
})(ItemsType || (ItemsType = {}));
// Transformation helper functions
function getInputFieldTypeFromNeed(need) {
    if (need.list) {
        return InputFieldType.ARRAY;
    }
    const typeMap = {
        string: InputFieldType.STRING,
        decimal: InputFieldType.NUMBER,
        integer: InputFieldType.INTEGER,
        boolean: InputFieldType.BOOLEAN,
        dict: InputFieldType.OBJECT,
    };
    return typeMap[need.type || ""] || InputFieldType.STRING;
}
function getInputFieldFormatFromNeed(need) {
    if (need.prefill || need.choices) {
        return InputFieldFormat.SELECT;
    }
    const formatMap = {
        text: InputFieldFormat.MULTILINE,
        datetime: InputFieldFormat.DATETIME,
        file: InputFieldFormat.FILE,
        password: InputFieldFormat.PASSWORD,
        code: InputFieldFormat.CODE,
    };
    return formatMap[need.type || ""];
}
function getItemsTypeFromNeed(need) {
    if (!need.list) {
        return undefined;
    }
    const typeMap = {
        string: ItemsType.STRING,
        decimal: ItemsType.NUMBER,
        integer: ItemsType.INTEGER,
        boolean: ItemsType.BOOLEAN,
        dict: ItemsType.OBJECT,
    };
    return typeMap[need.type || ""] || ItemsType.STRING;
}
// Transform Need to InputFieldItem
function transformNeedToInputFieldItem(need) {
    const itemsType = getItemsTypeFromNeed(need);
    return {
        type: "input_field",
        key: need.key,
        default_value: need.default || "",
        depends_on: need.depends_on || [],
        description: need.help_text || "",
        invalidates_input_fields: need.alters_custom_fields || false,
        is_required: need.required || false,
        placeholder: need.placeholder || "",
        title: need.label || "",
        value_type: getInputFieldTypeFromNeed(need),
        format: getInputFieldFormatFromNeed(need),
        items: itemsType ? { type: itemsType } : undefined,
    };
}
// Transform Need to InfoFieldItem (for copy fields)
function transformNeedToInfoFieldItem(need) {
    return {
        type: "info_field",
        key: need.key,
        description: need.help_text || "",
        title: need.label,
    };
}
// Transform needs to fields (similar to partnerapi compute_root_fieldset_from_needs)
function transformNeedsToFields(needs) {
    const rootFields = [];
    const fieldsetMap = new Map();
    for (const need of needs) {
        if (need.computed) {
            // Computed needs (i.e zap_id for CodeAPI steps) are not shown by the
            // editor, hide them here too.
            continue;
        }
        // If parent_key is set, we need to ensure that a corresponding
        // fieldset exists, since we'll be adding this need to that fieldset
        if (need.parent_key) {
            let fieldset = fieldsetMap.get(need.parent_key);
            if (!fieldset) {
                fieldset = {
                    type: "fieldset",
                    key: need.parent_key,
                    title: toTitleCase(need.parent_key),
                    fields: [],
                };
                fieldsetMap.set(need.parent_key, fieldset);
                rootFields.push(fieldset);
            }
            // Add field to fieldset
            if (need.type === "copy" && need.help_text) {
                fieldset.fields.push(transformNeedToInfoFieldItem(need));
            }
            else {
                fieldset.fields.push(transformNeedToInputFieldItem(need));
            }
        }
        else {
            // Add field to root
            if (need.type === "copy" && need.help_text) {
                rootFields.push(transformNeedToInfoFieldItem(need));
            }
            else {
                rootFields.push(transformNeedToInputFieldItem(need));
            }
        }
    }
    return rootFields;
}
export const listActionInputFieldsPlugin = definePlugin((sdk) => createPaginatedPluginMethod(sdk, {
    name: "listActionInputFields",
    categories: ["action"],
    type: "list",
    itemType: "RootField",
    inputSchema: ListActionInputFieldsInputSchema,
    outputSchema: RootFieldItemSchema,
    defaultPageSize: DEFAULT_PAGE_SIZE,
    resolvers: {
        app: appKeyResolver,
        actionType: actionTypeResolver,
        action: actionKeyResolver,
        connection: connectionIdResolver,
        inputs: inputsAllOptionalResolver,
    },
    handler: async ({ sdk, options, }) => {
        // pageSize/cursor ignored — this endpoint is single-page; pagination
        // helpers around it just yield the one page.
        const { api, getVersionedImplementationId } = sdk.context;
        const appKey = "app" in options ? options.app : options.appKey;
        const actionKey = "action" in options ? options.action : options.actionKey;
        const { actionType, connection, connectionId, authenticationId, inputs, } = options;
        const resolvedConnectionId = await resolveConnectionId({
            connection,
            connectionId,
            authenticationId,
            resolveConnection: sdk.context.resolveConnection,
        });
        const selectedApi = await getVersionedImplementationId(appKey);
        if (!selectedApi) {
            throw new ZapierConfigurationError("No current_implementation_id found for app", { configType: "current_implementation_id" });
        }
        setMethodMetadata({
            selectedApi,
            operationType: actionType,
            operationKey: actionKey,
        });
        // getAction resolves both action.key AND action.id (e.g.
        // `create_report` vs `core:39487493`).
        const { data: action } = await sdk.getAction({
            app: appKey,
            actionType,
            action: actionKey,
        });
        const needsData = await fetchImplementationNeeds({
            api,
            selectedApi,
            action: action.key,
            actionType,
            connectionId: resolvedConnectionId ?? null,
            inputs,
        });
        return {
            data: transformNeedsToFields(needsData.needs || []),
        };
    },
}));
