/** Append current field token to fields array and reset token */
function flushField(fields, current) {
    fields.push(current);
    return '';
}
/** Parse a single CSV line respecting quoted fields */
function parseCsvLine(line) {
    const fields = [];
    let current = '';
    let inQuotes = false;
    for (let i = 0; i < line.length; i++) {
        const ch = line[i] ?? '';
        if (ch === '"') {
            if (inQuotes && line[i + 1] === '"') {
                current += '"';
                i++;
            }
            else {
                inQuotes = !inQuotes;
            }
        }
        else if (ch === ',' && !inQuotes) {
            current = flushField(fields, current);
        }
        else {
            current += ch;
        }
    }
    fields.push(current);
    return fields.map((f) => f.trim());
}
/** Split criteria string into array — supports newlines, semicolons, or bullet points */
function splitCriteria(raw) {
    return raw
        .split(/[;\n]+/)
        .map((l) => l
        .trim()
        .replace(/^[-*]\s*\[[ xX]\]\s*/, '')
        .replace(/^[-*]\s+/, '')
        .trim())
        .filter((l) => l.length > 0);
}
/** Split tags string into array (comma or space separated) */
function splitTags(raw) {
    return raw
        .split(/[,\s]+/)
        .map((t) => t.trim())
        .filter((t) => t.length > 0);
}
/** Extract optional string field from a CSV row by column index */
function getOptionalField(row, idx) {
    if (idx === -1) {
        return '';
    }
    return row[idx]?.trim() ?? '';
}
/** Extract optional status field — returns undefined when column absent or empty */
function getStatusField(row, idx) {
    if (idx === -1) {
        return undefined;
    }
    const val = row[idx]?.trim();
    return val !== '' ? val : undefined;
}
/** Parse a single data row into an ImportedSpec given column indices */
function parseRow(row, titleIdx, descIdx, criteriaIdx, tagsIdx, statusIdx) {
    const title = row[titleIdx]?.trim() ?? '';
    if (!title) {
        return null;
    }
    const description = getOptionalField(row, descIdx);
    const criteriaRaw = getOptionalField(row, criteriaIdx);
    const tagsRaw = getOptionalField(row, tagsIdx);
    const externalStatus = getStatusField(row, statusIdx);
    const criteria = criteriaRaw ? splitCriteria(criteriaRaw) : [];
    const tags = tagsRaw ? splitTags(tagsRaw) : [];
    return { title, description, criteria, tags, externalStatus };
}
/**
 * Parse CSV content into an array of ImportedSpec objects.
 * Required columns: title
 * Optional columns: description, criteria, tags, status
 * Column order is determined from the header row.
 */
export function parseCsv(content) {
    const lines = content
        .split('\n')
        .map((l) => l.trimEnd())
        .filter((l) => l.length > 0);
    if (lines.length < 2) {
        return [];
    }
    const headerLine = lines[0];
    if (!headerLine) {
        return [];
    }
    const headers = parseCsvLine(headerLine).map((h) => h.toLowerCase());
    const titleIdx = headers.indexOf('title');
    if (titleIdx === -1) {
        throw new Error('CSV must have a "title" column header');
    }
    const descIdx = headers.indexOf('description');
    const criteriaIdx = headers.indexOf('criteria');
    const tagsIdx = headers.indexOf('tags');
    const statusIdx = headers.indexOf('status');
    const results = [];
    for (let i = 1; i < lines.length; i++) {
        const row = parseCsvLine(lines[i] ?? '');
        const spec = parseRow(row, titleIdx, descIdx, criteriaIdx, tagsIdx, statusIdx);
        if (spec) {
            results.push(spec);
        }
    }
    return results;
}
//# sourceMappingURL=csv-importer.js.map