/* eslint-disable no-continue */
const handleDelimitedMarkdown = (text, startIndex, openingDelimiter) => {
    const delimiterLength = openingDelimiter.length;
    // Check if there's content immediately after opening delimiter (no space)
    if (startIndex + delimiterLength >= text.length || text[startIndex + delimiterLength] === ' ') {
        return { isValidMarkdown: false, endIndex: startIndex + 1, token: '' };
    }
    let currentIndex = startIndex + delimiterLength; // Skip past the opening delimiter
    // Find the closing delimiter
    while (currentIndex <= text.length - openingDelimiter.length) {
        if (text.slice(currentIndex, currentIndex + openingDelimiter.length) === openingDelimiter) {
            // Check that there's no space before the closing delimiter
            if (text[currentIndex - 1] !== ' ') {
                currentIndex += openingDelimiter.length; // Include the closing delimiter
                return {
                    isValidMarkdown: true,
                    endIndex: currentIndex,
                    token: text.slice(startIndex, currentIndex)
                };
            }
            break;
        }
        currentIndex += 1;
    }
    return { isValidMarkdown: false, endIndex: startIndex + 1, token: '' };
};
const handleLineBasedMarkdown = (text, startIndex, openingChar, maxCount = 1) => {
    // Check if this character is at the beginning of a line
    const isAtLineStart = startIndex === 0 || text[startIndex - 1] === '\n';
    if (!isAtLineStart) {
        return { isValidMarkdown: false, endIndex: startIndex + 1, token: '' };
    }
    let currentIndex = startIndex;
    let charCount = 0;
    // Count consecutive opening characters
    while (currentIndex < text.length && text[currentIndex] === openingChar && charCount < maxCount) {
        charCount += 1;
        currentIndex += 1;
    }
    // Check if there's a space after the opening characters
    if (currentIndex < text.length && text[currentIndex] === ' ') {
        // Find the end of the line (or end of text)
        while (currentIndex < text.length && text[currentIndex] !== '\n') {
            currentIndex += 1;
        }
        // Include the newline character if present
        if (currentIndex < text.length && text[currentIndex] === '\n') {
            currentIndex += 1;
        }
        return {
            isValidMarkdown: true,
            endIndex: currentIndex,
            token: text.slice(startIndex, currentIndex)
        };
    }
    return { isValidMarkdown: false, endIndex: startIndex + 1, token: '' };
};
const markdownTokenizer = (text) => {
    if (!text)
        return [];
    const tokens = [];
    let currentTokenIndex = 0;
    while (currentTokenIndex < text.length) {
        const char = text[currentTokenIndex];
        // Handle code blocks (```text```)
        if (char === '`' &&
            text[currentTokenIndex + 1] === '`' &&
            text[currentTokenIndex + 2] === '`') {
            // Add the opening ``` as one token
            tokens.push('```');
            currentTokenIndex += 3; // Skip past the opening ```
            // Check if there's a language identifier on the same line
            let languageEndIndex = currentTokenIndex;
            while (languageEndIndex < text.length && text[languageEndIndex] !== '\n') {
                languageEndIndex += 1;
            }
            // If there's a language identifier, add it as one token including the newline
            if (languageEndIndex > currentTokenIndex) {
                const languageLine = text.slice(currentTokenIndex, languageEndIndex + (text[languageEndIndex] === '\n' ? 1 : 0));
                tokens.push(languageLine);
                currentTokenIndex = languageEndIndex + (text[languageEndIndex] === '\n' ? 1 : 0);
            }
            // Now stream the content character by character until we find closing ```
            while (currentTokenIndex < text.length - 2) {
                if (text[currentTokenIndex] === '`' &&
                    text[currentTokenIndex + 1] === '`' &&
                    text[currentTokenIndex + 2] === '`') {
                    // Add the closing ``` as one token
                    tokens.push('```');
                    currentTokenIndex += 3; // Include the closing ```
                    break;
                }
                // Add individual characters
                tokens.push(text[currentTokenIndex]);
                currentTokenIndex += 1;
            }
            continue;
        }
        // Markdown characters that surround the text
        if (['*', '`', '~'].includes(char)) {
            let openingDelimiter = char;
            // Bold case
            if (text[currentTokenIndex + 1] === char) {
                openingDelimiter = `${char}${char}`;
            }
            const result = handleDelimitedMarkdown(text, currentTokenIndex, openingDelimiter);
            if (result.isValidMarkdown) {
                tokens.push(result.token);
                currentTokenIndex = result.endIndex;
                continue;
            }
            // Not valid markdown, treat as regular characters
            tokens.push(char);
            currentTokenIndex += 1;
            continue;
        }
        // Markdown characters that start on a new line and add a space between actual text and the markdown character
        if (['#', '>'].includes(char)) {
            const result = handleLineBasedMarkdown(text, currentTokenIndex, char, char === '#' ? 6 : 1);
            if (result.isValidMarkdown) {
                tokens.push(result.token);
                currentTokenIndex = result.endIndex;
                continue;
            }
            // Not valid heading markdown, treat as regular character
            tokens.push(char);
            currentTokenIndex += 1;
            continue;
        }
        // Image and link markdown elements
        if (char === '[' || (char === '!' && text[currentTokenIndex + 1] === '[')) {
            const startIndex = currentTokenIndex;
            currentTokenIndex += char === '[' ? 1 : 2; // Skip past the opening
            // Find the closing ] and then check for (
            while (currentTokenIndex < text.length) {
                if (text[currentTokenIndex] === ']' && text[currentTokenIndex + 1] === '(') {
                    currentTokenIndex += 2; // Skip past ](
                    // Find the closing )
                    while (currentTokenIndex < text.length) {
                        if (text[currentTokenIndex] === ')') {
                            currentTokenIndex += 1; // Include the closing )
                            break;
                        }
                        currentTokenIndex += 1;
                    }
                    break;
                }
                currentTokenIndex += 1;
            }
            tokens.push(text.slice(startIndex, currentTokenIndex));
            continue;
        }
        tokens.push(char);
        currentTokenIndex += 1;
    }
    return tokens;
};
export default markdownTokenizer;
//# sourceMappingURL=markdownTokenizer.js.map