import * as Effect from "../Effect.ts";
import * as Sse from "../encoding/Sse.ts";
import * as HttpClient from "../http/HttpClient.ts";
import * as HttpClientError from "../http/HttpClientError.ts";
import type * as HttpClientResponse from "../http/HttpClientResponse.ts";
import * as Schema from "../Schema.ts";
import * as Stream from "../Stream.ts";
import type { Simplify } from "../Types.ts";
import * as HttpApi from "./HttpApi.ts";
import * as HttpApiEndpoint from "./HttpApiEndpoint.ts";
import type * as HttpApiGroup from "./HttpApiGroup.ts";
import type * as HttpApiMiddleware from "./HttpApiMiddleware.ts";
import * as HttpApiSchema from "./HttpApiSchema.ts";
/**
 * The type-safe client shape generated from HTTP API groups, with non-top-level
 * groups exposed as nested objects and top-level endpoints exposed as methods.
 *
 * @stability unstable
 * @category models
 * @since 4.0.0
 */
export type Client<Groups extends HttpApiGroup.Constraint, E = never, R = never> = Simplify<{
    readonly [Group in Extract<Groups, {
        readonly topLevel: false;
    }> as HttpApiGroup.Identifier<Group>]: Client.Group<Group, E, R>;
} & Client.TopLevelMethods<Groups, E, R>>;
/**
 * Derives the typed client interface for an `HttpApi`, preserving any additional
 * client error and service requirements supplied by the caller.
 *
 * @stability unstable
 * @category utility types
 * @since 4.0.0
 */
export type ForApi<Api extends HttpApi.Constraint, E = never, R = never> = Api extends HttpApi.HttpApi<infer _Id, infer Groups> ? Client<Groups, E, R> : never;
/**
 * Computes the decoded success value a client receives for an endpoint
 * success schema, including headers, streaming Server-Sent Events, and
 * streaming byte responses.
 *
 * @stability unstable
 * @category utility types
 * @since 4.0.0
 */
export type SuccessType<S> = S extends HttpApiSchema.WithHeaders<infer _Inner, infer _Headers> ? HttpApiSchema.withHeaders<SuccessType<_Inner>, _Headers["Type"]> : S extends HttpApiSchema.StreamSse<infer _Events, infer _Error, infer _Value> ? Stream.Stream<_Value, _Error["Type"] | HttpClientError.HttpClientError | Schema.SchemaError | Sse.Retry | Sse.SseError, never> : S extends HttpApiSchema.StreamUint8Array ? Stream.Stream<Uint8Array, HttpClientError.HttpClientError, never> : S extends Schema.Constraint ? S["Type"] : never;
type SuccessDecodingServices<S> = S extends HttpApiSchema.StreamSse<infer _Events, infer _Error, infer _Value> ? _Events["DecodingServices"] | _Error["DecodingServices"] : S extends HttpApiSchema.StreamUint8Array ? never : S extends Schema.Constraint ? S["DecodingServices"] : never;
/**
 * Helper types used to describe generated HTTP API clients, including endpoint
 * methods, response modes, and grouped client shapes.
 *
 * @stability unstable
 * @since 4.0.0
 */
export declare namespace Client {
    /**
     * The response mode accepted by generated client methods, controlling whether a
     * call returns the decoded success value, the raw response, or both.
     *
     * @stability unstable
     * @category models
     * @since 4.0.0
     */
    type ResponseMode = HttpApiEndpoint.ClientResponseMode;
    /**
     * Computes the value returned by a client method for a success type and response
     * mode.
     *
     * @stability unstable
     * @category models
     * @since 4.0.0
     */
    type Response<Success, Mode extends ResponseMode> = Mode extends "decoded-and-response" ? [Success, HttpClientResponse.HttpClientResponse] : Mode extends "response-only" ? HttpClientResponse.HttpClientResponse : Success;
    type GroupByEndpoint<Group extends HttpApiGroup.Constraint, E, R> = Group["endpoints"] extends infer Endpoints extends Readonly<Record<string, HttpApiEndpoint.ConstraintRequest>> ? {
        readonly [Identifier in keyof Endpoints]: Method<Endpoints[Identifier], E, R>;
    } : {};
    /**
     * The client object for one API group, mapping each endpoint identifier in that
     * group to its typed client method.
     *
     * @stability unstable
     * @category models
     * @since 4.0.0
     */
    type Group<Group extends HttpApiGroup.Constraint, E, R> = GroupByEndpoint<Group, E, R>;
    type MethodReturn<Endpoint extends HttpApiEndpoint.ConstraintRequest, E, R, Mode extends ResponseMode> = Effect.Effect<Response<SuccessType<Endpoint["~Success"]>, Mode>, HttpApiMiddleware.Error<Endpoint["~Middleware"]> | HttpApiMiddleware.ClientError<Endpoint["~Middleware"]> | E | HttpClientError.HttpClientError | ([Mode] extends ["response-only"] ? never : Endpoint["~Error"]["Type"] | Schema.SchemaError), R | Endpoint["~Params"]["EncodingServices"] | Endpoint["~Query"]["EncodingServices"] | Endpoint["~Payload"]["EncodingServices"] | Endpoint["~Headers"]["EncodingServices"] | ([Mode] extends ["response-only"] ? never : SuccessDecodingServices<Endpoint["~Success"]> | Endpoint["~Error"]["DecodingServices"])>;
    /**
     * The typed function generated for an endpoint, accepting the endpoint request
     * shape, including optional per-call SSE decoding options. The returned effect's success,
     * error, and service channels reflect the endpoint schemas, middleware, and
     * selected response mode.
     *
     * @stability unstable
     * @category models
     * @since 4.0.0
     */
    type Method<Endpoint extends HttpApiEndpoint.ConstraintRequest, E, R> = <Mode extends ResponseMode = "decoded-only">(request: Simplify<HttpApiEndpoint.ClientRequest<Endpoint["~Params"], Endpoint["~Query"], Endpoint["~Payload"], Endpoint["~Headers"], Mode>>) => MethodReturn<Endpoint, E, R, Mode>;
    /**
     * Extracts client methods for endpoints in top-level groups so they can be exposed
     * directly on the generated client object.
     *
     * @stability unstable
     * @category models
     * @since 4.0.0
     */
    type TopLevelMethods<Groups extends HttpApiGroup.Constraint, E, R> = {
        readonly [Endpoint in Extract<HttpApiGroup.Endpoints<Extract<Groups, {
            readonly topLevel: true;
        }>>, HttpApiEndpoint.ConstraintRequest> as Endpoint["identifier"]]: Method<Endpoint, E, R>;
    };
}
type UrlBuilderRequestPart<Key extends string, Value> = [Value] extends [never] ? {} : {
    readonly [K in Key]: Value;
};
type UrlBuilderRequest<Endpoint extends HttpApiEndpoint.Constraint, Params = HttpApiEndpoint.Params<Endpoint>["Type"], Query = HttpApiEndpoint.Query<Endpoint>["Type"]> = (UrlBuilderRequestPart<"params", Params> & UrlBuilderRequestPart<"query", Query>) extends infer Request ? keyof Request extends never ? void | undefined : Request : never;
type UrlBuilderArgs<Request> = [Request] extends [void | undefined] ? [request?: Request] : [request: Request];
/**
 * The type-safe URL builder shape for an HTTP API, mirroring the generated client
 * layout while returning URL strings instead of executing requests.
 *
 * @stability unstable
 * @category models
 * @since 4.0.0
 */
export type UrlBuilder<Api extends HttpApi.Constraint> = Api extends HttpApi.HttpApi<infer _ApiId, infer Groups> ? [
    Extract<Groups, {
        readonly topLevel: true;
    }>
] extends [never] ? UrlBuilderGroups<Groups> : [Extract<Groups, {
    readonly topLevel: false;
}>] extends [never] ? UrlBuilderTopLevelMethods<Groups> : Simplify<UrlBuilderGroups<Groups> & UrlBuilderTopLevelMethods<Groups>> : never;
type UrlBuilderGroups<Groups extends HttpApiGroup.Constraint> = {
    readonly [Group in Extract<Groups, {
        readonly topLevel: false;
    }> as HttpApiGroup.Identifier<Group>]: UrlBuilderGroup<HttpApiGroup.Endpoints<Group>>;
};
type UrlBuilderGroup<Endpoints extends HttpApiEndpoint.Constraint> = {
    readonly [Endpoint in Endpoints as HttpApiEndpoint.Identifier<Endpoint>]: UrlBuilderMethod<Endpoint>;
};
type UrlBuilderMethod<Endpoint extends HttpApiEndpoint.Constraint> = (...args: UrlBuilderArgs<UrlBuilderRequest<Endpoint>>) => string;
type UrlBuilderTopLevelMethods<Groups extends HttpApiGroup.Constraint> = {
    readonly [Endpoint in HttpApiGroup.Endpoints<Extract<Groups, {
        readonly topLevel: true;
    }>> as HttpApiEndpoint.Identifier<Endpoint>]: UrlBuilderMethod<Endpoint>;
};
/**
 * Constructs a type-safe client for an HTTP API using the `HttpClient` service,
 * endpoint schemas, middleware, and optional client or response transformations.
 *
 * @stability unstable
 * @category constructors
 * @since 4.0.0
 */
export declare const make: <ApiId extends string, Groups extends HttpApiGroup.Constraint>(api: HttpApi.HttpApi<ApiId, Groups>, options?: {
    readonly transformClient?: ((client: HttpClient.HttpClient) => HttpClient.HttpClient) | undefined;
    readonly transformResponse?: ((effect: Effect.Effect<unknown, unknown, unknown>) => Effect.Effect<unknown, unknown, unknown>) | undefined;
    readonly baseUrl?: URL | string | undefined;
}) => Effect.Effect<Client<Groups>, never, HttpClient.HttpClient | HttpApiGroup.MiddlewareClient<Groups>>;
/**
 * Constructs a type-safe client for an HTTP API from the supplied `HttpClient`,
 * using the API metadata to encode requests, execute middleware, and decode
 * responses.
 *
 * @stability unstable
 * @category constructors
 * @since 4.0.0
 */
export declare const makeWith: <ApiId extends string, Groups extends HttpApiGroup.Constraint, E, R>(api: HttpApi.HttpApi<ApiId, Groups>, options: {
    readonly httpClient: HttpClient.HttpClient.With<E, R>;
    readonly transformResponse?: ((effect: Effect.Effect<unknown, unknown, unknown>) => Effect.Effect<unknown, unknown, unknown>) | undefined;
    readonly baseUrl?: URL | string | undefined;
}) => Effect.Effect<Client<Groups, Exclude<E, HttpClientError.HttpClientError>, R>, never, HttpApiGroup.MiddlewareClient<Groups>>;
/**
 * Builds a typed client object for a single API group from the supplied
 * `HttpClient`, filtering the API to that group.
 *
 * @stability unstable
 * @category constructors
 * @since 4.0.0
 */
export declare const group: <ApiId extends string, Groups extends HttpApiGroup.Constraint, const GroupIdentifier extends HttpApiGroup.Identifier<Groups>, E, R>(api: HttpApi.HttpApi<ApiId, Groups>, options: {
    readonly group: GroupIdentifier;
    readonly httpClient: HttpClient.HttpClient.With<E, R>;
    readonly transformResponse?: ((effect: Effect.Effect<unknown, unknown, unknown>) => Effect.Effect<unknown, unknown, unknown>) | undefined;
    readonly baseUrl?: URL | string | undefined;
}) => Effect.Effect<Client.Group<HttpApiGroup.WithIdentifier<Groups, GroupIdentifier>, E, R>, never, HttpApiGroup.MiddlewareClient<HttpApiGroup.WithIdentifier<Groups, GroupIdentifier>>>;
type EndpointReturn<Groups extends HttpApiGroup.Constraint, GroupIdentifier extends HttpApiGroup.Identifier<Groups>, EndpointIdentifier extends HttpApiGroup.EndpointsWithIdentifier<Groups, GroupIdentifier>["identifier"], E, R, Endpoint extends HttpApiEndpoint.ConstraintRequest = Extract<HttpApiEndpoint.WithIdentifier<HttpApiGroup.EndpointsWithIdentifier<Groups, GroupIdentifier>, EndpointIdentifier>, HttpApiEndpoint.ConstraintRequest>> = Effect.Effect<Client.Method<Endpoint, E, R>, never, HttpApiEndpoint.MiddlewareClient<Endpoint>>;
/**
 * Builds the typed client method for one endpoint in one API group, using the
 * supplied `HttpClient` and endpoint metadata.
 *
 * @stability unstable
 * @category constructors
 * @since 4.0.0
 */
export declare const endpoint: <ApiId extends string, Groups extends HttpApiGroup.Constraint, const GroupIdentifier extends HttpApiGroup.Identifier<Groups>, const EndpointIdentifier extends HttpApiGroup.EndpointsWithIdentifier<Groups, GroupIdentifier>["identifier"], E, R>(api: HttpApi.HttpApi<ApiId, Groups>, options: {
    readonly group: GroupIdentifier;
    readonly endpoint: EndpointIdentifier;
    readonly httpClient: HttpClient.HttpClient.With<E, R>;
    readonly transformClient?: ((client: HttpClient.HttpClient.With<E, R>) => HttpClient.HttpClient.With<E, R>) | undefined;
    readonly transformResponse?: ((effect: Effect.Effect<unknown, unknown, unknown>) => Effect.Effect<unknown, unknown, unknown>) | undefined;
    readonly baseUrl?: URL | string | undefined;
}) => EndpointReturn<Groups, GroupIdentifier, EndpointIdentifier, E, R>;
/**
 * Creates a type-safe URL builder that mirrors `HttpApiClient.make`.
 *
 * **Example** (Building typed URLs)
 *
 * ```ts import.meta.vitest
 * import { Schema } from "effect"
 * import { HttpApi, HttpApiClient, HttpApiEndpoint, HttpApiGroup } from "effect/http-api"
 *
 * const Api = HttpApi.make("Api").add(
 *   HttpApiGroup.make("users").add(
 *     HttpApiEndpoint.get("getUser", "/users/:id", {
 *       params: { id: Schema.String }
 *     })
 *   )
 * )
 *
 * const buildUrl = HttpApiClient.urlBuilder(Api, {
 *   baseUrl: "https://api.example.com"
 * })
 *
 * buildUrl.users.getUser({
 *   params: { id: "123" }
 * }) // => "https://api.example.com/users/123"
 * ```
 *
 * @stability unstable
 * @category constructors
 * @since 4.0.0
 */
export declare const urlBuilder: <Api extends HttpApi.Constraint>(api: Api, options?: {
    readonly baseUrl?: URL | string | undefined;
}) => UrlBuilder<Api>;
export {};
//# sourceMappingURL=HttpApiClient.d.ts.map