import * as __site from '~/site';
import { UserConfig as UserConfig$1, ConfigEnv, PluginOption, ResolveFn } from 'vite';
export { ConfigEnv, UserConfig as ViteOptions } from 'vite';
import { GetManualChunk } from 'rollup';
import { DefineComponent, Ref, VNode, AsyncComponentLoader, App } from 'vue';
import VuePlugin, { Options as Options$1 } from '@vitejs/plugin-vue';
import ComponentsPlugin from 'unplugin-vue-components/vite';
import { Options as Options$2 } from 'unplugin-vue-components/types';
import { Options } from 'vite-plugin-solid';
import { Options as Options$3 } from '@sveltejs/vite-plugin-svelte';
export { Options as SvelteOptions } from '@sveltejs/vite-plugin-svelte';
import { PreactPluginOptions } from '@preact/preset-vite';
export { PreactPluginOptions as PreactOptions } from '@preact/preset-vite';
import { RouterOptions as RouterOptions$1, RouteComponent, RouteLocationNormalizedLoaded, Router, RouteRecordRaw, RouteParams, RouteRecordNormalized } from 'vue-router';
export { RouteLocationNormalizedLoaded, RouteMeta, RouteRecordRaw, Router } from 'vue-router';
import { HeadObject, HeadClient } from '@unhead/vue';
import { PageMeta, PageFrontmatter, PagesApi, PagesOptions } from '@islands/pages';
export { PageFrontmatter, PageMeta, RawPageMatter } from '@islands/pages';
import { MarkdownOptions } from '@islands/mdx';
export { OnLoadFn } from '@islands/hydration/dist/vanilla';

type RouterOptions = RouterOptions$1 & { base?: string }

interface PageProps extends Record<string, any> {}

type SolidOptions = Partial<Options>


interface WithFrontmatter extends PageFrontmatter, PageMeta {
  frontmatter: PageFrontmatter
  meta: PageMeta
}

interface PageComponent extends RouteComponent, WithFrontmatter {
  layoutName: string
  layoutFn: false | (() => Promise<DefineComponent>)
  getStaticPaths?: GetStaticPaths
  staticPaths: Ref<StaticPath<any>[]>
  render?: (props?: any) => VNode<any, any, any>
}

type Document<T = void> = AsyncComponentLoader<PageComponent & T> & WithFrontmatter & {
  component: () => Promise<PageComponent & T>
} & T

interface PageData<T = PageProps> {
  readonly page: Ref<PageComponent>
  readonly route: RouteLocationNormalizedLoaded
  readonly props: T
  readonly meta: PageMeta
  readonly frontmatter: PageFrontmatter
  readonly site: UserSite
}

type HeadConfig = HeadObject

interface CreateAppConfig {
  /**
   * Current router path on SSG, `undefined` on client side.
   */
  routePath?: string
  /**
   * Props for the current page on SSG, `undefined` on client side.
   */
  ssrProps?: any
}

interface AppContext extends PageData {
  app: App
  config: AppClientConfig
  head: HeadClient
  router: Router
  routes: RouteRecordRaw[]
}

interface StaticPath<T = Record<string, any>> {
  params: RouteParams
  props: T
}

interface RouteToRender {
  path: string
  ssrProps: StaticPath['props']
  outputFilename: string
  rendered: string
}

interface GetStaticPathsArgs {
  route: RouteLocationNormalizedLoaded | RouteRecordNormalized
}

type GetStaticPaths<T = any> = (args: GetStaticPathsArgs) => StaticPath<T>[] | Promise<StaticPath<T>[]>

type CreateAppFactory = (options?: CreateAppConfig) => Promise<AppContext>

type LayoutFactory = (name: string | false) => any

interface NamedPlugins {
  pages: { api: PagesApi }
  vue: ReturnType<typeof VuePlugin>
  components: ReturnType<typeof ComponentsPlugin>
}

interface SSGContext {
  config: AppConfig
  pages: RouteToRender[]
}

interface BaseIlesConfig extends PagesOptions {
  /**
   * Configuration options for Vite.js
   */
  vite: UserConfig$1
  /**
   * Configuration options for @vitejs/plugin-vue
   */
  vue: Options$1
  /**
   * Configuration options for unplugin-vue-components, which manages automatic
   * imports for components in Vue and MDX files.
   */
  components: Options$2
  /**
   * Configuration options for @preact/preset-vite
   */
  preact?: boolean | PreactPluginOptions
  /**
   * Configuration options for vite-plugin-solid
   */
  solid?: boolean | SolidOptions
  /**
   * Configuration options for @sveltejs/vite-plugin-svelte
   */
  svelte?: boolean | Options$3
  /**
   * Configuration options for markdown processing in îles, including remark
   * and rehype plugins.
   */
  markdown: MarkdownOptions
  /**
   * Options for iles build.
   */
  ssg: {
    /**
     * This hook will be invoked before îles renders a page.
     * Plugins may alter the rendered HTML
     */
    beforePageRender?: (page: RouteToRender, config: AppConfig) => RouteToRender | void | Promise<void | RouteToRender>
    /**
     * This hook will be invoked once îles has bundled client, SSR, and islands.
     */
    onSiteBundled?: (context: SSGContext) => void | Promise<void>
    /**
     * This hook will be invoked once îles has rendered the entire site.
     */
    onSiteRendered?: (context: SSGContext) => void | Promise<void>
    /**
     * Allows to configure how JS chunks for islands should be grouped.
     */
    manualChunks?: GetManualChunk
    /**
     * Whether to generate a sitemap.xml and inject the meta tag referencing it.
     * NOTE: Must provide siteUrl to enable sitemap generation.
     * @default true
     */
    sitemap?: boolean
  }
}

interface IlesModule extends Partial<BaseIlesConfig> {
  name: string
  config?: (config: UserConfig, env: ConfigEnv) => UserConfig | null | void | Promise<UserConfig | null | void>
  configResolved?: (config: AppConfig, env: ConfigEnv) => void | Promise<void>
}

type EnhanceAppContext = AppContext
type MDXComponents = Record<string, any>

interface UserApp {
  head?: HeadConfig | ((ctx: EnhanceAppContext) => HeadConfig)
  enhanceApp?: (ctx: EnhanceAppContext) => void | Promise<void>
  mdxComponents?: MDXComponents | ((ctx: EnhanceAppContext) => MDXComponents | Promise<MDXComponents>)
  router?: Omit<RouterOptions$1, 'history', 'routes'>
  socialTags?: boolean
}

type UserSite = typeof __site.default & {
  url: string
  canonical: string
}

type IlesModuleLike = IlesModule | IlesModule[] | false | null | undefined
type IlesModuleOption = IlesModuleLike | Promise<IlesModuleLike> | string | [string, any]

interface RequiredConfig {
  /**
   * URL for site in production, used to generate absolute URLs for sitemap.xml
   * and social meta tags. Available as `site.url` and `site.canonical`.
   * @type {string}
   */
  siteUrl: string
  /**
   * Whether to enable SPA-like navigation by avoiding full-page reloads.
   * @default false
   */
  turbo: boolean
  /**
   * Whether to output more information about islands and hydration in development.
   * @default true
   */
  debug: boolean | 'log'
  /**
   * Which framework to use to process `.jsx` and `.tsx` files.
   */
  jsx?: 'vue' | 'preact' | 'solid'
  /**
   * Whether to skip `.html` in hrefs and router paths.
   * @default true
   */
  prettyUrls: boolean
  /**
   * Specify the output directory (relative to project root).
   * @default 'dist'
   */
  outDir: string
  /**
   * Specify the pages directory (relative to srcDir).
   * @default 'pages'
   */
  pagesDir: string
  /**
   * Specify the layouts directory (relative to srcDir).
   * @default 'layouts'
   */
  layoutsDir: string
  /**
   * Specify the directory where the app source is located (relative to project root).
   * @default 'src'
   */
  srcDir: string
  tempDir: string
  /**
   * Specify the directory to nest generated assets under (relative to outDir).
   * @default 'assets'
   */
  assetsDir: string
}

interface UserConfig extends Partial<RequiredConfig>, Partial<IlesModule> {
  /**
   * Whether to display drafts in documents and pages.
   */
  drafts?: boolean
  modules?: IlesModuleOption[]
}

interface AppConfig extends RequiredConfig, Omit<BaseIlesConfig, 'pagesDir'> {
  base: string
  root: string
  drafts: boolean
  configPath: string
  modules: IlesModule[]
  namedPlugins: NamedPlugins
  vitePlugins: PluginOption[]
  resolvePath: ResolveFn
}

type AppClientConfig = Pick<AppConfig, 'base' | 'root' | 'debug' | 'siteUrl' | 'jsx'> & {
  overrideElements?: MarkdownOptions['overrideElements']
  sitemap?: boolean
}

interface IslandDefinition {
  id: string
  script: string
  placeholder: string
  componentPath: string
  entryFilename?: string
}

type IslandsByPath = Record<string, IslandDefinition[]>

type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T

export type { AppClientConfig, AppConfig, AppContext, Awaited, BaseIlesConfig, CreateAppConfig, CreateAppFactory, Document, GetStaticPaths, HeadConfig, IlesModule, IlesModuleLike, IlesModuleOption, IslandDefinition, IslandsByPath, LayoutFactory, MDXComponents, NamedPlugins, PageComponent, PageData, PageProps, RouteToRender, RouterOptions, SSGContext, SolidOptions, StaticPath, UserApp, UserConfig, UserSite };
