import path from 'node:path';
import { z } from 'zod';
import { METRIC_FIELDS, compareCodeUnits, hasKey } from './utils.js';
export const AggregateOptionsSchema = z.object({
    byFile: z.boolean().optional(),
    sort: z.string().optional(),
    showConfidence: z.boolean().optional(),
});
const SUM_FIELDS = ['files', ...METRIC_FIELDS, 'size'];
export function aggregate(results, options = {}) {
    const { byFile = false, sort = 'files' } = options;
    if (byFile) {
        return aggregateByFile(results, sort, options);
    }
    return aggregateByType(results, sort, options);
}
function aggregateByType(results, sort, options) {
    const groups = {};
    for (const r of results) {
        const key = r.success ? r.fileType : 'Unreadable';
        if (!groups[key]) {
            const g = {
                fileType: key,
                files: 0,
                size: 0,
                words: 0,
                pages: 0,
                paragraphs: 0,
                sheets: 0,
                rows: 0,
                cells: 0,
                slides: 0,
            };
            for (const f of METRIC_FIELDS) {
                g[hasKey(f)] = false;
            }
            groups[key] = g;
        }
        const g = groups[key];
        g.files++;
        g.size += r.size || 0;
        if (r.success && r.metrics) {
            const m = r.metrics;
            for (const f of METRIC_FIELDS) {
                if (m[f] != null) {
                    g[f] += m[f];
                    g[hasKey(f)] = true;
                    if (r.confidence?.[f]) {
                        if (!g.confidence)
                            g.confidence = {};
                        if (r.confidence[f] === 'estimated' || !g.confidence[f]) {
                            g.confidence[f] = r.confidence[f];
                        }
                    }
                }
            }
        }
    }
    return finalize(Object.values(groups), sort, 'grouped', options);
}
function aggregateByFile(results, sort, options) {
    const rows = results.map(r => {
        const row = {
            fileType: r.success ? r.fileType : 'Unreadable',
            fileName: path.basename(r.filePath),
            filePath: r.filePath,
            files: 1,
            size: r.size || 0,
            words: 0,
            pages: 0,
            paragraphs: 0,
            sheets: 0,
            rows: 0,
            cells: 0,
            slides: 0,
        };
        for (const f of METRIC_FIELDS) {
            row[f] = r.metrics?.[f] || 0;
            row[hasKey(f)] = r.metrics?.[f] != null;
        }
        if (r.confidence)
            row.confidence = r.confidence;
        return row;
    });
    return finalize(rows, sort, 'by-file', options);
}
function finalize(rows, sort, mode, options = {}) {
    sortRows(rows, sort);
    const totals = computeTotals(rows);
    const columns = detectColumns(rows);
    return { rows, totals, columns, mode, showConfidence: !!options.showConfidence };
}
function sortRows(rows, sort) {
    const sortFns = {
        files: (a, b) => b.files - a.files,
        // Per-file rows carry a fileName and sort by it; grouped rows have no
        // fileName and fall back to sorting by fileType.
        name: (a, b) => compareCodeUnits(a.fileName || a.fileType || '', b.fileName || b.fileType || ''),
        words: (a, b) => b.words - a.words,
        size: (a, b) => b.size - a.size,
    };
    const fn = sortFns[sort] || sortFns.files;
    rows.sort(fn);
}
function computeTotals(rows) {
    const totals = {
        fileType: 'Total',
        files: 0,
        size: 0,
        words: 0,
        pages: 0,
        paragraphs: 0,
        sheets: 0,
        rows: 0,
        cells: 0,
        slides: 0,
    };
    for (const f of SUM_FIELDS)
        totals[f] = 0;
    for (const r of rows) {
        for (const f of SUM_FIELDS)
            totals[f] += r[f];
    }
    return totals;
}
function detectColumns(rows) {
    const columns = {};
    for (const f of METRIC_FIELDS) {
        columns[hasKey(f)] = rows.some(r => !!r[hasKey(f)]);
    }
    return columns;
}
//# sourceMappingURL=stats.js.map