import * as gql from '@lens-protocol/api-bindings';
import { InsufficientGasError, PendingSigningRequestError, TransactionError, UserRejectedError, WalletConnectionError } from '@lens-protocol/domain/entities';
import { OpenActionConfig, ReferencePolicyConfig } from '@lens-protocol/domain/use-cases/publications';
import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions';
import { PublicationMetadata } from '@lens-protocol/metadata';
import { UseDeferredTask } from "../../helpers/tasks.js";
import { IUploader, UploadError } from "./IUploader.js";
import { PostAsyncResult } from "./useCreatePost.js";
/**
 * Create new post details.
 *
 * @experimental This API is experimental and may change or be removed in future versions.
 */
export type OptimisticCreatePostArgs = {
    /**
     * The metadata object created via `@lens-protocol/metadata` package.
     */
    metadata: PublicationMetadata;
    /**
     * The Open Actions associated with the publication.
     *
     * @defaultValue empty, no open actions
     */
    actions?: OpenActionConfig[];
    /**
     * The post reference policy.
     *
     * Determines the criteria that must be met for a user to be able to comment, quote, or mirror the post.
     *
     * @defaultValue `{ type: ReferencePolicyType.ANYONE }`
     */
    reference?: ReferencePolicyConfig;
    /**
     * Whether the transaction costs should be sponsored by the Lens API or
     * should be paid by the authenticated wallet.
     *
     * There are scenarios where the sponsorship will be denied regardless of this value.
     * See {@link BroadcastingError} with:
     * - {@link BroadcastingErrorReason.NOT_SPONSORED} - the profile is not sponsored
     * - {@link BroadcastingErrorReason.RATE_LIMITED} - the profile reached the rate limit
     * - {@link BroadcastingErrorReason.APP_NOT_ALLOWED} - the app is not whitelisted for gasless transactions
     *
     * If not specified, or `true`, the hook will attempt a Sponsored Transaction.
     * Set it to `false` to force it to use a Self-Funded Transaction.
     */
    sponsored?: boolean;
};
/**
 * @experimental This API is experimental and may change or be removed in future versions.
 */
export type OptimisticCreatePostData = gql.Post | undefined;
/**
 * @experimental This API is experimental and may change or be removed in future versions.
 */
export type OptimisticCreatePostError = BroadcastingError | PendingSigningRequestError | InsufficientGasError | UserRejectedError | UploadError | WalletConnectionError | TransactionError;
/**
 * `useOptimisticCreatePost` is a React Hook that mirrors the behavior of {@link useCreatePost} but it also
 * provides an optimistic response.
 *
 * **This is still an experimental feature and for now the optimistic behavior is limited to posts
 * created with Signless Experience.**
 *
 * You MUST be authenticated via {@link useLogin} to use this hook.
 *
 * @example
 * ```ts
 * const { data, execute, loading, error } = useOptimisticCreatePost(uploader);
 * ```
 *
 * ## Basic usage
 *
 * To use the hook, first define an instance of the {@link Uploader} class.
 *
 * In this example, we're using a Stateless Uploader.
 * This type of uploader requires just a function that matches the {@link UploadHandler} signature.
 * Refer to {@link IUploader} for other types of uploaders.
 *
 * ```ts
 * const uploadHandler = async (file: File) => {
 *   // upload the file and return the public URI
 *   return 'https://example.com/uploaded-file.jpg';
 * };
 * ```
 *
 * Then, create an instance of the {@link Uploader} class.
 *
 * ```ts
 * const uploader = new Uploader(uploadHandler);
 * ```
 * Then pass the `uploader` to the `useOptimisticCreatePost` hook.
 *
 * To create a post, call the `execute` function with the metadata. Contrary to the `useCreatePost` hook you can pass the whole metadata object to the `execute` function.
 *
 * ```ts
 * import { textOnly } from '@lens-protocol/metadata';
 *
 * // ...
 *
 * const { data, execute, loading, error } = useOptimisticCreatePost(uploader);
 *
 * const post = (content: string) => {
 *   // create the desired metadata via the `@lens-protocol/metadata` package helpers
 *   const metadata = textOnly({ content });
 *
 *   // invoke the `execute` function to create the post
 *   const result = await execute({
 *     metadata,
 *   });
 *
 *   // check for failure scenarios
 *   if (result.isFailure()) {
 *     console.log(result.error.message);
 *   }
 * };
 *
 * return (
 *   // render data as you would do normally with any Post object
 * );
 * ```
 *
 * The `data` property will be updated with the optimistic Post object immediately after the `execute` call.
 *
 * ## Media Upload
 *
 * The `useOptimisticCreatePost` hook also supports media uploads.
 * It accomplishes this by utilizing the provided `uploader` to upload each media file. After the upload,
 * it updates the supplied metadata with the public URIs of the media files, as returned by the `uploader`.
 * Finally, it uploads the metadata and creates the post.
 *
 * To accomplish this, simply use the local file URL as media URI in the metadata object.
 *
 * When using the `@lens-protocol/react-web` package, you can use the `fileToUri` helper to convert a `File` object to a local file URL.
 *
 * ```ts fileName="foo"
 * import { image } from '@lens-protocol/metadata';
 * import { fileToUri, useOptimisticCreatePost } from '@lens-protocol/react-web';
 *
 * // ...
 *
 * const post = (file: File) => {
 *   // create the desired metadata via the `@lens-protocol/metadata` package helpers
 *   const metadata = image({
 *     image: {
 *       item: fileToUri(file),
 *       type: MediaImageMimeType.JPEG,
 *     },
 *   });
 *
 *   // invoke the `execute` function to create the post
 *   const result = await execute({
 *     metadata,
 *   });
 *
 *   // check for failure scenarios
 *   if (result.isFailure()) {
 *     console.log(result.error.message);
 *   }
 * };
 * ```
 *
 * When using the `@lens-protocol/react-native` package, you use the property that yield a `file://` URL from the
 * file picker library of your choice.
 *
 * ## Wait for completion
 *
 * Optionally, you can wait for the full completion of the post creation. .
 *
 * ```ts
 * const post = (content: string) => {
 *   // create the desired metadata via the `@lens-protocol/metadata` package helpers
 *   const metadata = textOnly({ content });
 *
 *   // invoke the `execute` function to create the post
 *   const result = await execute({
 *     metadata,
 *   });
 *
 *   // check for failure scenarios
 *   if (result.isFailure()) {
 *     console.log(result.error.message);
 *   }
 *
 *   // wait for full completion
 *   const completion = await result.value.waitForCompletion();
 *
 *   // check for late failures
 *   if (completion.isFailure()) {
 *     console.log(completion.error.message);
 *     return;
 *   }
 *
 *   console.log(completion.value);
 * };
 *
 * return (
 *   // render data
 * );
 * ```
 *
 * At the end the `data` property will automatically update and the final Post object will be available for further interactions.
 *
 * ## Failure scenarios
 *
 * In case of upload error an new error type {@link UploadError} will be returned both from the `error` property and from the `Result<T, E>` object from the `execute` function.
 *
 * ```ts
 * const { data, execute, loading, error } = useOptimisticCreatePost(uploader);
 *
 * const post = (content: string) => {
 *   // ...
 *   const result = await execute({
 *     metadata,
 *   });
 *
 *   // check for failure scenarios
 *   if (result.isFailure()) {
 *
 *     // check for upload error
 *     if (result.error instanceof UploadError) {
 *        console.log('There was an error uploading the file', result.error.cause);
 *        return;
 *     }
 *     // other errors handling
 *
 *     return;
 *   }
 * };
 *
 * return (
 *   {error && <p>{error.message}</p>}
 *   // render data
 * );
 * ```
 *
 * @experimental This API is experimental and may change or be removed in future versions without honoring semver.
 *
 * @category Publications
 * @group Hooks
 */
export declare function useOptimisticCreatePost(uploader: IUploader): UseDeferredTask<OptimisticCreatePostData, OptimisticCreatePostError, OptimisticCreatePostArgs, PostAsyncResult>;
