import { EV } from "@fastkit/ev";
import { App, Component, InjectionKey, PropType, VNode } from "vue";
import { RouteMatchedItem } from "@fastkit/vue-utils";
import { LocationAsRelativeRaw, LocationQueryRaw, MatcherLocationAsPath, RouteLocation, RouteLocationNormalized, RouteLocationNormalizedLoaded, RouteQueryAndHash, Router, RouterLink, RouterScrollBehavior, RouterView, useLink } from "vue-router";
import { Cookies } from "@fastkit/cookies";
import { IncomingMessage, ServerResponse } from "node:http";
//#region src/schemes.d.ts
interface ResolvedRouteLocation extends RouteLocation {
  href: string;
}
type InstanceOf<T> = T extends (new (...args: any[]) => infer R) ? R : never;
type RouterViewSlotProps = Parameters<NonNullable<InstanceOf<typeof RouterView>['$slots']['default']>>[0];
type WatchQueryOption = boolean | string[];
type VuePageKeyOverride = string | null | ((route: RouteLocationNormalizedLoaded) => string);
//#endregion
//#region src/composables/router/suspense-route-bucket.d.ts
type SuspenseRouteSource = VNode;
interface SuspenseRouteBucketPayload {
  bucket: SuspenseRouteBucket;
  source: SuspenseRouteSource;
}
interface SuspenseRouteBucketEventMap {
  push: SuspenseRouteBucketPayload;
  remove: SuspenseRouteBucketPayload;
  start: SuspenseRouteBucketPayload;
  finish: SuspenseRouteBucketPayload;
}
interface SuspenseRouteBucketProgress {
  total: number;
  resolved: number;
}
declare class SuspenseRouteBucket extends EV<SuspenseRouteBucketEventMap> {
  private readonly _sources;
  private readonly _total;
  private readonly _progress;
  get sources(): SuspenseRouteSource[];
  get total(): number;
  get progress(): SuspenseRouteBucketProgress;
  constructor();
  push(source?: SuspenseRouteSource): void;
  remove(source?: SuspenseRouteSource): void;
  ensureReady(): Promise<void>;
}
declare function getSuspenseRouteBucket(): SuspenseRouteBucket;
//#endregion
//#region src/composables/router/scroll-behavior.d.ts
type RawRouterScrollBehavior = 'top' | RouterScrollBehavior;
declare module 'vue' {
  interface ComponentCustomOptions {
    scrollBehavior?: RawRouterScrollBehavior;
  }
}
type ScrollBehaviorMessengerFn = (canceled: boolean) => any;
declare class ScrollBehaviorMessenger {
  private static fns;
  static trigger(): void;
  static reserveNextPosition(position: any): Promise<any>;
  static release(): void;
}
declare function createScrollBehavior(): RouterScrollBehavior;
//#endregion
//#region src/composables/page-error.d.ts
interface VuePageControlErrorSettings {
  statusCode?: number;
  message?: string;
  stack?: string;
}
declare function isVuePageControlError(source: unknown): source is VuePageControlError;
declare class VuePageControlError extends Error {
  readonly name = "VuePageControlError";
  readonly statusCode: number;
  constructor(rawSettings?: VuePageControlErrorSettings | unknown | string | Error);
  toJSON(): {
    name: string;
    statusCode: number;
    message: string;
    stack: string | undefined;
  };
}
//#endregion
//#region src/composables/state.d.ts
type StateInjectionKey<T extends object> = string;
declare function useState<T extends object>(key: StateInjectionKey<T>): T | undefined;
declare function useState<T extends object>(key: StateInjectionKey<T>, defaultValue: T | (() => T)): T;
declare function provideState<T extends object>(key: StateInjectionKey<T>, value: T): void;
//#endregion
//#region src/composables/page-control.d.ts
type InitialState = Record<string, unknown>;
type VuePageInjectionKey<T> = string;
type VuePagePrefetchFn = (this: void, queue: VuePagePrefetchQueue) => void | Promise<void>;
type RawPrefetchContext = VuePagePrefetchFn | PrefetchContext;
interface WrittenResponse {
  status?: number;
  statusText?: string;
  headers?: Record<string, string>;
}
type WriteResponseFn = (params: WrittenResponse) => void;
type RedirectFn = (location: string, status?: number) => void;
interface PrefetchHandlerContext {
  control: VuePageControl;
  to: RouteLocationNormalized;
  from: RouteLocationNormalized;
  matched: {
    from?: RouteMatchedItem;
    to: RouteMatchedItem;
  };
  pageKey: string;
}
type PrefetchHandler = (ctx: PrefetchHandlerContext) => boolean | void;
declare module 'vue' {
  interface ComponentCustomOptions {
    prefetch?: RawPrefetchContext;
    prefetchHandler?: PrefetchHandler;
    watchQuery?: WatchQueryOption;
    middleware?: VuePageControlMiddlewareFn | VuePageControlMiddlewareFn[];
  }
}
interface RouteMatchedItemWithPrefetch extends RouteMatchedItem {
  prefetch?: RawPrefetchContext;
  middleware: VuePageControlMiddlewareFn[];
  updateQueries(queries: string[]): void;
}
interface RequiredRouteMatchedItemWithPrefetch extends RouteMatchedItemWithPrefetch {
  prefetch: RawPrefetchContext;
}
declare function extractRouteMatchedItemsWithPrefetch(control: VuePageControl, to: RouteLocationNormalized, from: RouteLocationNormalized): {
  extracted: RouteMatchedItemWithPrefetch[];
  matched: RouteMatchedItem[];
};
type VuePageControlMiddlewareFn = (ctx: VuePageControl) => void | Promise<void>;
declare function createMiddleware(source: VuePageControlMiddlewareFn): VuePageControlMiddlewareFn;
type RedirectOptions = {
  statusCode?: number;
};
type RawVuePageControlRedirectSpec = string | (RouteQueryAndHash & MatcherLocationAsPath & RedirectOptions) | (RouteQueryAndHash & LocationAsRelativeRaw & RedirectOptions);
interface VuePageControlRedirectSpec extends RouteQueryAndHash, MatcherLocationAsPath, Omit<LocationAsRelativeRaw, 'path'> {
  statusCode: number;
  query?: LocationQueryRaw;
}
interface VuePageControlSettings {
  app: App;
  router: Router;
  RouterLink?: any;
  useLink?: typeof useLink;
  initialState?: InitialState;
  initialRoute: ResolvedRouteLocation;
  ErrorComponent?: Component;
  request?: IncomingMessage;
  response?: ServerResponse;
  serverRedirect?: RedirectFn;
  writeResponse?: WriteResponseFn;
  middleware?: VuePageControlMiddlewareFn[];
}
type RawProvided<T> = T | ((queue: VuePagePrefetchQueue) => T | Promise<T>);
interface VuePagePrefetchProgress {
  resolved: number;
  total: number;
  per: number;
  finished: boolean;
}
interface VuePageControlEventMap {
  start: VuePagePrefetchProgress;
  finish: VuePagePrefetchProgress;
  error: VuePageControlError;
}
declare class VuePageControl extends EV<VuePageControlEventMap> {
  readonly app: App;
  readonly router: Router;
  readonly cookies: Cookies;
  readonly RouterLink: typeof RouterLink;
  readonly useLink: typeof useLink;
  private _from;
  private _to;
  private _initialState;
  private _beforeRoute;
  private _route;
  private _stopFn?;
  private _prefetchQueues;
  private _initialStateConsumed;
  private _runningQueues;
  private _preftechProgress;
  private _suspenseComponents;
  private _err;
  private _ErrorComponent;
  readonly request?: IncomingMessage;
  readonly response?: ServerResponse;
  private readonly _serverRedirect?;
  private readonly _writeResponse?;
  readonly isClient: boolean;
  readonly middleware: VuePageControlMiddlewareFn[];
  private _redirectSpec?;
  private _providedMap;
  private _transitioning;
  private _serverRedirected;
  get isServer(): boolean;
  get serverRedirected(): boolean;
  get from(): import("vue-router").RouteLocationNormalizedGeneric | null;
  get to(): import("vue-router").RouteLocationNormalizedGeneric | null;
  get initialState(): InitialState;
  get beforeRoute(): ResolvedRouteLocation | null;
  get route(): ResolvedRouteLocation;
  get prefetchQueues(): VuePagePrefetchQueue[];
  get initialStateConsumed(): boolean;
  get runningQueues(): VuePagePrefetchQueue[];
  get preftechProgress(): VuePagePrefetchProgress;
  get suspenseComponents(): VNode<import("vue").RendererNode, import("vue").RendererElement, {
    [key: string]: any;
  }>[];
  get pageError(): VuePageControlError | null;
  get ErrorComponent(): Component;
  get transitioning(): boolean;
  constructor(settings: VuePageControlSettings);
  /** @private */
  _getQueryBucket(provideKey: string): string[];
  /** @private */
  _pushQueryToBucket(provideKey: string, query: string): void;
  initState<T extends object>(key: StateInjectionKey<T>, initializer: () => T | Promise<T>): Promise<T>;
  useState<T extends object>(key: StateInjectionKey<T>): T | undefined;
  useState<T extends object>(key: StateInjectionKey<T>, defaultValue: T | (() => T)): T;
  provide<T>(key: InjectionKey<T> | string, value: T): void;
  inject<T>(key: InjectionKey<T> | string): T | undefined;
  inject<T>(key: InjectionKey<T> | string, defaultValue: T, treatDefaultAsFactory?: false): T;
  inject<T>(key: InjectionKey<T> | string, defaultValue: T | (() => T), treatDefaultAsFactory: true): T;
  addMiddleware(middleware: VuePageControlMiddlewareFn): void;
  writeResponse(params: WrittenResponse): void;
  onSuspensePending(Component: VNode): void;
  onSuspenseResolved(Component: VNode): void;
  setInitialState(key: string, data: any): void;
  consumeInitialState(key: string): unknown;
  injectData<T, D extends T | undefined, N extends boolean>(key: VuePageInjectionKey<T>, defaultData?: D, allowNull?: N): D extends T ? T : N extends true ? T | D : T;
  private _stop;
  private _init;
  private _handleAfterEach;
  private _closePrefetchs;
  redirect(redirectSpec: RawVuePageControlRedirectSpec): void;
  private _triggerRedirect;
  private _handleBeforeResolve;
  private _deletePageError;
  private _setPageError;
  private _writeStates;
}
interface VuePagePrefetchQueueEventMap {
  close: void;
}
declare class VuePagePrefetchQueue extends EV<VuePagePrefetchQueueEventMap> {
  readonly control: VuePageControl;
  readonly item: RouteMatchedItemWithPrefetch;
  readonly route: RouteLocationNormalized;
  private readonly _resolved;
  private readonly _canceled;
  private readonly _running;
  private _resolvedData?;
  /** @private */
  _providePromise?: Promise<any>;
  /** @private */
  _provideKey?: string;
  /** @private */
  _setupPromise?: void | Promise<void>;
  get resolved(): boolean;
  get canceled(): boolean;
  get provideKey(): string | undefined;
  get resolvedData(): any;
  get params(): import("vue-router").RouteParamsGeneric;
  get query(): import("vue-router").LocationQuery;
  get running(): boolean;
  constructor(control: VuePageControl, item: RequiredRouteMatchedItemWithPrefetch, to: RouteLocationNormalized);
  getQuery(key: string): string | undefined;
  getQuery(key: string, type: undefined, defaultValue: string): string;
  getQuery(key: string, type: StringConstructor): string | undefined;
  getQuery(key: string, type: StringConstructor, defaultValue: string): string;
  getQuery(key: string, type: NumberConstructor): number | undefined;
  getQuery(key: string, type: NumberConstructor, defaultValue: number): number;
  getQuery(key: string, type: BooleanConstructor): boolean;
  getQuery(key: string, type: BooleanConstructor, defaultValue: boolean): boolean;
  close(): void;
  cancel(): void;
  provide<T>(key: VuePageInjectionKey<T>, data: RawProvided<T>): Promise<any>;
  injectOtherQueue<T, D extends T | undefined>(key: VuePageInjectionKey<T>, defaultData?: D): Promise<T | D>;
}
interface UseVuePageControlOptions {
  onStart?: (progress: VuePagePrefetchProgress) => any;
  onFinish?: (progress: VuePagePrefetchProgress) => any;
  onError?: (error: VuePageControlError) => any;
}
type PrefetchContext<T = any> = {
  key: VuePageInjectionKey<T>;
  prefetch: VuePagePrefetchFn;
  inject: <D extends T | undefined, N extends boolean = false>(defaultValue?: D, allowNull?: N) => D extends T ? T : N extends true ? T | D : T;
};
declare function createPrefetch<T>(key: VuePageInjectionKey<T>, data: RawProvided<T>): PrefetchContext<T>;
//#endregion
//#region src/composables/plugin.d.ts
declare module 'vue' {
  interface ComponentCustomProperties {
    $vpc: VuePageControl;
  }
}
declare function installVuePageControl(settings: VuePageControlSettings): VuePageControl;
//#endregion
//#region src/components/VPage.d.ts
declare const VPage: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
  pageKey: {
    type: PropType<VuePageKeyOverride>;
    default: null;
  };
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
  pageKey: {
    type: PropType<VuePageKeyOverride>;
    default: null;
  };
}>> & Readonly<{}>, {
  pageKey: VuePageKeyOverride;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
//#endregion
//#region src/components/VPageProgress/VPageProgress.d.ts
declare const VPageProgress: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
  color: StringConstructor;
  failedColor: StringConstructor;
  height: {
    type: import("vue").PropType<import("@fastkit/vue-utils").Numberish>;
  };
  throttle: {
    type: import("vue").PropType<import("@fastkit/vue-utils").Numberish>;
  };
  duration: {
    type: import("vue").PropType<import("@fastkit/vue-utils").Numberish>;
  };
  continuous: BooleanConstructor;
  rtl: BooleanConstructor;
}>, () => import("vue/jsx-runtime").JSX.Element | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
  color: StringConstructor;
  failedColor: StringConstructor;
  height: {
    type: import("vue").PropType<import("@fastkit/vue-utils").Numberish>;
  };
  throttle: {
    type: import("vue").PropType<import("@fastkit/vue-utils").Numberish>;
  };
  duration: {
    type: import("vue").PropType<import("@fastkit/vue-utils").Numberish>;
  };
  continuous: BooleanConstructor;
  rtl: BooleanConstructor;
}>> & Readonly<{}>, {
  continuous: boolean;
  rtl: boolean;
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
//#endregion
//#region src/components/VPageLink.d.ts
declare const VPageLink: typeof RouterLink;
//#endregion
//#region src/components/VPageRoot/VPageRoot.d.ts
declare const VPageRoot: import("vue").DefineComponent<{}, () => import("vue/jsx-runtime").JSX.Element | never[], {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
//#endregion
//#region src/components/VErrorPage/VErrorPage.d.ts
declare const VErrorPage: import("vue").DefineComponent<{}, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
//#endregion
//#region src/injections.d.ts
declare const VuePageControlInjectionKey: InjectionKey<VuePageControl>;
declare function useVuePageControl(opts?: UseVuePageControlOptions): VuePageControl;
//#endregion
export { PrefetchContext, PrefetchHandler, PrefetchHandlerContext, RawPrefetchContext, RawRouterScrollBehavior, RawVuePageControlRedirectSpec, RedirectFn, ResolvedRouteLocation, RouterViewSlotProps, ScrollBehaviorMessenger, ScrollBehaviorMessengerFn, StateInjectionKey, SuspenseRouteBucketEventMap, SuspenseRouteBucketPayload, SuspenseRouteBucketProgress, SuspenseRouteSource, UseVuePageControlOptions, VErrorPage, VPage, VPageLink, VPageProgress, VPageRoot, VuePageControl, VuePageControlError, VuePageControlErrorSettings, VuePageControlEventMap, VuePageControlInjectionKey, VuePageControlMiddlewareFn, VuePageControlRedirectSpec, VuePageControlSettings, VuePageInjectionKey, VuePageKeyOverride, VuePagePrefetchFn, VuePagePrefetchProgress, VuePagePrefetchQueue, VuePagePrefetchQueueEventMap, WatchQueryOption, WriteResponseFn, WrittenResponse, createMiddleware, createPrefetch, createScrollBehavior, extractRouteMatchedItemsWithPrefetch, getSuspenseRouteBucket, installVuePageControl, isVuePageControlError, provideState, useState, useVuePageControl };
