// tools/design-schema/entity-extractor.ts — Entity extraction from spec content
// -- Entity extraction --------------------------------------------------------
export function extractEntities(content) {
    const entities = [];
    const seen = new Set();
    const entityPatterns = [
        /(?:table|model|entity|collection|schema)\s+["']?(\w+)["']?/gi,
        /(?:create|add|store|manage|track)\s+(\w+?)(?:s?\b)/gi,
        /(\w+?)(?:Model|Entity|Table|Schema|Record)\b/g,
    ];
    for (const pattern of entityPatterns) {
        const matches = content.matchAll(pattern);
        for (const match of matches) {
            if (match[1]) {
                const name = normalizeEntityName(match[1]);
                if (name.length > 2 && !seen.has(name) && !isCommonWord(name)) {
                    seen.add(name);
                    const fields = extractFieldsForEntity(content, match[1]);
                    entities.push({ name, fields, isJoinTable: false, relatesTo: [] });
                }
            }
        }
    }
    if (entities.length === 0) {
        const words = content.split(/\s+/).slice(0, 3);
        const name = normalizeEntityName(words.join('_'));
        entities.push({
            name: name || 'items',
            fields: ['name', 'description', 'status'],
            isJoinTable: false,
            relatesTo: [],
        });
    }
    for (let i = 0; i < entities.length; i++) {
        for (let j = i + 1; j < entities.length; j++) {
            const a = entities[i];
            const b = entities[j];
            /* v8 ignore start */
            if (!a || !b) {
                continue;
            }
            /* v8 ignore stop */
            if (a.fields.some((f) => f.toLowerCase().includes(b.name.toLowerCase())) ||
                content.toLowerCase().includes(`${a.name} ${b.name}`) ||
                content.toLowerCase().includes(`${b.name} ${a.name}`)) {
                a.relatesTo.push(b.name);
                b.relatesTo.push(a.name);
            }
        }
    }
    return entities;
}
function extractFieldsForEntity(content, entityName) {
    const fields = [];
    const lower = content.toLowerCase();
    const entityLower = entityName.toLowerCase();
    const entityIndex = lower.indexOf(entityLower);
    if (entityIndex !== -1) {
        const context = content.substring(Math.max(0, entityIndex - 200), Math.min(content.length, entityIndex + 500));
        const fieldPatterns = [
            /(?:field|column|property|attribute)\s+["']?(\w+)["']?/gi,
            /(?:has|with|contains|includes)\s+(?:a\s+)?(\w+)/gi,
        ];
        for (const pattern of fieldPatterns) {
            const matches = context.matchAll(pattern);
            for (const match of matches) {
                if (match[1] && match[1].length > 2 && !isCommonWord(match[1])) {
                    fields.push(match[1].toLowerCase());
                }
            }
        }
    }
    if (fields.length === 0) {
        fields.push('name', 'status');
    }
    return [...new Set(fields)];
}
function normalizeEntityName(name) {
    return name
        .replace(/[^a-zA-Z0-9]/g, '_')
        .replace(/_+/g, '_')
        .replace(/^_|_$/g, '')
        .toLowerCase();
}
function isCommonWord(word) {
    const commons = new Set([
        'the',
        'and',
        'for',
        'with',
        'from',
        'this',
        'that',
        'have',
        'will',
        'should',
        'must',
        'can',
        'not',
        'all',
        'each',
        'new',
        'get',
        'set',
        'add',
        'remove',
        'update',
        'delete',
        'create',
        'read',
        'list',
        'find',
        'data',
        'type',
        'spec',
        'file',
        'path',
        'test',
        'true',
        'false',
        'string',
        'number',
        'boolean',
        'null',
        'undefined',
        'function',
    ]);
    return commons.has(word.toLowerCase());
}
//# sourceMappingURL=entity-extractor.js.map