import { BULLET_PREFIX, NUMBERED_PREFIX, NUMBERED_PREFIX_FULL } from "./listFormatting.js";
function toggleInlineWrap(input, marker) {
    const { value, selectionStart, selectionEnd } = input;
    const markerLen = marker.length;
    const selectedText = value.slice(selectionStart, selectionEnd);
    const hasSelection = selectionStart !== selectionEnd;
    if (!hasSelection) {
        const textBefore = value.slice(0, selectionStart);
        const textAfter = value.slice(selectionStart);
        const markerChar = marker[0];
        const esc = (s)=>s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        const me = esc(marker);
        const ce = esc(markerChar);
        const beforeRe = 1 === markerLen ? new RegExp(`(?<!${ce})${me}(?!${ce})([^${ce}]*)$`) : new RegExp(`${me}([^${ce}]*)$`);
        const afterRe = 1 === markerLen ? new RegExp(`^([^${ce}]*)(?<!${ce})${me}(?!${ce})`) : new RegExp(`^([^${ce}]*)${me}`);
        const bm = beforeRe.exec(textBefore);
        const am = afterRe.exec(textAfter);
        if (bm && am) {
            const openStart = selectionStart - bm[0].length;
            const closeEnd = selectionStart + am[0].length;
            const boundaryClean = 1 === markerLen || value[openStart - 1] !== markerChar && value[closeEnd] !== markerChar;
            if (boundaryClean) {
                const newValue = value.slice(0, openStart) + bm[1] + am[1] + value.slice(closeEnd);
                const newCursor = selectionStart - markerLen;
                return {
                    value: newValue,
                    selectionStart: newCursor,
                    selectionEnd: newCursor
                };
            }
        }
        const lineStart = value.lastIndexOf('\n', selectionStart - 1) + 1;
        let lineEnd = value.indexOf('\n', selectionStart);
        if (-1 === lineEnd) lineEnd = value.length;
        const currentLine = value.slice(lineStart, lineEnd);
        const bulletMatch = BULLET_PREFIX.exec(currentLine);
        const numberedMatch = NUMBERED_PREFIX_FULL.exec(currentLine);
        const prefixLen = bulletMatch?.[0].length ?? numberedMatch?.[0].length ?? 0;
        if (prefixLen > 0) {
            const content = currentLine.slice(prefixLen);
            if (content.length > 0) {
                const prefix = currentLine.slice(0, prefixLen);
                const newLine = `${prefix}${marker}${content}${marker}`;
                const newValue = value.slice(0, lineStart) + newLine + value.slice(lineEnd);
                const newCursor = selectionStart + markerLen;
                return {
                    value: newValue,
                    selectionStart: newCursor,
                    selectionEnd: newCursor
                };
            }
        }
        const newValue = value.slice(0, selectionStart) + marker + marker + value.slice(selectionEnd);
        const cursorPos = selectionStart + markerLen;
        return {
            value: newValue,
            selectionStart: cursorPos,
            selectionEnd: cursorPos
        };
    }
    {
        const lineStart = value.lastIndexOf('\n', selectionStart - 1) + 1;
        let lineEnd = value.indexOf('\n', selectionEnd);
        if (-1 === lineEnd) lineEnd = value.length;
        if (selectionEnd > lineStart && '\n' === value[selectionEnd - 1]) lineEnd = selectionEnd - 1;
        const lines = value.slice(lineStart, lineEnd).split('\n');
        if (lines.length >= 2 && lines.some((line)=>BULLET_PREFIX.test(line) || NUMBERED_PREFIX.test(line))) {
            const parsed = lines.map((line)=>{
                const bulletMatch = BULLET_PREFIX.exec(line);
                const numberedMatch = NUMBERED_PREFIX.exec(line);
                const prefix = bulletMatch?.[0] ?? numberedMatch?.[0] ?? '';
                const content = line.slice(prefix.length);
                return {
                    prefix,
                    content
                };
            });
            const isWrapped = (content)=>{
                if (content.length < 2 * markerLen) return false;
                if (!content.startsWith(marker) || !content.endsWith(marker)) return false;
                const mc = marker[0];
                if (1 === markerLen) {
                    let leadingStars = 0;
                    while(content[leadingStars] === mc)leadingStars++;
                    let trailingStars = 0;
                    while(content[content.length - 1 - trailingStars] === mc)trailingStars++;
                    return leadingStars % 2 === 1 && trailingStars % 2 === 1;
                }
                return content[markerLen] !== mc && content[content.length - markerLen - 1] !== mc;
            };
            const allWrapped = parsed.every(({ content })=>isWrapped(content));
            const newLines = allWrapped ? parsed.map(({ prefix, content })=>`${prefix}${content.slice(markerLen, content.length - markerLen)}`) : parsed.map(({ prefix, content })=>content.length > 0 ? `${prefix}${marker}${content}${marker}` : `${prefix}${content}`);
            const newLinesText = newLines.join('\n');
            const newValue = value.slice(0, lineStart) + newLinesText + value.slice(lineEnd);
            const newSelectionEnd = lineStart + newLinesText.length;
            return {
                value: newValue,
                selectionStart: lineStart,
                selectionEnd: newSelectionEnd
            };
        }
    }
    const before = value.slice(selectionStart - markerLen, selectionStart);
    const after = value.slice(selectionEnd, selectionEnd + markerLen);
    const markerChar = marker[0];
    const outerBefore = value[selectionStart - markerLen - 1];
    const outerAfter = value[selectionEnd + markerLen];
    const isBoundaryClean = outerBefore !== markerChar && outerAfter !== markerChar;
    if (before === marker && after === marker && isBoundaryClean) {
        const newValue = value.slice(0, selectionStart - markerLen) + selectedText + value.slice(selectionEnd + markerLen);
        return {
            value: newValue,
            selectionStart: selectionStart - markerLen,
            selectionEnd: selectionEnd - markerLen
        };
    }
    const newValue = value.slice(0, selectionStart) + marker + selectedText + marker + value.slice(selectionEnd);
    return {
        value: newValue,
        selectionStart: selectionStart + markerLen,
        selectionEnd: selectionEnd + markerLen
    };
}
function toggleBold(input) {
    return toggleInlineWrap(input, '**');
}
function toggleItalic(input) {
    return toggleInlineWrap(input, '*');
}
function toggleStrikethrough(input) {
    return toggleInlineWrap(input, '~~');
}
export { toggleBold, toggleItalic, toggleStrikethrough };
