import { Fexios, FexiosFinalContext, FexiosConfigs, FexiosRequestOptions } from 'fexios';
export * from 'fexios';

interface FexiosSaikou extends Fexios {
    _tokens: Map<string, string>;
}
/**
 * FexiosSaikou
 *
 * A pre-configured Fexios instance with MediaWiki-friendly defaults:
 * - MediaWiki-specific request/response params normalization
 * - built-in token management
 * - error handling
 *
 * @author dragon-fish <dragon-fish@qq.com>
 * @license MIT
 *
 * @param {string|URL} payload create a new FexiosSaikou instance with the given baseURL
 * @param {Fexios} payload or make the given Fexios instance a FexiosSaikou instance
 */
declare function createFexiosSaikou(payload: string | URL | Fexios): FexiosSaikou;

type MwApiParams = Record<string, string | number | string[] | undefined | boolean | File | Blob>;
type MwTokenName = 'createaccount' | 'csrf' | 'login' | 'patrol' | 'rollback' | 'userrights' | 'watch';
type MwApiResponse<T = any> = T & {
    batchcomplete?: string;
    continue?: {
        [key: string]: string;
        continue: string;
    };
    limits?: Record<string, number>;
    error?: MwApiResponseError;
    errors?: MwApiResponseError[];
    warnings?: Record<string, {
        warnings: string;
    }>;
};
interface MwApiResponseError {
    code: string;
    text: string;
    module?: string;
    docref?: string;
}

/**
 * Error codes for WikiSaikouError
 */
declare enum WikiSaikouErrorCode {
    HTTP_ERROR = "HTTP_ERROR",
    LOGIN_FAILED = "LOGIN_FAILED",
    LOGIN_RETRY_LIMIT_EXCEEDED = "LOGIN_RETRY_LIMIT_EXCEEDED",
    TOKEN_RETRY_LIMIT_EXCEEDED = "TOKEN_RETRY_LIMIT_EXCEEDED"
}
/**
 * Server-side (MediaWiki API) business error:
 * - fetch succeeded but JSON includes `error` or `errors.length > 0`
 * - Special states (e.g., login NeedToken/WrongToken) are also considered API-side errors
 * Note: network/retry issues belong to WikiSaikouError, not this class
 */
declare class MediaWikiApiError extends Error {
    readonly errors: MwApiResponseError[];
    readonly cause?: FexiosFinalContext;
    readonly name = "MediaWikiApiError";
    readonly code: string;
    constructor(errors: MwApiResponseError[], cause?: FexiosFinalContext);
    get firstError(): MwApiResponseError;
    isBadTokenError(): boolean;
    toString(): string;
    static is(data?: any): data is MediaWikiApiError;
    static normalizeErrors(errors: MwApiResponseError[]): MwApiResponseError[];
}
/**
 * WikiSaikou Error:
 * - Transport/network failures (e.g., fetch failure, HTTP layer issues)
 * - SDK behavioral errors such as exhausted internal retries or misconfigurations
 * Note: When MediaWiki API responds with JSON containing error/errors, a MediaWikiApiError should be thrown instead
 */
declare class WikiSaikouError extends Error {
    readonly code: WikiSaikouErrorCode;
    readonly message: string;
    readonly cause?: FexiosFinalContext;
    readonly name = "WikiSaikouError";
    constructor(code: WikiSaikouErrorCode, message?: string, cause?: FexiosFinalContext);
    static is(data?: any, code?: WikiSaikouErrorCode): data is WikiSaikouError;
}
/**
 * Helper functions for WikiSaikouError and MediaWikiApiError
 */
declare namespace WikiSaikouError {
    function includesMediaWikiApiError(data?: any): boolean;
    const normalizeMwApiErrors: typeof MediaWikiApiError.normalizeErrors;
    function extractMediaWikiApiErrors(data?: any): MwApiResponseError[];
    function isBadTokenError(data?: any): boolean;
}

declare namespace MwParamNormalizer {
    function normalizeParamValue(item: any): string | Blob | undefined;
    function normalizeBody(body: any): FormData | undefined;
}

interface WikiSaikouConfig {
    /**
     * @default undefined // required in Node.js environment
     * @default `${wgServer}${wgScriptPath}/api.php` // in MW pages
     * @description The MediaWiki API endpoint, e.g. "https://www.mediawiki.org/w/api.php"
     * @optional In real MediaWiki browser pages, `baseURL` can be omitted and will be inferred automatically based on `window.mw`
     */
    baseURL: string;
    /**
     * Transport/runtime options passed to the underlying Fexios instance (headers, fetch, credentials, etc.).
     * @default { responseType: 'json' }
     */
    fexiosConfigs: Partial<FexiosConfigs>;
    /**
     * Default query parameters merged into every request.
     * @default { action: 'query' }
     */
    defaultParams: MwApiParams;
    /**
     * When true, responses whose JSON body contains `error`/`errors` will throw `MediaWikiApiError` even if HTTP status is 2xx.
     * @default false
     */
    throwOnApiError: boolean;
}
type WikiSaikouInitConfig = Omit<Partial<WikiSaikouConfig>, 'baseURL'> & {
    baseURL: string;
};
/**
 * WikiSaikou Core class
 * @internal You **SHOULD NOT** use this class directly, instead, use the `MediaWikiApi` class.
 * @author dragon-fish <dragon-fish@qq.com>
 * @license MIT
 */
declare class WikiSaikouCore {
    readonly config: Required<WikiSaikouConfig>;
    readonly version: any;
    readonly request: FexiosSaikou;
    static INIT_DEFAULT_PARAMS: MwApiParams;
    static DEFAULT_CONFIGS: Required<WikiSaikouConfig>;
    /** @deprecated Use `new MediaWikiApi(config)` instead */
    constructor(baseURL?: string, defaultOptions?: Partial<FexiosConfigs>, defaultParams?: MwApiParams);
    constructor(config?: WikiSaikouInitConfig);
    setBaseURL(baseURL: string): this;
    /** Base methods encapsulation */
    get<T = any>(query: MwApiParams, options?: Partial<FexiosRequestOptions>): Promise<FexiosFinalContext<MwApiResponse<T>>>;
    post<T = any>(data: MwApiParams | URLSearchParams | FormData, options?: Partial<FexiosRequestOptions>): Promise<FexiosFinalContext<MwApiResponse<T>>>;
    /**
     * Wrap a request to map non-2xx responses containing MediaWiki API error bodies
     * into MediaWikiApiError when throwOnApiError=true, and then pass 2xx responses
     * through handleApiResponse for unified processing.
     */
    private runRequestWithApiErrorMapping;
    private throwIfApiError;
    private handleApiResponse;
    /** Token Handler */
    get tokens(): Map<string, string>;
    fetchTokens(types?: MwTokenName[]): Promise<Map<string, string>>;
    getToken(type?: MwTokenName, noCache?: boolean): Promise<string>;
    badToken(type: MwTokenName): Map<string, string>;
    postWithToken<T = any>(tokenType: MwTokenName, body: MwApiParams, options?: {
        tokenName?: string;
        retry?: number;
        noCache?: boolean;
        fexiosOptions?: Partial<FexiosRequestOptions>;
    }): Promise<FexiosFinalContext<MwApiResponse<T>>>;
    postWithEditToken<T = any>(body: MwApiParams): Promise<FexiosFinalContext<MwApiResponse<T>>>;
    /** @deprecated Use `this.config.baseURL` instead */
    get baseURL(): string;
    /** @deprecated Use `this.config.defaultParams` instead */
    get defaultParams(): MwApiParams;
    /** @deprecated Use `this.config.fexiosConfigs` instead */
    get defaultOptions(): Partial<FexiosConfigs>;
    /** @deprecated Use `createFexiosSaikou` instead */
    static readonly createRequestHandler: typeof createFexiosSaikou;
    /** @deprecated Use `this.getToken` instead */
    token: (type?: MwTokenName, noCache?: boolean) => Promise<string>;
}

export { MediaWikiApiError, WikiSaikouCore as MwApiBase, MwParamNormalizer, WikiSaikouCore, WikiSaikouError, WikiSaikouErrorCode, createFexiosSaikou };
export type { FexiosSaikou, MwApiParams, MwApiResponse, MwApiResponseError, MwTokenName, WikiSaikouConfig, WikiSaikouInitConfig };
