import * as unified from 'unified';
import * as hast from 'hast';
import * as mdast from 'mdast';
import React from 'react';
import { HTMLReactParserOptions } from 'html-react-parser';
import { Hookified } from 'hookified';
import { CacheableMemory } from 'cacheable';

declare class WritrCache {
    private readonly _store;
    private readonly _hashStore;
    get store(): CacheableMemory;
    get hashStore(): CacheableMemory;
    get(markdown: string, options?: RenderOptions): string | undefined;
    set(markdown: string, value: string, options?: RenderOptions): void;
    clear(): void;
    hash(markdown: string, options?: RenderOptions): string;
}

/**
 * Writr options.
 * @typedef {Object} WritrOptions
 * @property {RenderOptions} [renderOptions] - Default render options (default: undefined)
 * @property {boolean} [throwErrors] - Throw error (default: false)
 */
type WritrOptions = {
    renderOptions?: RenderOptions;
    throwErrors?: boolean;
};
/**
 * Render options.
 * @typedef {Object} RenderOptions
 * @property {boolean} [emoji] - Emoji support (default: true)
 * @property {boolean} [toc] - Table of contents generation (default: true)
 * @property {boolean} [slug] - Slug generation (default: true)
 * @property {boolean} [highlight] - Code highlighting (default: true)
 * @property {boolean} [gfm] - Github flavor markdown (default: true)
 * @property {boolean} [math] - Math support (default: true)
 * @property {boolean} [mdx] - MDX support (default: true)
 * @property {boolean} [caching] - Caching (default: false)
 */
type RenderOptions = {
    emoji?: boolean;
    toc?: boolean;
    slug?: boolean;
    highlight?: boolean;
    gfm?: boolean;
    math?: boolean;
    mdx?: boolean;
    caching?: boolean;
};
declare enum WritrHooks {
    beforeRender = "beforeRender",
    afterRender = "afterRender",
    saveToFile = "saveToFile",
    renderToFile = "renderToFile",
    loadFromFile = "loadFromFile"
}
declare class Writr extends Hookified {
    engine: unified.Processor<mdast.Root, mdast.Root, hast.Root, hast.Root, string>;
    private readonly _options;
    private _content;
    private readonly _cache;
    /**
     * Initialize Writr. Accepts a string or options object.
     * @param {string | WritrOptions} [arguments1] If you send in a string, it will be used as the markdown content. If you send in an object, it will be used as the options.
     * @param {WritrOptions} [arguments2] This is if you send in the content in the first argument and also want to send in options.
     *
     * @example
     * const writr = new Writr('Hello, world!', {caching: false});
     */
    constructor(arguments1?: string | WritrOptions, arguments2?: WritrOptions);
    /**
     * Get the options.
     * @type {WritrOptions}
     */
    get options(): WritrOptions;
    /**
     * Get the Content. This is the markdown content and front matter if it exists.
     * @type {WritrOptions}
     */
    get content(): string;
    /**
     * Set the Content. This is the markdown content and front matter if it exists.
     * @type {WritrOptions}
     */
    set content(value: string);
    /**
     * Get the cache.
     * @type {WritrCache}
     */
    get cache(): WritrCache;
    /**
     * Get the front matter raw content.
     * @type {string} The front matter content including the delimiters.
     */
    get frontMatterRaw(): string;
    /**
     * Get the body content without the front matter.
     * @type {string} The markdown content without the front matter.
     */
    get body(): string;
    /**
     * Get the markdown content. This is an alias for the body property.
     * @type {string} The markdown content.
     */
    get markdown(): string;
    /**
     * Get the front matter content as an object.
     * @type {Record<string, any>} The front matter content as an object.
     */
    get frontMatter(): Record<string, any>;
    /**
     * Set the front matter content as an object.
     * @type {Record<string, any>} The front matter content as an object.
     */
    set frontMatter(data: Record<string, any>);
    /**
     * Get the front matter value for a key.
     * @param {string} key The key to get the value for.
     * @returns {T} The value for the key.
     */
    getFrontMatterValue<T>(key: string): T;
    /**
     * Render the markdown content to HTML.
     * @param {RenderOptions} [options] The render options.
     * @returns {Promise<string>} The rendered HTML content.
     */
    render(options?: RenderOptions): Promise<string>;
    /**
     * Render the markdown content to HTML synchronously.
     * @param {RenderOptions} [options] The render options.
     * @returns {string} The rendered HTML content.
     */
    renderSync(options?: RenderOptions): string;
    /**
     * Render the markdown content and save it to a file. If the directory doesn't exist it will be created.
     * @param {string} filePath The file path to save the rendered markdown content to.
     * @param {RenderOptions} [options] the render options.
     */
    renderToFile(filePath: string, options?: RenderOptions): Promise<void>;
    /**
     * Render the markdown content and save it to a file synchronously. If the directory doesn't exist it will be created.
     * @param {string} filePath The file path to save the rendered markdown content to.
     * @param {RenderOptions} [options] the render options.
     */
    renderToFileSync(filePath: string, options?: RenderOptions): void;
    /**
     * Render the markdown content to React.
     * @param {RenderOptions} [options] The render options.
     * @param {HTMLReactParserOptions} [reactParseOptions] The HTML React parser options.
     * @returns {Promise<string | React.JSX.Element | React.JSX.Element[]>} The rendered React content.
     */
    renderReact(options?: RenderOptions, reactParseOptions?: HTMLReactParserOptions): Promise<string | React.JSX.Element | React.JSX.Element[]>;
    /**
     * Render the markdown content to React synchronously.
     * @param {RenderOptions} [options] The render options.
     * @param {HTMLReactParserOptions} [reactParseOptions] The HTML React parser options.
     * @returns {string | React.JSX.Element | React.JSX.Element[]} The rendered React content.
     */
    renderReactSync(options?: RenderOptions, reactParseOptions?: HTMLReactParserOptions): string | React.JSX.Element | React.JSX.Element[];
    /**
     * Load markdown content from a file.
     * @param {string} filePath The file path to load the markdown content from.
     * @returns {Promise<void>}
     */
    loadFromFile(filePath: string): Promise<void>;
    /**
     * Load markdown content from a file synchronously.
     * @param {string} filePath The file path to load the markdown content from.
     * @returns {void}
     */
    loadFromFileSync(filePath: string): void;
    /**
     * Save the markdown content to a file. If the directory doesn't exist it will be created.
     * @param {string} filePath The file path to save the markdown content to.
     * @returns {Promise<void>}
     */
    saveToFile(filePath: string): Promise<void>;
    /**
     * Save the markdown content to a file synchronously. If the directory doesn't exist it will be created.
     * @param {string} filePath The file path to save the markdown content to.
     * @returns {void}
     */
    saveToFileSync(filePath: string): void;
    private isCacheEnabled;
    private createProcessor;
    private mergeOptions;
    private mergeRenderOptions;
}

export { type RenderOptions, Writr, WritrHooks, type WritrOptions };
