import { PreprocessorGroup, Processed } from 'svelte/compiler';
import { Plugin, PluggableList } from 'unified';
import * as unified from 'unified';
export { unified as Unified };
export { Plugin } from 'unified';
import { Element, Root } from 'hast';
import * as hast from 'hast';
export { hast as Hast };
import * as vfile from 'vfile';
export { vfile as VFile };
import * as mdast from 'mdast';
export { mdast as Mdast };

interface HighlighterData {
    lang: string | undefined;
    meta: string | undefined;
    code: string | undefined;
}
type Highlighter = (data: HighlighterData) => Promise<string | undefined> | string | undefined;
interface HighlightOptions {
    /**
     * Specifies custom syntax highlighter.
     *
     * @default undefined
     */
    highlighter?: Highlighter;
    /**
     * Specifies custom options for the `root` node (usually the `<pre>` tag).
     *
     * @default undefined
     */
    root?: (node: Element) => void;
}

/**
 * A custom `Rehype` plugin that creates code highlighter.
 *
 * @example
 *
 * ```ts
 * import { rehypeHighlight } from '@sveltek/markdown'
 *
 * svelteMarkdown({
 *   plugins: {
 *     rehype: [[rehypeHighlight, options]]
 *   }
 * })
 * ```
 */
declare const rehypeHighlight: Plugin<[HighlightOptions], Root>;

type PluginList = PluggableList;
interface Plugins {
    remark?: PluginList;
    rehype?: PluginList;
}

type Frontmatter = Record<string, unknown> & {
    /**
     * Specifies frontmatter global data to be applied to all markdown files.
     *
     * @default undefined
     */
    defaults?: Record<string, unknown>;
    /**
     * Specifies support for parsing Svelte `special` elements such as `svelte:head` etc. in markdown files.
     *
     * Can be enabled at the **top-level** (via config) or at the **file-level** (via frontmatter).
     *
     * If you don't plan to use them in every markdown file, it is recommended to enable the option only on those pages where you really need it.
     *
     * @default undefined
     */
    specialElements?: boolean;
    /**
     * Specifies at the **file-level** whether plugins will be used or not.
     *
     * Useful if you want to completely disable plugins in a specific markdown file.
     *
     * @default undefined
     */
    plugins?: {
        remark?: false;
        rehype?: false;
    };
    /**
     * Specifies layout name.
     *
     * To disable the layout, simply set it to `layout: false`.
     *
     * Also, it is possible to specify at the **file-level** whether layout plugins will be used or not.
     *
     * Useful if you want to completely disable layout plugins in a specific markdown file.
     *
     * @default undefined
     */
    layout?: string | false | {
        name: string;
        plugins?: {
            remark?: false;
            rehype?: false;
        };
    };
    /**
     * Specifies entry name.
     *
     * Also, it is possible to specify at the **file-level** whether entry plugins will be used or not.
     *
     * Useful if you want to completely disable entry plugins in a specific markdown file.
     *
     * @default undefined
     */
    entry?: string | false | {
        name: string;
        plugins?: {
            remark?: false;
            rehype?: false;
        };
    };
};

interface Layout {
    /**
     * Specifies the path to the layout file.
     */
    path: string;
    /**
     * Specifies the **layout-specific** plugins that will only be applied to markdown files that use this layout.
     *
     * Also, these plugins will run after the **top-level** plugins.
     *
     * @default undefined
     */
    plugins?: {
        /**
         * Specifies custom `remark` plugins at the **layout-level**.
         *
         * Parses source into a Markdown AST (MDAST).
         *
         * @default undefined
         */
        remark?: PluginList;
        /**
         * Specifies custom `rehype` plugins at the **layout-level**.
         *
         * Parses source into a HTML AST (HAST).
         *
         * @default undefined
         */
        rehype?: PluginList;
    };
}
type Layouts = Record<string, Layout>;

interface ASTScript {
    start: number;
    end: number;
    content: string;
}
interface FileData {
    preprocessors?: PreprocessorGroup[];
    plugins?: Plugins;
    dependencies?: string[];
    frontmatter?: Frontmatter;
    components?: string[];
    layout?: Layout;
}

interface Entry {
    /**
     * Specifies the **entry-specific** plugins that will only be applied to this particular markdown file.
     *
     * Also, these plugins will run after **top-level** and **layout-level** plugins.
     *
     * @default undefined
     */
    plugins?: {
        /**
         * Specifies custom `remark` plugins at the **entry-level**.
         *
         * Parses source into a Markdown AST (MDAST).
         *
         * @default undefined
         */
        remark?: PluginList;
        /**
         * Specifies custom `rehype` plugins at the **entry-level**.
         *
         * Parses source into a HTML AST (HAST).
         *
         * @default undefined
         */
        rehype?: PluginList;
    };
}
type Entries = Record<string, Entry>;

interface Highlight {
    /**
     * Specifies custom syntax highlighter.
     *
     * @example
     *
     * ```ts
     * svelteMarkdown({
     *   highlight: {
     *     highlighter: async ({ lang, meta, code }) => {
     *       return code
     *     }
     *   }
     * })
     * ```
     *
     * @default undefined
     */
    highlighter?: Highlighter;
    /**
     * Specifies custom options for the `root` node (usually the `<pre>` tag).
     *
     * @example
     *
     * ```ts
     * svelteMarkdown({
     *   highlight: {
     *     root: (node) => {
     *       node.tagName = 'div'
     *       node.properties.id = 'code-highlight'
     *       // ...
     *     }
     *   }
     * })
     * ```
     *
     * @default undefined
     */
    root?: HighlightOptions['root'];
}

interface MarkdownConfig {
    /**
     * Specifies custom file extensions.
     *
     * @default ['.md']
     */
    extensions?: string[];
    /**
     * Specifies a custom list of preprocessors that will be applied to a Svelte file.
     *
     * @default undefined
     */
    preprocessors?: PreprocessorGroup[];
    /**
     * Defines frontmatter custom options.
     *
     * By default, frontmatter only supports the `YAML` format, but allows additional customization via parser.
     *
     * @default undefined
     */
    frontmatter?: {
        /**
         * Specifies frontmatter global data to be applied to all markdown files.
         *
         * @default undefined
         */
        defaults?: Record<string, unknown>;
        /**
         * Specifies the **start/end** symbols for the frontmatter content block.
         *
         * It only works in combination with the default parser.
         *
         * @default '-'
         */
        marker?: string;
        /**
         * Specifies a custom parser for frontmatter.
         *
         * Allows adaptation to other formats such as `TOML` or `JSON`.
         *
         * @default undefined
         */
        parser?: (value: string) => Record<string, unknown> | void;
    };
    /**
     * Specifies the **top-level** plugins that will be used for all markdown files.
     *
     * @default undefined
     */
    plugins?: {
        /**
         * Specifies custom `remark` plugins at the **top-level**.
         *
         * Parses source into a Markdown AST (MDAST).
         *
         * @default undefined
         */
        remark?: PluginList;
        /**
         * Specifies custom `rehype` plugins at the **top-level**.
         *
         * Parses source into a HTML AST (HAST).
         *
         * @default undefined
         */
        rehype?: PluginList;
    };
    /**
     * Specifies a custom layout records.
     *
     * Layout component serves as a wrapper for the markdown files, which means the page content is displayed via the component's children prop.
     *
     * Can be enabled at the **top-level** (via config) or at the **file-level** (via frontmatter).
     *
     * @default undefined
     */
    layouts?: Layouts;
    /**
     * Specifies a custom entry records.
     *
     * Entry serves as a special configuration for markdown files, which means it is similar to layout but without the need to create a custom component file.
     *
     * Allows unique and straightforward customization for an individual markdown file. An entry can be a page or a component.
     *
     * Can be enabled at the **top-level** (via config) or at the **file-level** (via frontmatter).
     *
     * @default undefined
     */
    entries?: Entries;
    /**
     * Defines custom syntax highlighting options.
     *
     * @default undefined
     */
    highlight?: Highlight;
}

interface CompileOptions {
    filename?: string;
    config?: MarkdownConfig;
}

/**
 * Defines configuration via custom `options` object that contains all available settings.
 *
 * @example
 *
 * ```ts
 * import { defineConfig } from '@sveltek/markdown'
 *
 * export const markdownConfig = defineConfig({
 *   frontmatter: {
 *     defaults: {
 *       layout: 'default',
 *       author: 'Sveltek',
 *     },
 *   },
 *   layouts: {
 *     default: {
 *       path: 'lib/content/layouts/default/layout.svelte',
 *     },
 *   },
 * })
 * ```
 */
declare function defineConfig(config: MarkdownConfig): MarkdownConfig;

declare function compile(source: string, { filename, config }: CompileOptions): Promise<Processed>;

/**
 * Svelte Markdown Preprocessor.
 *
 * @example
 *
 * ```ts
 * // svelte.config.js
 * import adapter from '@sveltejs/adapter-static'
 * import { svelteMarkdown } from '@sveltek/markdown'
 *
 * const config = {
 *   kit: { adapter: adapter() },
 *   preprocess: [svelteMarkdown()],
 *   extensions: ['.svelte', '.md'],
 * }
 *
 * export default config
 * ```
 *
 * @see [Repository](https://github.com/sveltek/markdown)
 */
declare function svelteMarkdown(config?: MarkdownConfig): PreprocessorGroup;

export { compile, defineConfig, rehypeHighlight, svelteMarkdown };
export type { ASTScript, CompileOptions, Entries, Entry, FileData, Frontmatter, Highlight, HighlightOptions, Highlighter, HighlighterData, Layout, Layouts, MarkdownConfig, PluginList, Plugins };
