import * as vue from 'vue';
import { DeepReadonly, App } from 'vue';
import { RouteLocationRaw, Router, RouteLocationNormalized } from 'vue-router';
import { O as OAuth2Driver } from './OAuth2Driver-450f22ca.js';

declare const __defaultOption: {
    readonly rolesKey: "roles";
    readonly rememberKey: "auth_remember";
    readonly userKey: "auth_user";
    readonly staySignedInKey: "auth_stay_signed_in";
    readonly tokenDefaultKey: "auth_token_default";
    readonly tokenImpersonateKey: "auth_token_impersonate";
    readonly stores: readonly ["storage", "cookie"];
    readonly cookie: {
        readonly path: "/";
        readonly domain: undefined;
        readonly secure: true;
        readonly expires: 1209600000;
        readonly sameSite: "None";
    };
    readonly authRedirect: "/login";
    readonly forbiddenRedirect: "/403";
    readonly notFoundRedirect: "/404";
    readonly registerData: {
        readonly url: "auth/register";
        readonly method: "POST";
        readonly redirect: "/login";
        readonly autoLogin: false;
        readonly staySignedIn: true;
    };
    readonly loginData: {
        readonly url: "auth/login";
        readonly method: "POST";
        readonly redirect: "/";
        readonly fetchUser: true;
        readonly staySignedIn: true;
    };
    readonly logoutData: {
        readonly url: "auth/logout";
        readonly method: "POST";
        readonly redirect: "/";
        readonly makeRequest: true;
    };
    readonly fetchData: {
        readonly url: "auth/user";
        readonly method: "GET";
        readonly enabled: true;
    };
    readonly refreshToken: {
        readonly url: "auth/refresh";
        readonly method: "GET";
        readonly enabled: true;
        readonly interval: number | boolean | undefined;
    };
    readonly impersonateData: {
        readonly url: "auth/impersonate";
        readonly method: "POST";
        readonly redirect: "/";
        readonly fetchUser: true;
    };
    readonly unimpersonateData: {
        readonly url: "auth/unimpersonate";
        readonly method: "POST";
        readonly redirect: "/admin";
        readonly fetchUser: true;
        readonly makeRequest: false;
    };
    readonly oauth2Data: {
        readonly url: "auth/social";
        readonly method: "POST";
        readonly redirect: "/";
        readonly fetchUser: true;
    };
};

declare type TypeOrFnReturn<T, E = any> = T | ((this: E) => T);

declare type CookieOptions = {
    path?: TypeOrFnReturn<string>;
    domain?: TypeOrFnReturn<string>;
    secure?: TypeOrFnReturn<boolean>;
    expires?: TypeOrFnReturn<number | Date | string>;
    sameSite?: TypeOrFnReturn<string>;
};

declare type HttpDriver = {
    request: (options: {
        url: string;
        method?: string;
        data?: any;
        headers?: Record<string, string>;
        responseType?: "arraybuffer" | "blob" | "json" | "text";
    }) => Promise<{
        headers: Record<string, string>;
        data: any;
        status: number;
        statusText: string;
    }>;
    invalidToken?: (auth: Auth, response: Awaited<ReturnType<HttpDriver["request"]>>) => boolean;
};

declare function defineHttpDriver(opts: HttpDriver): HttpDriver;

declare type OptionRequest = {
    data?: Parameters<HttpDriver["request"]>[0]["data"];
    headers: Required<Parameters<HttpDriver["request"]>[0]>["headers"];
};
declare type AuthDriver = {
    tokens?: string[];
    request: (auth: Auth, options: OptionRequest, token: string) => OptionRequest;
    response: (auth: Auth, response: Awaited<ReturnType<HttpDriver["request"]>>) => string | null;
};

declare function defineAuthDriver(opts: AuthDriver): AuthDriver;

declare type HttpData = Partial<Parameters<HttpDriver["request"]>[0]> & {
    redirect?: RouteLocationRaw;
};
declare type Options = {
    initSync?: boolean;
    rolesKey?: string;
    rememberKey?: string;
    userKey?: string;
    staySignedInKey?: string;
    tokenDefaultKey?: string;
    tokenImpersonateKey?: string;
    stores?: ("cookie" | "storage" | {
        set: <T>(key: string, value: T, expires: boolean, auth: Auth) => void;
        get: <T>(key: string) => T;
        remove: (key: string) => void;
    })[];
    cookie?: CookieOptions;
    authRedirect?: RouteLocationRaw;
    forbiddenRedirect?: RouteLocationRaw;
    notFoundRedirect?: RouteLocationRaw;
    registerData?: HttpData & {
        keyUser?: string;
        autoLogin?: boolean;
        fetchUser?: boolean;
        staySignedIn?: boolean;
        remember?: boolean;
    };
    loginData?: HttpData & {
        keyUser?: string;
        fetchUser?: boolean;
        staySignedIn?: boolean;
        remember?: boolean;
        cacheUser?: boolean;
    };
    logoutData?: HttpData & {
        makeRequest?: boolean;
    };
    fetchData?: HttpData & {
        keyUser?: string;
        enabled?: boolean;
        cache?: boolean;
        enabledInBackground?: boolean;
        waitRefresh?: boolean;
    };
    refreshToken?: Omit<HttpData, "redirect"> & {
        enabled?: boolean;
        enabledInBackground?: boolean;
        interval?: number | false;
    };
    impersonateData?: HttpData & {
        fetchUser?: boolean;
        cacheUser?: boolean;
    };
    unimpersonateData?: HttpData & {
        fetchUser?: boolean;
        makeRequest?: boolean;
        cacheUser?: boolean;
    };
    oauth2Data?: HttpData & {
        fetchUser?: true;
    };
    plugins?: {
        router?: Router;
    };
    drivers: {
        auth: AuthDriver;
        http: HttpDriver;
        oauth2?: {
            facebook?: OAuth2Driver;
            google?: OAuth2Driver;
        };
    };
};

declare type Roles = string | (string | string[] | Record<string, unknown>)[] | Record<string, (string | string[] | Record<string, unknown>)[]>;

declare class Auth {
    readonly state: {
        data: any;
        loaded: boolean;
        offline: boolean;
        authenticated: boolean | null;
        impersonating: boolean | null;
        remember: boolean | null;
        cacheUser: boolean;
    };
    _redirect: vue.ShallowRef<{
        type: number | null;
        from: RouteLocationNormalized | null;
        to: RouteLocationNormalized | null;
    } | null>;
    readonly options: typeof __defaultOption & DeepReadonly<Options>;
    currentToken: string | null;
    tPrev: RouteLocationNormalized | null;
    tCurrent: RouteLocationNormalized | null;
    tStatusType: number | null;
    install(app: App, key?: symbol | string): void;
    constructor(options: Options);
    http<OtherOptions extends object>(options: OtherOptions & Parameters<HttpDriver["request"]>[0] & {
        ignoreVueAuth?: boolean;
        impersonating?: boolean;
    }): Promise<{
        headers: Record<string, string>;
        data: any;
        status: number;
        statusText: string;
    }>;
    ready(): boolean;
    private __timer_load;
    load(): Promise<void>;
    cancel(): void;
    redirect(): {
        type: number | null;
        from: RouteLocationNormalized | null;
        to: RouteLocationNormalized | null;
    } | null;
    user<U extends object>(data?: U): U | null;
    offline(): boolean;
    check(role?: Roles, key?: string): boolean;
    impersonating(): boolean;
    token(name?: string | null, token?: string | null, expires?: boolean): string | null;
    /**
     * @request auth/user
     * @returns Promise<user data> info user data (exm: {
     *
          username: "Tachibana Shin",
  
          email: "asjwepit32r@duck.com"
  
      })
     */
    fetch<OtherOptions extends object>(data?: OtherOptions & Partial<Options["fetchData"]>): Promise<{
        headers: Record<string, string>;
        data: any;
        status: number;
        statusText: string;
    }>;
    /**
     * @request auth/refresh
     * @returns Promise exists token refresh in Authorizer
     */
    refresh<OtherOptions extends object>(data?: OtherOptions & Required<Options>["refreshToken"]): Promise<{
        headers: Record<string, string>;
        data: any;
        status: number;
        statusText: string;
    }>;
    register<OtherOptions extends object>(data?: OtherOptions & Required<Options>["registerData"]): Promise<{
        headers: Record<string, string>;
        data: any;
        status: number;
        statusText: string;
    }>;
    login<OtherOptions extends object>(data?: OtherOptions & Required<Options>["loginData"]): Promise<{
        headers: Record<string, string>;
        data: any;
        status: number;
        statusText: string;
    }>;
    remember(val: boolean): boolean | null;
    unremember(): void;
    logout<OtherOptions extends object>(data?: OtherOptions & Required<Options>["logoutData"]): Promise<void>;
    impersonate<OtherOptions extends object>(data?: OtherOptions & Required<Options>["impersonateData"]): Promise<void>;
    unimpersonate<OtherOptions extends object>(data?: OtherOptions & Required<Options>["unimpersonateData"]): Promise<void>;
    oauth2(type: string | number, data: {
        code: any;
        state: string;
        params: {
            [x: string]: string | number | boolean;
            state?: any;
            redirect_uri?: any;
        };
        url: any;
        window: any;
    }): Promise<{
        headers: Record<string, string>;
        data: any;
        status: number;
        statusText: string;
    }> | undefined;
    enableImpersonate(): void;
    disableImpersonate(): void;
}

export { Auth as A, HttpDriver as H, Options as O, defineHttpDriver as a, AuthDriver as b, defineAuthDriver as d };
