import fs from 'fs';
import { AxiosInstance, AxiosResponse } from 'axios';
import { DocumentIntelligenceClient } from '@azure-rest/ai-document-intelligence';
import TurndownService from 'turndown';

type TextContent = {
    type: "text";
    text: string;
};
type ImageContent = {
    type: "image_url";
    image_url: {
        url: string;
    };
};
type MessageContent = TextContent | ImageContent;
type Message = {
    role: "user" | "assistant" | "system";
    content: MessageContent[];
};
type LlmCallInputParams = {
    messages?: Message[];
    imageBase64?: string;
    file?: fs.ReadStream;
};
type LlmCall = ((params: LlmCallInputParams) => Promise<string | null>) | null | undefined;
interface MarkItDownOptions {
    requestsSession?: AxiosInstance;
    llmCall?: LlmCall;
    styleMap?: any;
    docintelEndpoint?: string | null;
}

/**
 * Abstract base class for document converters.
 * Provides a common interface for all document conversion implementations.
 * @abstract
 */
declare abstract class DocumentConverter {
    /**
     * Lower priority values are tried first.
     * Used for specific file formats like .docx, .pdf, .xlsx, or specific pages like Wikipedia.
     */
    static readonly PRIORITY_SPECIFIC_FILE_FORMAT: number;
    /**
     * Used for near catch-all converters for mimetypes like text/*, etc.
     * These are tried after more specific converters.
     */
    static readonly PRIORITY_GENERIC_FILE_FORMAT: number;
    /**
     * The priority of this converter.
     * @private
     */
    private _priority;
    /**
     * Initialize the DocumentConverter with a given priority.
     *
     * Priorities work as follows: By default, most converters get priority
     * DocumentConverter.PRIORITY_SPECIFIC_FILE_FORMAT (== 0). The exception
     * is the PlainTextConverter, which gets priority PRIORITY_GENERIC_FILE_FORMAT (== 10),
     * with lower values being tried first (i.e., higher priority).
     *
     * Just prior to conversion, the converters are sorted by priority, using
     * a stable sort. This means that converters with the same priority will
     * remain in the same order, with the most recently registered converters
     * appearing first.
     *
     * @param {number} priority - The priority of this converter
     */
    constructor(priority?: number);
    /**
     * Converts a local file to the target format.
     * @abstract
     * @param {string} localPath - The path to the local file to convert
     * @param {ConversionOptions} [options] - Optional conversion configuration
     * @returns {Promise<DocumentConverterResult | null>} A promise that resolves with the conversion result or null if conversion is not applicable
     * @throws {Error} May throw implementation-specific errors during conversion
     */
    abstract convert(localPath: string, options?: ConversionOptions): Promise<DocumentConverterResult | null>;
    /**
     * Gets the priority of the converter in the converter list.
     * Lower values are tried first (higher priority).
     * @returns {number} The priority value
     */
    get priority(): number;
    /**
     * Sets the priority of the converter.
     * @param {number} value - The new priority value
     */
    set priority(value: number);
}

type DocumentConverterResult = {
    title: string | null;
    textContent: string;
} | null;
type ConversionOptions = {
    fileExtension: string;
    parentConverters?: DocumentConverter[];
    url?: string;
    requestsSession?: AxiosInstance;
} & MarkItDownOptions;

/**
 * Converts plain text files to a standard document format.
 * Handles various text-based content types including plain text and JSON files.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const plaintextConverter = new PlainTextConverter();
 * let result = await plaintextConverter.convert('document.txt', {
 *   fileExtension: '.txt'
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert('document.txt');
 * ```
 */
declare class PlainTextConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts a text file to the standard document format.
     * Automatically detects content type based on file extension and only processes
     * files that have text/* MIME types or application/json.
     *
     * @param {string} localPath - Path to the text file
     * @param {ConversionOptions} options - Conversion options including file extension
     * @returns {Promise<DocumentConverterResult>} Object containing the file content as textContent (title is null), or returns null if the file type is not supported
     * @throws {Error} If the file cannot be read or decoded
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
}

/**
 * Converts HTML files to Markdown format.
 * Handles both standalone HTML files and HTML content from other converters.
 * Removes scripts and styles while preserving content structure.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const htmlConverter = new HtmlConverter();
 * let result = await htmlConverter.convert('page.html', { fileExtension: '.html' });
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert('page.html');
 * ```
 */
declare class HtmlConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts an HTML file to Markdown format.
     *
     * @param {string} localPath - Path to the local HTML file
     * @param {ConversionOptions} options - Conversion options
     * @param {string} [options.fileExtension] - File extension (must be .html or .htm)
     * @returns {Promise<DocumentConverterResult>} Conversion result or null if:
     *   - File extension is not .html or .htm
     *   - File cannot be read
     *   - Conversion fails
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
    /**
     * Converts HTML content to Markdown format.
     * Internal method used by both direct HTML conversion and other converters.
     *
     * @param {string} htmlContent - Raw HTML content to convert
     * @returns {DocumentConverterResult} Object containing title and converted markdown content
     *
     * @remarks
     * - Removes all <script> and <style> elements before conversion
     * - Attempts to extract content from <body> first, falls back to entire document
     * - Preserves document title if available
     * - Trims whitespace from the final markdown
     *
     * @protected
     */
    protected _convert(htmlContent: string): DocumentConverterResult;
}

/**
 * Converts RSS, Atom, and XML feeds to markdown format.
 * Supports multiple feed formats with automatic format detection:
 * - RSS feeds (RSS 2.0)
 * - Atom feeds
 * - Generic XML documents
 *
 * @extends HtmlConverter
 *
 * @example
 * ```typescript
 * const rssConverter = new RSSConverter();
 * let xmlResult = await rssConverter.convert('feed.xml', {
 *   fileExtension: ".xml"
 * });
 * let rssResult = await rssConverter.convert('feed.rss', {
 *   fileExtension: ".rss"
 * });
 * let atomResult = await rssConverter.convert('feed.atom', {
 *   fileExtension: ".atom"
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let xmlResult = await converter.convert('feed.xml');
 * let rssResult = await converter.convert('feed.rss');
 * let atomResult = await converter.convert('feed.atom');
 * ```
 */
declare class RSSConverter extends HtmlConverter {
    constructor();
    /**
     * Converts a feed file to markdown format.
     * Automatically detects the feed type (RSS, Atom, or XML) and processes accordingly.
     *
     * @param {string} localPath - Path to the feed file
     * @param {ConversionOptions} options - Conversion options including file extension
     * @returns {Promise<DocumentConverterResult>} Object containing formatted markdown with feed content, or returns null for unsupported file types or parsing failures
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
    /**
     * Parses an Atom feed document into markdown.
     * Extracts feed metadata and entries, including titles, summaries, and content.
     *
     * @param {Document} doc - Parsed XML document
     * @returns {DocumentConverterResult} Formatted markdown content
     * @private
     */
    private _parseAtomType;
    /**
     * Parses an RSS feed document into markdown.
     * Extracts channel metadata and items, including titles, descriptions, and content.
     *
     * @param {Document} doc - Parsed XML document
     * @returns {DocumentConverterResult} Formatted markdown content
     * @private
     */
    private _parseRssType;
    /**
     * Parses a generic XML document into markdown.
     * Creates a hierarchical markdown representation of the XML structure.
     *
     * @param {Document} doc - Parsed XML document
     * @returns {DocumentConverterResult} Formatted markdown content
     * @private
     */
    private _parseXmlType;
    /**
     * Recursively parses XML nodes into a markdown list structure.
     *
     * @param {Element} items - XML element to parse
     * @param {number} tabCount - Current indentation level
     * @returns {string} Formatted markdown content
     * @private
     */
    private _parseXmlNode;
    /**
     * Parses HTML content within feed entries.
     *
     * @param {string} content - HTML content to parse
     * @returns {string} Cleaned content
     * @private
     */
    private _parseContent;
    /**
     * Extracts data from the first child element with the given tag name.
     *
     * @param {HTMLElement} element - Parent element to search
     * @param {string} tagName - Tag name to find
     * @returns {string | null} Content of the first matching element or null
     * @private
     */
    private _getDataByTagName;
}

/**
 * WikipediaConverter class handles the conversion of Wikipedia HTML pages to Markdown format.
 * This class specifically focuses on extracting and formatting the main content while removing
 * unnecessary elements like references, edit sections, and other Wikipedia-specific markup.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const wikipediaConverter = new WikipediaConverter();
 * // first fetch and save the search results in a HTML file
 * let result = await wikipediaConverter.convert("wikipediaFile.html", {
 *   fileExtension: ".html",
 *   url: "https://en.wikipedia.org/wiki/Javascript"
 * })
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert('https://en.wikipedia.org/wiki/Javascript');
 * ```
 */
declare class WikipediaConverter extends DocumentConverter {
    private _turndown;
    /**
     * Initializes a new instance of WikipediaConverter and configures the markdown converter.
     */
    constructor(priority?: number);
    /**
     * Configures the Turndown converter with Wikipedia-specific rules for handling
     * images and references.
     * @private
     */
    private _configureTurndown;
    /**
     * Converts a Wikipedia HTML file to Markdown format.
     * @param {string} localPath - The local file path to the Wikipedia HTML file
     * @param {ConversionOptions} options - Conversion options including file extension and URL
     * @returns {Promise<DocumentConverterResult>} The converted document or null if conversion fails
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
    /**
     * Removes unwanted elements from the Wikipedia content and cleans up the HTML structure.
     * @param {HTMLElement} element - The root element containing Wikipedia content
     * @private
     */
    private cleanupContent;
    /**
     * Creates an anchor ID from text by removing non-alphanumeric characters and converting to lowercase.
     * @param {string} text - The text to convert to an anchor ID
     * @returns {string} The formatted anchor ID
     * @private
     */
    private _createAnchorId;
    /**
     * Parses the Wikipedia content into sections with titles and content.
     * @param {HTMLElement} mainContent - The main content element to parse
     * @returns {Section[]} An array of parsed sections
     * @private
     */
    private parseSections;
    /**
     * Generates a table of contents from the document headings.
     * @param {HTMLElement} root - The root element containing headings
     * @returns {string} Markdown formatted table of contents
     * @private
     */
    private generateTableOfContents;
    /**
     * Generates the final Markdown document from the parsed content.
     * @param {{title: string, sections: Section[]}} content - The parsed document content
     * @param {HTMLElement} root - The root HTML element
     * @returns {string} The complete Markdown document
     * @private
     */
    private generateMarkdown;
}

/**
 * YouTubeConverter handles the conversion of YouTube video pages to Markdown format.
 * Extracts video metadata, description, and transcript when available.
 * Supports both regular YouTube videos and YouTube Shorts.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const ytConverter = new YouTubeConverter();
 * // first fetch and save the youtube results in a HTML file
 * let result = await ytConverter.convert("youtubeVideoFile.html", {
 *   fileExtension: ".html",
 *   url: "https://www.youtube.com/watch?v=abc123"
 * })
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert('https://www.youtube.com/watch?v=abc123');
 * ```
 */
declare class YouTubeConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts a YouTube video page to Markdown format.
     * Extracts video title, metadata, description, and transcript (if available).
     *
     * @param {string} localPath - The local file path to the YouTube page HTML file
     * @param {ConversionOptions} options - Conversion options including file extension and URL
     * @returns {Promise<DocumentConverterResult>} Object containing the converted markdown content, or null if the file is not a YouTube video page
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
    /**
     * Retries an operation with specified number of attempts and delay between retries
     *
     * @param {Function} operation - The async function to retry
     * @param {number} retries - Number of retry attempts
     * @param {number} delay - Delay between retries in milliseconds
     * @returns {Promise<any>} Result of the operation if successful
     * @throws {Error} If all retry attempts fail
     * @private
     */
    private retryOperation;
    /**
     * Retrieves a value from metadata using a list of possible keys.
     *
     * @param {Record<string, any>} metadata - The metadata object to search in
     * @param {string[]} keys - Array of possible keys to look for
     * @param {any} defaultValue - Value to return if no key is found
     * @returns {any} The first found value or the default value
     * @private
     */
    private _get;
    /**
     * Recursively searches for a specific key in a nested object or array.
     *
     * @param {any} obj - The object or array to search in
     * @param {string} key - The key to search for
     * @returns {any} The value associated with the key if found, null otherwise
     * @private
     */
    private _findKey;
}

/**
 * Converts Bing Search Engine Results Pages (SERP) to markdown format.
 * Extracts and formats organic search results from Bing HTML pages.
 *
 * @extends DocumentConverter
 *
 * @remarks
 * This converter only handles organic Bing search results.
 * It is better to use Bing API.
 *
 * @example
 * ```typescript
 * const bingConverter = new BingSerpConverter();
 * // first fetch and save the search results in a HTML file
 * let result = await bingConverter.convert('bingSavedSearch.html', {
 *   url: 'https://www.bing.com/search?q=Javascript',
 *   fileExtension: '.html'
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert('https://www.bing.com/search?q=Javascript');
 * ```
 */
declare class BingSerpConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts a Bing search results page to markdown format.
     * Only processes HTML files from Bing search URLs.
     *
     * @param {string} localPath - Path to the local HTML file
     * @param {ConversionOptions} options - Conversion options
     * @param {string} [options.fileExtension] - File extension (must be .html or .htm)
     * @param {string} [options.url] - Original URL (must be a Bing search URL)
     * @returns {Promise<DocumentConverterResult>} Conversion result containing search results
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
}

/**
 * Converts DOCX files to Markdown format via HTML intermediate conversion.
 * Preserves document structure including headings, tables, and styling where possible.
 *
 * @extends HtmlConverter
 *
 * @example
 * ```typescript
 * const docxConverter = new DocxConverter();
 * let result = await docxConverter.convert('document.docx', {
 *   fileExtension: '.docx',
 *   styleMap: [
 *     "p[style-name='Section Title'] => h1:fresh",
 *     "p[style-name='Subsection Title'] => h2:fresh"
 *   ]
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown({
 *   styleMap: [
 *     "p[style-name='Section Title'] => h1:fresh",
 *     "p[style-name='Subsection Title'] => h2:fresh"
 *   ]
 * });
 * let result = await converter.convert('document.docx');
 * ```
 */
declare class DocxConverter extends HtmlConverter {
    constructor(priority?: number);
    /**
     * Converts a DOCX file to Markdown format.
     * Uses Mammoth.js to convert DOCX to HTML, then processes the HTML to Markdown.
     *
     * @param {string} localPath - Path to the local DOCX file
     * @param {ConversionOptions} options - Conversion options
     * @param {string} [options.fileExtension] - File extension (must be .docx)
     * @param {Array<string>} [options.styleMap] - Custom style mappings for Mammoth.js conversion
     * @returns {Promise<DocumentConverterResult>} Conversion result or null if:
     *   - File is not a DOCX
     *   - File cannot be read
     *   - Conversion fails
     *
     * @throws {Error} If file reading or conversion process fails
     * @override
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
}

/**
 * XlsxConverter handles the conversion of Excel files (XLSX/XLS) to Markdown format.
 * Each sheet in the workbook is converted to a Markdown table with proper formatting.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const xlsxConverter = new XlsxConverter();
 * let result = await xlsxConverter.convert("file.xlsx", {
 *   fileExtension: ".xlsx"
 * })
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert("file.xlsx");
 * ```
 */
declare class XlsxConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts an Excel file to Markdown format.
     * Each sheet is represented as a separate section with a Markdown table.
     *
     * @override
     * @param {string} localPath - The local file path to the Excel file
     * @param {ConversionOptions} options - Conversion options including file extension
     * @returns {Promise<DocumentConverterResult>} Object containing the converted markdown content, or returns null if the file is not an Excel file
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
}

/**
 * Converts PowerPoint PPTX files to markdown format.
 * Only supports .pptx files (modern PowerPoint format), not .ppt files.
 * Each slide is converted to a markdown section with its text content preserved.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const pptxConverter = new PptxConverter();
 * let result = await pptxConverter.convert('presentation.pptx', {
 *   fileExtension: '.pptx'
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert('presentation.pptx');
 * ```
 */
declare class PptxConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts a PPTX file to markdown format.
     * Extracts text from each slide and organizes them in order.
     * Slides are sorted by their ID to maintain presentation order.
     *
     * @param {string} localPath - Path to the PPTX file
     * @param {ConversionOptions} options - Conversion options including file extension
     * @returns {Promise<DocumentConverterResult>} Object containing formatted markdown as textContent (title is null), or returns null for unsupported file types (.ppt files or non-PowerPoint files)
     * @throws {Error} If the file cannot be read or parsed
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
}

/**
 * Abstract base class for media converters.
 * Provides a common interface for all media conversion implementations.
 *
 * @abstract
 *
 * @example
 * ```typescript
 * const converter = new MediaConverter();
 *
 * const metadata = await converter._getMetadata('video.mp4');
 * ```
 */
declare abstract class MediaConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts a local file to the target format.
     * @abstract
     * @param {string} localPath - The path to the local file to convert
     * @param {ConversionOptions} [options] - Optional conversion configuration
     * @returns {Promise<DocumentConverterResult>} A promise that resolves with the conversion result
     * @throws {Error} May throw implementation-specific errors during conversion
     */
    convert(localPath: string, options?: ConversionOptions): Promise<DocumentConverterResult>;
    /**
     * Generates media metadata using exiftool.
     * @param {string} localPath - Path to the local audio file
     * @returns {Promise<Record<string, any> | null>} The transcription text or null if transcription fails or is unavailable
     */
    _getMetadata(localPath: string): Promise<Record<string, any> | null>;
}

/**
 * Converter for audio files that extracts metadata and generates transcriptions.
 * Supports .m4a, .mp3, .mpga, and .wav formats.
 *
 * @extends MediaConverter
 *
 *    * @example
 * ```typescript
 *
 * const AudioConverter = new AudioConverter();
 * let result = await AudioConverter.convert('audio.wav', {
 *   fileExtension: '.wav'
 *   llmCall: async (params) => {
 *     if(params.file) {
 *       const completion = await openai.audio.transcriptions.create({
 *         model: "whisper-1",
 *         file: params.file
 *       });
 *       return completion.text;
 *     }
 *     return null;
 *   }
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown({
 *   llmCall: async (params) => {
 *     if(params.file) {
 *       const completion = await openai.audio.transcriptions.create({
 *         model: "whisper-1",
 *         file: params.file
 *       });
 *       return completion.text;
 *     }
 *     return null;
 *   }
 * });
 * let result = await converter.convert('audio.wav');
 * ```
 */
declare class AudioConverter extends MediaConverter {
    /**
     * Converts an audio file to markdown format, including metadata and transcription.
     * @param {string} localPath - Path to the local audio file
     * @param {ConversionOptions} options - Conversion options including file extension and LLM callback
     * @param {string} options.fileExtension - The file extension of the audio file
     * @param {LlmCall} [options.llmCall] - Callback function for audio transcription
     * @returns {Promise<DocumentConverterResult>} The conversion result or null if file type not supported
     * @override
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
    /**
     * Transcribes audio content using the provided LLM callback function.
     * @param {string} localPath - Path to the local audio file
     * @param {LlmCall} llmCall - Callback function for audio transcription
     * @returns {Promise<string | null>} The transcription text or null if transcription fails or is unavailable
     */
    _transcribeAudio(localPath: string, llmCall: LlmCall): Promise<string | null>;
}

/**
 * Converts video files to markdown format, extracting metadata and optionally transcribing audio.
 * Supports MP4, MKV, WebM, and MPEG formats.
 *
 * Features:
 * - Extracts video metadata (title, artist, date, etc.)
 * - Transcribes audio content when FFmpeg is available
 * - Inherits audio processing capabilities from AudioConverter
 *
 * @extends AudioConverter
 *
 * @example
 * ```typescript
 * const videoConverter = new VideoConverter();
 * let result = await videoConverter.convert('audio.wav', {
 *   fileExtension: ".wav",
 *   llmCall: async (params) => {
 *     if(params.file) {
 *       const completion = await openai.audio.transcriptions.create({
 *         model: "whisper-1",
 *         file: params.file
 *       });
 *       return completion.text;
 *     }
 *   }
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown({
 *   llmCall: async (params) => {
 *     if(params.file) {
 *       const completion = await openai.audio.transcriptions.create({
 *         model: "whisper-1",
 *         file: params.file
 *       });
 *       return completion.text;
 *     }
 *   }
 * });
 * let result = await converter.convert('audio.wav');
 * ```
 */
declare class VideoConverter extends AudioConverter {
    /**
     * Converts a video file to markdown format.
     * Extracts available metadata and optionally transcribes audio content if FFmpeg is available.
     *
     * @param {string} localPath - Path to the video file
     * @param {ConversionOptions} options - Conversion options including:
     *   - fileExtension: The file extension (must be .mp4, .mkv, .webm, or .mpeg)
     *   - llmCall: Optional function for audio transcription
     * @returns {Promise<DocumentConverterResult>} Object containing extracted metadata and optional transcript,or returns null for unsupported file types
     * @throws {Error} If file processing or transcription fails
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
}

/**
 * Converts images to markdown format with enhanced content extraction.
 * Provides three types of information:
 * 1. Image metadata (size, date, location, etc.)
 * 2. OCR-extracted text (requires Tesseract installation)
 * 3. AI-generated image description (requires LLM call as callback)
 *
 * @extends MediaConverter
 *
 * @example
 * ```typescript
 * const imageConverter = new ImageConverter();
 * let result = await imageConverter.convert('photo.jpg', {
 *   fileExtension: '.jpg',
 *   llmCall: async (params) => {
 *     if(params.base64Image) {
 *       const completion = await openai.chat.completions.create({
 *         model: "gpt-4o",
 *         messages: params.messages
 *       });
 *       return completion.choices[0].message.content;
 *     }
 *     return null;
 *   }
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown({
 *   llmCall: async (params) => {
 *     if(params.base64Image) {
 *       const completion = await openai.chat.completions.create({
 *         model: "gpt-4o",
 *         messages: params.messages
 *       });
 *       return completion.choices[0].message.content;
 *     }
 *     return null;
 *   }
 * });
 * let result = await converter.convert('photo.jpg');
 * ```
 */
declare class ImageConverter extends MediaConverter {
    /**
     * Converts an image file to markdown format with metadata, OCR text, and AI description.
     *
     * @param {string} localPath - Path to the local image file
     * @param {ConversionOptions} options - Conversion options
     * @param {string} [options.fileExtension] - File extension (must be .jpg, .jpeg, or .png)
     * @param {LlmCall} [options.llmCall] - Callback function for LLM image description
     * @returns {Promise<DocumentConverterResult>} Conversion result or null if:
     *   - File is not a supported image type
     *   - File cannot be read
     *
     * @remarks
     * The converter attempts to extract three types of information:
     * 1. Metadata fields: ImageSize, Title, Caption, Description, Keywords, Artist,
     *    Author, DateTimeOriginal, CreateDate, GPSPosition
     * 2. OCR text (requires Tesseract installation)
     * 3. AI-generated description (requires configured llmCall)
     * @override
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
    /**
     * Gets an AI-generated description of the image using the provided LLM callback.
     *
     * @param {Object} params - Parameters for LLM description generation
     * @param {string} params.localPath - Path to the image file
     * @param {string} params.fileExtension - File extension for MIME type determination
     * @param {LlmCall} params.llmCall - Callback function for LLM processing
     * @returns {Promise<string | null>} Generated description or null if:
     *   - LLM callback is not provided
     *   - Image processing fails
     *   - LLM call fails
     *
     * @private
     */
    private _getLlmDescription;
}

/**
 * Converter class for Jupyter Notebook (.ipynb) files to markdown format.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const ipynbConverter = new IpynbConverter();
 * let result = await ipynbConverter.convert('notebook.ipynb', {
 *   fileExtension: '.ipynb'
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert('notebook.ipynb');
 * ```
 */
declare class IpynbConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts a Jupyter Notebook file to markdown format.
     *
     * @param {string} localPath - The local file system path to the .ipynb file
     * @param {ConversionOptions} options - Conversion options including file extension
     * @returns {Promise<DocumentConverterResult>} A promise that resolves to the conversion result
     * @throws {Error} If the file cannot be read or parsed
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
    /**
     * Internal method to convert parsed notebook content to markdown format.
     * Processes both markdown and code cells, including their outputs.
     *
     * @param {JupyterNotebook} notebookContent - Parsed Jupyter notebook content
     * @returns {DocumentConverterResult} Converted document with title and markdown content
     * @throws {Error} If conversion process fails
     * @private
     */
    private _convert;
}

/**
 * Converts PDF files to Markdown format.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const pdfConverter = new PdfConverter();
 * let result = await pdfConverter.convert('document.pdf', {
 *   fileExtension: '.pdf'
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert('document.pdf');
 * ```
 */
declare class PdfConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts a PDF file to Markdown format.
     * Uses pdf-parse to Extract text from PDF file.
     *
     * @param {string} localPath - Path to the local PDF file
     * @param {ConversionOptions} options - Conversion options
     * @returns {Promise<DocumentConverterResult>} A promise that resolves to the conversion result
     * @throws {Error} If the file cannot be read or parsed
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
}

/**
 * ZipConverter handles the conversion of ZIP archives to Markdown format.
 * It extracts the archive contents and processes each file using appropriate parent converters.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const zipConverter = new ZipConverter();
 * let result = await zipConverter.convert("archive.zip", {
 *   parentConverters: [new PdfConverter(), new DocxConverter(), new HtmlConverter()],
 *   fileExtension: ".zip"
 * })
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert("archive.zip");
 * ```
 */
declare class ZipConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts a ZIP archive to Markdown by extracting and processing its contents.
     * Creates a temporary directory for extraction, processes each file with available converters,
     * and cleans up afterward.
     *
     * @param {string} localPath - The local file path to the ZIP archive
     * @param {ConversionOptions} options - Conversion options including:
     *   - fileExtension: The file extension (must be .zip)
     *   - parentConverters: Array of available document converters for processing extracted files
     * @returns {Promise<DocumentConverterResult>} Object containing:
     *   - Markdown content with results from all processed files
     *   - Error message if processing fails or no converters are available
     *
     * @throws Will return an error result if:
     *   - The file is not a ZIP archive
     *   - No parent converters are available
     *   - Archive extraction fails
     *   - File processing fails
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
    /**
     * Processes a directory of files within a ZIP archive.
     * Converts each file using available parent converters.
     *
     * @param {string} extractionDir - The directory path to process
     * @param {DocumentConverter[]} parentConverters - Conversion options
     * @param {string} [parentDirName] - The name of the parent directory (if present)
     *
     * @returns {Promise<string>} The processed directory contents
     *
     * @private
     */
    private processDirectory;
}

/**
 * Converts Outlook MSG files (.msg) to markdown format.
 * Extracts email metadata (sender, receiver, subject) and content including attachments.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const outlookConverter = new OutlookMsgConverter();
 * let result = await outlookConverter.convert('outlook.msg', {
 *   fileExtension: '.msg'
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown();
 * let result = await converter.convert('outlook.msg');
 * ```
 */
declare class OutlookMsgConverter extends DocumentConverter {
    constructor(priority?: number);
    /**
     * Converts an Outlook MSG file to markdown format.
     * The resulting markdown includes email metadata, body content, and attachment information.
     *
     * @param {string} localPath - Path to the .msg file
     * @param {ConversionOptions} options - Conversion options including file extension
     * @returns {Promise<DocumentConverterResult>} Object containing email subject as title and formatted markdown as textContent
     * @throws {Error} If the file cannot be read or parsed
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
}

/**
 * Converts documents using Azure Document Intelligence API.
 * Supports various document formats including PDF, Office documents, and images.
 *
 * @extends DocumentConverter
 *
 * @example
 * ```typescript
 * const docIntelConverter = new DocumentIntelligenceConverter({
 *   endpoint: "https://your-endpoint.cognitiveservices.azure.com/"
 * })
 * let result = await converter.convert("document.pdf", {
 *   fileExtension: ".pdf"
 * });
 *
 * // Using Markitdown
 * const converter = new Markitdown({
 *   docintelEndpoint: "https://your-endpoint.cognitiveservices.azure.com/"
 * });
 * let result = await converter.convert("document.pdf");
 * ```
 */
declare class DocumentIntelligenceConverter extends DocumentConverter {
    /** Azure Document Intelligence client instance */
    docIntelClient: DocumentIntelligenceClient;
    /**
     * Creates a new DocumentIntelligenceConverter instance.
     * @param {Object} config - Configuration options
     * @param {string} config.endpoint - Azure Document Intelligence API endpoint
     * @param {string} [config.apiVersion='2024-07-31-preview'] - API version to use
     * @throws {Error} If authentication with Azure fails
     */
    constructor({ endpoint, apiVersion, priority, }: {
        endpoint: string;
        apiVersion?: string;
        priority?: number;
    });
    /**
     * Converts a document to markdown format using Azure Document Intelligence.
     *
     * @param {string} localPath - Path to the local file
     * @param {ConversionOptions} options - Conversion options
     * @returns {Promise<DocumentConverterResult>} Conversion result or null if file type not supported
     *
     * @remarks
     * Supported file extensions:
     * - Documents: .pdf, .docx, .xlsx, .pptx, .html
     * - Images: .jpeg, .jpg, .png, .bmp, .tiff, .heif
     *
     * Note: Some analysis features (formulas, ocrHighResolution, styleFont) are not
     * available for Office file types (.xlsx, .pptx, .html, .docx)
     *
     * @throws {Error} If the Azure API request fails
     */
    convert(localPath: string, options: ConversionOptions): Promise<DocumentConverterResult>;
}

interface TurndownOptions extends TurndownService.Options {
    headingStyle?: "atx" | "setext";
    hr?: string;
    bulletListMarker?: "*" | "-" | "+";
    codeBlockStyle?: "fenced" | "indented";
    emDelimiter?: "_" | "*";
    keepInlineImages?: string[];
}
/**
 * Custom Markdown converter with customized rules.
 *
 * @example
 * ```typescript
 * const converter = new CustomMarkdownConverter({
 *   headingStyle: "atx",
 *   hr: "---",
 *   bulletListMarker: "*",
 *   codeBlockStyle: "fenced",
 *   emDelimiter: "_",
 *   keepInlineImages: [],
 * }); // Custom Turndown options
 *
 * const result = await converter.convert('<h1>Hello World</h1>'); // Output: # Hello World
 *
 * converter.addRule("customRule", {
 *   filter: "tag-name",
 *   replacement: (content: string, node: Node): string => {
 *     // Custom rule logic
 *     return content;
 *   },
 * });
 * ```
 */
declare class CustomMarkdownConverter {
    private turndownService;
    /**
     * Initializes the Markdown converter with customized rules.
     * @param {TurndownOptions} [options={}] - Optional configuration settings for Turndown.
     */
    constructor(options?: TurndownOptions);
    /**
     * Converts an HTML string into Markdown.
     * @param {string} html - The HTML content to convert.
     * @returns {string} The converted Markdown string.
     */
    convert(html: string): string;
    /**
     * Adds a custom Turndown rule.
     * @param {string} rule - The name of the custom rule.
     * @param {TurndownService.Rule} rules - The rule definition to be added.
     */
    addRule(rule: string, rules: TurndownService.Rule): void;
}

declare global {
    var IS_FFMPEG_CAPABLE: boolean;
}
/**
 * MarkItDown is a document conversion utility that supports multiple file formats
 * and provides conversion to markdown format.
 *
 * @class
 *
 * @example
 * ```typescript
 * const markitdown = new MarkItDown({
 *   llmCall: async (params) => {
 *     const openai = new OpenAI();
 *     if(params.file) {
 *       const completion = await openai.audio.transcriptions.create({
 *         model: "whisper-1",
 *         file: params.file
 *       });
 *       return completion.text;
 *     } else if(params.messages) {
 *       const completion = await openai.chat.completions.create({
 *         model: "gpt-4o",
 *         messages: params.messages
 *       });
 *       return completion.text;
 *     } else {
 *       return null;
 *     }
 *   },
 *   styleMap: [
 *     "p[style-name='Section Title'] => h1:fresh",
 *     "p[style-name='Subsection Title'] => h2:fresh"
 *   ],
 *   docintelEndpoint: 'https://your-endpoint.cognitiveservices.azure.com/'
 * });
 * let docxResult = await markitdown.convert('document.docx');
 * let pdfResult = await markitdown.convert('invoice.pdf');
 * let pptxResult = await markitdown.convert('presentation.pptx');
 * let imageOcrResult = await markitdown.convert('image.png');
 * ```
 */
declare class MarkItDown {
    private _requestsSession;
    private _llmCall;
    private _styleMap;
    private _pageConverters;
    /**
     * Creates a new instance of MarkItDown.
     * @param {Object} options - Configuration options for the converter
     * @param {AxiosInstance} [options.requestsSession=axios.create()] - Custom axios instance for HTTP requests
     * @param {LlmCall} [options.llmCall=null] - Language model callback function
     * @param {Object} [options.styleMap=null] - Custom style mapping for docx conversions
     * @param {string} [options.docintelEndpoint=null] - Document intelligence API endpoint
     */
    constructor({ requestsSession, llmCall, styleMap, docintelEndpoint, }?: MarkItDownOptions);
    /**
     * Checks if FFmpeg is available in the system.
     * @private
     */
    private _checkFfmpeg;
    /**
     * Registers all default document converters.
     * @private
     */
    private _registerDefaultConverters;
    /**
     * Converts a source to markdown format.
     * @param {string | fs.ReadStream} source - The source to convert (URL, file path, or ReadStream)
     * @param {Object} [options={}] - Conversion options
     * @returns {Promise<DocumentConverterResult>} The conversion result
     * @throws {Error} When the source type is unsupported
     */
    convert(source: string | fs.ReadStream, options?: Record<string, any>): Promise<DocumentConverterResult>;
    /**
     * Converts a File ReadStream to markdown.
     * @param {fs.ReadStream} stream - The input stream to convert
     * @param {Object} [options={}] - Conversion options
     * @param {string} [options.fileExtension] - Optional file extension to help determine the converter
     * @returns {Promise<DocumentConverterResult>} The conversion result
     */
    convertStream(stream: fs.ReadStream, options?: {
        fileExtension?: string;
    }): Promise<DocumentConverterResult>;
    /**
     * Converts a local file to markdown.
     * @param {string} filePath - Path to the local file
     * @param {Object} [options={}] - Conversion options
     * @returns {Promise<DocumentConverterResult>} The conversion result
     */
    convertLocal(filePath: string, options?: Record<string, any>): Promise<DocumentConverterResult>;
    /**
     * Fetches a URL as a stream and converts it into markdown using convertResponse.
     * @param {string} url - The URL to convert
     * @param {Object} [options={}] - Conversion options
     * @returns {Promise<DocumentConverterResult>} The conversion result
     */
    convertUrl(url: string, options?: Record<string, any>): Promise<DocumentConverterResult>;
    /**
     * Converts an Axios response to markdown.
     * @param {AxiosResponse} response - The Axios response to convert
     * @param {Object} [options={}] - Conversion options
     * @returns {Promise<DocumentConverterResult>} The conversion result
     */
    convertResponse(response: AxiosResponse, options?: Record<string, any>): Promise<DocumentConverterResult>;
    /**
     * Internal method to convert a file using the appropriate converter.
     * @private
     * @param {string} filePath - Path to the file to convert
     * @param {string[]} extensions - Array of possible file extensions
     * @param {Object} options - Conversion options
     * @returns {Promise<DocumentConverterResult>} The conversion result
     * @throws {Error} When no suitable converter is found
     */
    private _convert;
    /**
     * Determines the file extensions to try for conversion.
     * @private
     * @param {string} filePath - Path to the file
     * @param {Object} options - Options containing potential file extension
     * @returns {string[]} Array of possible file extensions
     */
    private _determineExtensions;
    /**
     * Registers a new document converter.
     * @param {DocumentConverter} converter - The converter to register
     */
    registerConverter(converter: DocumentConverter): void;
}

export { AudioConverter, BingSerpConverter, CustomMarkdownConverter, DocumentConverter, DocumentIntelligenceConverter, DocxConverter, HtmlConverter, ImageConverter, IpynbConverter, MarkItDown, MediaConverter, OutlookMsgConverter, PdfConverter, PlainTextConverter, PptxConverter, RSSConverter, VideoConverter, WikipediaConverter, XlsxConverter, YouTubeConverter, ZipConverter, MarkItDown as default };
