import { chunkMarkdownIR, markdownToIR, } from "../markdown/ir.js";
/**
 * Convert MarkdownIR to Feishu Post format
 */
function renderFeishuPost(ir) {
    const lines = [];
    const text = ir.text;
    if (!text) {
        return { zh_cn: { content: [[{ tag: "text", text: "" }]] } };
    }
    // Build a map of style ranges for quick lookup
    const styleRanges = buildStyleRanges(ir.styles, text.length);
    const linkMap = buildLinkMap(ir.links);
    // Split text into lines
    const textLines = text.split("\n");
    let charIndex = 0;
    for (const line of textLines) {
        const lineElements = [];
        if (line.length === 0) {
            // Empty line - add empty text element
            lineElements.push({ tag: "text", text: "" });
        }
        else {
            // Process each character segment with consistent styling
            let segmentStart = charIndex;
            let currentStyles = getStylesAt(styleRanges, segmentStart);
            let currentLink = getLinkAt(linkMap, segmentStart);
            for (let i = 0; i < line.length; i++) {
                const pos = charIndex + i;
                const newStyles = getStylesAt(styleRanges, pos);
                const newLink = getLinkAt(linkMap, pos);
                // Check if style or link changed
                const stylesChanged = !stylesEqual(currentStyles, newStyles);
                const linkChanged = currentLink !== newLink;
                if (stylesChanged || linkChanged) {
                    // Emit previous segment
                    const segmentText = text.slice(segmentStart, pos);
                    if (segmentText) {
                        lineElements.push(createPostElement(segmentText, currentStyles, currentLink));
                    }
                    segmentStart = pos;
                    currentStyles = newStyles;
                    currentLink = newLink;
                }
            }
            // Emit final segment of the line
            const finalText = text.slice(segmentStart, charIndex + line.length);
            if (finalText) {
                lineElements.push(createPostElement(finalText, currentStyles, currentLink));
            }
        }
        lines.push(lineElements.length > 0 ? lineElements : [{ tag: "text", text: "" }]);
        charIndex += line.length + 1; // +1 for newline
    }
    return {
        zh_cn: {
            content: lines,
        },
    };
}
function buildStyleRanges(styles, textLength) {
    const ranges = Array(textLength)
        .fill(null)
        .map(() => ({
        bold: false,
        italic: false,
        strikethrough: false,
        code: false,
    }));
    for (const span of styles) {
        for (let i = span.start; i < span.end && i < textLength; i++) {
            switch (span.style) {
                case "bold":
                    ranges[i].bold = true;
                    break;
                case "italic":
                    ranges[i].italic = true;
                    break;
                case "strikethrough":
                    ranges[i].strikethrough = true;
                    break;
                case "code":
                case "code_block":
                    ranges[i].code = true;
                    break;
            }
        }
    }
    return ranges;
}
function buildLinkMap(links) {
    const map = new Map();
    for (const link of links) {
        for (let i = link.start; i < link.end; i++) {
            map.set(i, link.href);
        }
    }
    return map;
}
function getStylesAt(ranges, pos) {
    return ranges[pos] ?? { bold: false, italic: false, strikethrough: false, code: false };
}
function getLinkAt(linkMap, pos) {
    return linkMap.get(pos);
}
function stylesEqual(a, b) {
    return (a.bold === b.bold &&
        a.italic === b.italic &&
        a.strikethrough === b.strikethrough &&
        a.code === b.code);
}
function createPostElement(text, styles, link) {
    const styleArray = [];
    if (styles.bold)
        styleArray.push("bold");
    if (styles.italic)
        styleArray.push("italic");
    if (styles.strikethrough)
        styleArray.push("lineThrough");
    if (styles.code)
        styleArray.push("code");
    if (link) {
        return {
            tag: "a",
            text,
            href: link,
            ...(styleArray.length > 0 ? { style: styleArray } : {}),
        };
    }
    return {
        tag: "text",
        text,
        ...(styleArray.length > 0 ? { style: styleArray } : {}),
    };
}
/**
 * Convert Markdown to Feishu Post format
 */
export function markdownToFeishuPost(markdown, options = {}) {
    const ir = markdownToIR(markdown ?? "", {
        linkify: true,
        headingStyle: "bold",
        blockquotePrefix: "｜ ",
        tableMode: options.tableMode,
    });
    return renderFeishuPost(ir);
}
/**
 * Convert Markdown to Feishu Post chunks (for long messages)
 */
export function markdownToFeishuChunks(markdown, limit, options = {}) {
    const ir = markdownToIR(markdown ?? "", {
        linkify: true,
        headingStyle: "bold",
        blockquotePrefix: "｜ ",
        tableMode: options.tableMode,
    });
    const chunks = chunkMarkdownIR(ir, limit);
    return chunks.map((chunk) => ({
        post: renderFeishuPost(chunk),
        text: chunk.text,
    }));
}
/**
 * Check if text contains Markdown formatting
 */
export function containsMarkdown(text) {
    if (!text)
        return false;
    // Check for common Markdown patterns
    const markdownPatterns = [
        /\*\*[^*]+\*\*/, // bold
        /\*[^*]+\*/, // italic
        /~~[^~]+~~/, // strikethrough
        /`[^`]+`/, // inline code
        /```[\s\S]*```/, // code block
        /\[.+\]\(.+\)/, // links
        /^#{1,6}\s/m, // headings
        /^[-*]\s/m, // unordered list
        /^\d+\.\s/m, // ordered list
    ];
    return markdownPatterns.some((pattern) => pattern.test(text));
}
