import * as E from 'fp-ts/Either';
import type * as IO from 'fp-ts/IO';
import * as O from 'fp-ts/Option';
import type * as R from 'fp-ts/Reader';
import * as T from 'fp-ts/Task';
import type * as TO from 'fp-ts/TaskOption';
import type { Lazy } from 'fp-ts/function';
import * as t from 'io-ts';
import type { ajax, AjaxConfig } from 'rxjs/ajax';
import * as ROR from './ReaderObservableResource';
import type * as RES from './Resource';
import type { resourceBadFailT, resourceBadRejectedT, resourceBadT } from './io-types/resourceBadT';
import type { StatusCode } from './statusCode';
export type CacheItem<S = StatusCode, P = unknown> = RES.ResourceData<S, P>;
export type CachePool = CachePoolSync | CachePoolAsync;
export interface CachePoolSync {
    _tag: 'sync';
    findItem: (key: string) => IO.IO<O.Option<CacheItem>>;
    addItem: (key: string, item: CacheItem, ttl: number) => IO.IO<void>;
}
export interface CachePoolAsync {
    _tag: 'async';
    findItem: (key: string) => TO.TaskOption<CacheItem>;
    addItem: (key: string, item: CacheItem, ttl: number) => T.Task<void>;
}
export interface LoggerFail<DL, OL> {
    (e: ResourceBad): R.Reader<DL, OL>;
}
export interface CreateCacheKey<DC> {
    (endpoint: EndpointRequest): R.Reader<DC, string>;
}
export type FetchFactoryDeps = DepsAjax;
export type FetchFactoryCacheableDeps = FetchFactoryDeps & DepsCache;
export interface DepsAjax {
    ajax: typeof ajax;
}
export interface DepsCache {
    cachePool: CachePool;
}
interface ResourceBadCtor<RB extends ResourceBadRejected | ResourceBadFail> {
    error: RB['error'];
    detail: unknown;
    errorMessage?: string;
    statusCode?: StatusCode | 0;
}
export type ResourceBadRejected = t.TypeOf<typeof resourceBadRejectedT>;
export declare const resourceBadRejected: (d: ResourceBadCtor<ResourceBadRejected>) => ResourceBad;
export type ResourceBadFail = t.TypeOf<typeof resourceBadFailT>;
export declare const resourceBadFail: (d: ResourceBadCtor<ResourceBadFail>) => ResourceBad;
export type ResourceBad = t.TypeOf<typeof resourceBadT>;
interface EndpointRequestAjaxRequest extends AjaxConfig {
    url: string;
    headers?: Record<string, string>;
}
interface EndpointRequestMethod {
    method: 'HEAD' | 'PUT' | 'POST' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'CONNECT';
}
export type EndpointRequest = EndpointRequestAjaxRequest & ({
    method: 'GET';
} | EndpointRequestMethod);
export type EndpointRequestCacheable = EndpointRequestAjaxRequest & ({
    method: 'GET';
    appCacheTtl?: number;
} | EndpointRequestMethod);
export type FetchFactoryDecoders<K extends StatusCode> = {
    [k in K]?: (i: unknown) => E.Either<t.Errors, any>;
};
export declare const fetchFactory: <DL, OL>(env: {
    loggerFail: (e: ResourceBad) => R.Reader<DL, OL>;
}) => <K extends StatusCode, DS extends FetchFactoryDecoders<K>, SC extends keyof DS>(request: EndpointRequest, decoderL: Lazy<DS>, successCodes: SC[]) => ROR.ReaderObservableResource<DepsAjax & DL, {
    type: "rejected";
    error: "notFound" | "clientError";
    errorMessage: string;
    statusCode: 0 | StatusCode;
    detail: unknown;
} | {
    type: "fail";
    error: "fail" | "unexpectedResponse" | "unknownError" | "networkError" | "decodeError" | "appError";
    errorMessage: string;
    statusCode: 0 | StatusCode;
    detail: unknown;
}, Extract<RES.DecodersToResourceData<DS>, {
    status: SC;
}>>;
export declare const fetchCacheableFactory: <DL, OL, DC>(env: {
    loggerFail: LoggerFail<DL, OL>;
    createCacheKey: CreateCacheKey<DC>;
}) => <K extends StatusCode, DS extends FetchFactoryDecoders<K>, SC extends keyof DS>(request: EndpointRequestCacheable, decoderL: Lazy<DS>, successCodes: SC[]) => ROR.ReaderObservableResource<DC & DepsAjax & DepsCache & DL, {
    type: "rejected";
    error: "notFound" | "clientError";
    errorMessage: string;
    statusCode: 0 | StatusCode;
    detail: unknown;
} | {
    type: "fail";
    error: "fail" | "unexpectedResponse" | "unknownError" | "networkError" | "decodeError" | "appError";
    errorMessage: string;
    statusCode: 0 | StatusCode;
    detail: unknown;
}, Extract<RES.DecodersToResourceData<DS>, {
    status: SC;
}>>;
export declare const errorMessage: (endpoint: EndpointRequest, error: ResourceBad['error']) => string;
export declare const logFail: <R1, B>(loggerFail: (e: ResourceBad) => R.Reader<R1, B>) => <R2, A>(ma: ROR.ReaderObservableResource<R2, {
    type: "rejected";
    error: "notFound" | "clientError";
    errorMessage: string;
    statusCode: 0 | StatusCode;
    detail: unknown;
} | {
    type: "fail";
    error: "fail" | "unexpectedResponse" | "unknownError" | "networkError" | "decodeError" | "appError";
    errorMessage: string;
    statusCode: 0 | StatusCode;
    detail: unknown;
}, A>) => ROR.ReaderObservableResource<R2 & R1, {
    type: "rejected";
    error: "notFound" | "clientError";
    errorMessage: string;
    statusCode: 0 | StatusCode;
    detail: unknown;
} | {
    type: "fail";
    error: "fail" | "unexpectedResponse" | "unknownError" | "networkError" | "decodeError" | "appError";
    errorMessage: string;
    statusCode: 0 | StatusCode;
    detail: unknown;
}, A>;
export {};
