import JSZip from 'jszip';
import { countWords } from '../utils.js';
import { asOptionalString, formatDateLike } from '../inspect/shared.js';
function parseXmlText(xml, tag) {
    const regex = new RegExp(`<${tag}[^>]*>([^<]*)</${tag}>`, 'i');
    const match = xml.match(regex);
    return match?.[1]?.trim() || undefined;
}
function extractTextFromElement(xml) {
    const matches = xml.match(/<text:(?:p|span)[^>]*>([^<]*)<\/text:(?:p|span)>/g) || [];
    const texts = [];
    for (const m of matches) {
        const text = m.replace(/<[^>]+>/g, '').trim();
        if (text)
            texts.push(text);
    }
    return texts.join(' ');
}
export async function inspectOdp(buffer) {
    const zip = await JSZip.loadAsync(buffer);
    // Parse metadata
    const properties = {};
    const metaXml = await zip.file('meta.xml')?.async('text');
    if (metaXml) {
        properties.title = asOptionalString(parseXmlText(metaXml, 'dc:title'));
        properties.subject = asOptionalString(parseXmlText(metaXml, 'dc:subject'));
        properties.author = asOptionalString(parseXmlText(metaXml, 'dc:creator') ?? parseXmlText(metaXml, 'meta:initial-creator'));
        properties.keywords = asOptionalString(parseXmlText(metaXml, 'meta:keyword'));
        properties.createdDate = formatDateLike(parseXmlText(metaXml, 'meta:creation-date'));
        properties.modifiedDate = formatDateLike(parseXmlText(metaXml, 'dc:date'));
    }
    // Parse content.xml for slides
    const contentXml = await zip.file('content.xml')?.async('text');
    const slideProfiles = [];
    const riskFlags = {
        comments: false,
        speakerNotes: false,
        hyperlinks: false,
        embeddedMedia: false,
        animations: false,
        macros: false,
        charts: false,
        tables: false,
    };
    if (contentXml) {
        // Split by draw:page elements
        const slideMatches = contentXml.match(/<draw:page\b[^>]*>[\s\S]*?<\/draw:page>/g) || [];
        for (let i = 0; i < slideMatches.length; i++) {
            const slideXml = slideMatches[i];
            // Get title from draw:name attribute or first text frame
            let title = null;
            const nameMatch = slideXml.match(/draw:name="([^"]*)"/);
            if (nameMatch && nameMatch[1]) {
                title = nameMatch[1];
            }
            // Extract text
            const text = extractTextFromElement(slideXml);
            const words = countWords(text);
            // Count tables and images — only the table container; the \b boundary
            // would also match <table:table-row>/<table:table-cell>/<table:table-column>.
            const tables = (slideXml.match(/<table:table(?=[\s/>])/g) || []).length;
            const images = (slideXml.match(/<draw:image\b/g) || []).length;
            // Check for notes
            let hasNotes = false;
            let notePreview = null;
            const notesMatch = slideXml.match(/<presentation:notes\b[^>]*>([\s\S]*?)<\/presentation:notes>/);
            if (notesMatch) {
                const notesText = extractTextFromElement(notesMatch[1]);
                if (notesText.trim()) {
                    hasNotes = true;
                    notePreview = notesText.length > 200 ? notesText.slice(0, 200) + '...' : notesText;
                }
            }
            slideProfiles.push({
                index: i + 1,
                title,
                words,
                hasNotes,
                notePreview,
                images,
                tables,
                charts: 0,
            });
        }
        // Risk flags
        if (/<office:annotation\b/.test(contentXml))
            riskFlags.comments = true;
        if (slideProfiles.some(p => p.hasNotes))
            riskFlags.speakerNotes = true;
        if (/<text:a\b[^>]*xlink:href=/.test(contentXml))
            riskFlags.hyperlinks = true;
        if (/<draw:image\b/.test(contentXml))
            riskFlags.embeddedMedia = true;
        if (/<presentation:transition\b/.test(contentXml) || /<anim:/.test(contentXml))
            riskFlags.animations = true;
        if (/<table:table\b/.test(contentXml))
            riskFlags.tables = true;
        if (/<draw:object\b/.test(contentXml))
            riskFlags.charts = true;
    }
    // Check for macros
    if (zip.file('Basic/') || zip.file('Scripts/'))
        riskFlags.macros = true;
    return { properties, riskFlags, slideProfiles };
}
//# sourceMappingURL=inspect-odp.js.map