import type {
    DisplayModalParamsType,
    FrakClient,
    ModalRpcStepsResultType,
    ModalStepTypes,
} from "../types";

/**
 * Function used to display a modal
 * @param client - The current Frak Client
 * @param args
 * @param args.steps - The different steps of the modal
 * @param args.metadata - The metadata for the modal (customization, etc)
 * @param placement - Optional placement ID to associate with this modal display
 * @returns The result of each modal steps
 *
 * @description This function will display a modal to the user with the provided steps and metadata.
 *
 * @remarks
 * - The UI of the displayed modal can be configured with the `customCss` property in the `customizations.css` field of the top-level config.
 * - The `login` step will be automatically skipped if the user is already logged in. It's safe to include this step in all cases to ensure proper user state.
 * - Steps are automatically reordered in the following sequence:
 *     1. `login` (if needed)
 *     2. All other steps in the order specified
 *     3. `success` (if included, always last)
 *
 * @example
 * Simple sharing modal with steps:
 *  1. Login (Skipped if already logged in)
 *  2. Display a success message with sharing link option
 *
 * ```ts
 * const results = await displayModal(frakConfig, {
 *     steps: {
 *         // Simple login with no SSO, nor customization
 *         login: { allowSso: false },
 *         // Success message
 *         final: {
 *             action: { key: "reward" },
 *             // Skip this step, it will be only displayed in the stepper within the modal
 *             autoSkip: true,
 *         },
 *     },
 * });
 *
 * console.log("Login step - wallet", results.login.wallet);
 * ```
 *
 * @example
 * A full modal example, with a few customization options, with the steps:
 *  1. Login (Skipped if already logged in)
 *  2. Authenticate via SIWE
 *  3. Send a transaction
 *  4. Display a success message with sharing link options
 *
 * ```ts
 * const results = await displayModal(frakConfig, {
 *     steps: {
 *         // Login step
 *         login: {
 *             allowSso: true,
 *             ssoMetadata: {
 *                 logoUrl: "https://my-app.com/logo.png",
 *                 homepageLink: "https://my-app.com",
 *             },
 *         },
 *         // Siwe authentication
 *         siweAuthenticate: {
 *             siwe: {
 *                 domain: "my-app.com",
 *                 uri: "https://my-app.com/",
 *                 nonce: generateSiweNonce(),
 *                 version: "1",
 *             },
 *         },
 *         // Send batched transaction
 *         sendTransaction: {
 *             tx: [
 *                 { to: "0xdeadbeef", data: "0xdeadbeef" },
 *                 { to: "0xdeadbeef", data: "0xdeadbeef" },
 *             ],
 *         },
 *         // Success message with sharing options
 *         final: {
 *             action: {
 *                 key: "sharing",
 *                 options: {
 *                     popupTitle: "Share the app",
 *                     text: "Discover my super app website",
 *                     link: "https://my-app.com",
 *                 },
 *             },
 *             dismissedMetadata: {
 *                 title: "Dismiss",
 *                 description: "You won't be rewarded for this sharing action",
 *             },
 *         },
 *     },
 *     metadata: {
 *         // Header of desktop modals
 *         header: {
 *             title: "My-App",
 *             icon: "https://my-app.com/logo.png",
 *         },
 *         // Context that will be present in every modal steps
 *         context: "My-app overkill flow",
 *     },
 * });
 * ```
 */
export async function displayModal<
    T extends ModalStepTypes[] = ModalStepTypes[],
>(
    client: FrakClient,
    { steps, metadata }: DisplayModalParamsType<T>,
    placement?: string
): Promise<ModalRpcStepsResultType<T>> {
    return (await client.request({
        method: "frak_displayModal",
        params: placement
            ? [steps, metadata, client.config.metadata, placement]
            : [steps, metadata, client.config.metadata],
    })) as ModalRpcStepsResultType<T>;
}
